docker 3 - 容器化&迁移
docker 3 - 容器化&迁移
记录一下一个项目里踩的坑: 将已有 apache-tomcat
服务迁移到 docker 中。途中遇到了, “机器码”(不是简单的MAC地址, 而是由一套算出来的特征码)莫名其妙变化, 磁盘空间不足, 转换临时文件目录, docker 迁移等问题。
需求
将一个已有的可正常运行的 apache-tomcat
中的服务部署到 docker 环境中。由于这个应用有基于机器码的授权码认证机制, 需要固定每次启动的参数 (ip,mac等)。
文件准备
目录结构如下:
1 | tomcat-docker/ |
Dockerfile
编写一个简单的 Dockerfile
:
1 | # 9.0.78 |
为什么要设置时区?
- 因为该 Tomcat 应用需要连接远程数据库, 添加时区设置避免 Oracle 报错。
为什么使用
VOLUME
:ROOT
和ROOT_BPMUpload
是要长期调试更新的内容, 直接挂载方便变动文件。
为什么入口是
catalina.sh
而不是startup.sh
:- 因为
startup.sh
本身就是对catalina.sh
的调用, 另外使用 JPDA 远程调试更符合容器需求。
- 因为
tomcat 镜像:
- 直接使用
tomcat:9.0-jdk8-openjdk
, docker 会自动从官方镜像库里找。
- 直接使用
离线安装镜像
如果无法访问到互联网, 那么就需要事先在本地装好镜像。docker 在安装镜像时会优先拉取本地的镜像, 如果没有, 才会尝试拉取官方的同名镜像。
在可以用 ssh
连接到目标机的时候, 可以使用 scp
的方法来完成文件拷贝:
1 | scp [文件路径] [账户@地址:目标路径] |
然后再目标机中直接安装并验证这个镜像:
1 | docker load -i tomcat_9_jdk8.tar |
docker-compose
1 | version: "3.3" |
参数说明:
- version:3.3
: 广泛支持的版本;
- ports: A:B
: 将容器的端口 A 映射到宿主机上的端口 B;
- 自定义网络: 保持静态 ip;
把文件拷贝到服务器上, 用宝塔终端连上去能看见(直接用终端 ls -liah
也行)

迁移 docker
本来到这里已经可以直接进行构建了, 但是非常不幸, 由于年久失修(?), 目标机的 docker 工作目录所在磁盘已经没有空间了, 必须要进行文件迁移。由于目标机在生产环境中, 不能随便重启, 这里有两种方案:
首先要用 systemctl stop docker
来关闭服务并备份好文件。
方案 1: 直接改变挂载磁盘(备选)
这个方案需要更改挂载的磁盘( 例如, sdb
), 最好是格式化之后的空磁盘。先使用 mount
指令暂时将 docker 目录挂载到 sdb
。然后查询这个新磁盘 sdb
的 uuid, 并编辑 fstab
让挂载永久生效
方案 2: 更换 docker 的工作目录
docker 的工作配置默认存放在 /etc/docker/daemon.json
中, 修改这个文件就可以完成迁移。
如果没有也可以用 find
来找:
1 | find / -type f -name daemon.json |
找到两个, 看看哪个对的:
找到要改的那个:
1 | vim /etc/docker/daemon.json |
添加 data-root
项并验证:
用 cp -avfp
拷贝文件到新目录, 然后尝试重启服务:
1 | systemctl start docker |
重启 docker 服务
结果失败了, 这里查了一下原因, 是 data-root
没有被识别为正确的配置项。
升级 docker 服务
搜了一下原因, 可能是 docker 版本过旧了:
果然是太旧了, 这里卸载并重新安装了 docker:
1 | # 1. 卸载旧版 Docker |
临时区空间不足
再次重启, 依然失败, 抛出错误: OSError: [Error 28]No space left on device
。 然而使用 df -h
命令显示, docker 工作目录还有 200G 可用空间。
考虑可能是临时文件的问题, 问了下 deepseek 确认:
可以临时将构建缓存目录切换到空间更大的位置,构建完成后再恢复。这种临时方案既安全又有效。
1 | # 1.创建临时构建缓存目录(在空间充足的/home/tomcat 分区) |
构建容器
确认无误后, 重启 docker 服务, 并开始构建容器。
以下常用的命令:
- 容器和镜像:
验证容器:
1 | # 所有容器 |
- docker 服务:
1 | sudo systemctl status docker |
