从老服务器(182)迁移 Docker 环境到新服务器(249)的完整步骤总结
以下是整个从老服务器(A)迁移 Docker 环境到新服务器(B)的完整步骤总结,已按顺序整理,方便你直接复制到博客中使用。整个过程基于你的实际操作和问题解决经验,包含了常见坑和修复方式。
迁移环境概览
- 老服务器:A
- 新服务器:B
- 核心组件:MySQL、Redis、Nginx、前端 UI、Java 应用(ai-anes、xxl-job)、license、JPOM
- 容器镜像:java-env-image:latest(自定义镜像,包含多服务)
- 关键挂载路径:/data/mysql、/data/redis、/data/nginx-docker、/home/ubuntu/botsoftware/
完整迁移步骤
1. 准备工作(新服务器 249)
- 登录 root
创建目录结构(保持与老服务器一致)
mkdir -p /data/{mysql/{data,conf/{conf.d,mysql.conf.d}},redis/{data,conf},nginx-docker/{conf.d,empty-sites-enabled}}
mkdir -p /home/ubuntu/botsoftware/{manageplatform/ui,serverside/{ai-anes,xxl-job,license,jpom},botdownload}
更新系统并安装 Docker(如果还没装)
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | bash
docker --version # 确认版本(你的为 29.1.2)
2. 停止老服务器容器(182)
防止数据拷贝过程中不一致:
docker stop java-env
3. 拷贝数据目录(从 A 推到 B)
使用 rsync 拷贝所有关键目录(以 root 执行,避免权限问题):
# 数据库和配置
rsync -avz --progress /data/ root@192.168.0.249:/data/
如果目标服务器不是root账号用下面的命令解决权限问题(在需要拷贝的服务器执行):
sudo rsync -avz --progress --no-owner --no-group --delete \
--rsync-path="sudo rsync" \
/data/ ubuntu@192.168.19.172:/data/
# 应用代码和静态文件(包括 ui、serverside 等)
rsync -avz --progress /home/ubuntu/botsoftware/ root@192.168.0.249:/home/ubuntu/botsoftware/
如果目标服务器不是root账号用下面的命令解决权限问题:
sudo rsync -avz --progress --no-owner --no-group --delete \
--rsync-path="sudo rsync" \
/home/ubuntu/botsoftware/ ubuntu@192.168.19.170:/home/ubuntu/botsoftware/
特别注意:
- 如果 rsync 提示 Permission denied → 在老服务器用 sudo rsync
- 如果提示 host key verification failed → 先 ssh root@192.168.0.249 接受指纹
4. 拷贝镜像(从 182 导出 → 249 导入)
在老服务器(182):
docker save -o java-env-image.tar java-env-image:latest
scp java-env-image.tar root@192.168.0.249:/home/ubuntu/docker/
拷贝镜像 scp ubuntu@192.168.19.172:/home/ubuntu/docker/anes-image_v1.tar.gz /home/ubuntu/docker/
从172拷贝到171 示例
在新服务器(249):
docker load -i /home/ubuntu/docker/java-env-image.tar
或者:docker load -i anes-image_v1.tar.gz
docker images | grep java-env-image # 确认加载成功
anes-image_v1.tar.gz方式 导入镜像:
gunzip -c /home/ubuntu/docker/anes-image_v1.tar.gz | docker load
成功会看到:
Loaded image: anes-image:v1
然后确认:
docker images | grep anes
5. 修复权限(在新服务器 249 上执行)
如果是root
因为新服务器只有 root 用户,统一使用 root:root + 宽松权限:
# MySQL(根据镜像 uid,通常 27 或 999)
chown -R 27:27 /data/mysql/data # 或 999:999,根据实际测试
chmod -R 700 /data/mysql/data
# Redis
chown -R 1000:1000 /data/redis/data # 或 999:999
chmod -R 700 /data/redis/data
# 所有 botsoftware 目录(应用代码、jpom 等)
chown -R root:root /home/ubuntu/botsoftware/
chmod -R 755 /home/ubuntu/botsoftware/
find /home/ubuntu/botsoftware/ -type f -exec chmod 644 {} \;
特别修复:
- 如果 redis.conf 变成目录:
rm -rf /data/redis/conf/redis.conf→ 重新 scp 单文件 - JPOM 启动脚本:
chmod +x /home/ubuntu/botsoftware/serverside/jpom/*/bin/*.sh
如果是ubuntu用户:
一步步修复(最安全顺序)
- 这会把所有文件/目录的所有者改为 uid=105, gid=106(容器内 mysql 用户)。
- 运行后用 ls -la /data/mysql/data 确认:应该看到所有行都变成 105 mysql 或类似(因为 gid=106 通常对应组名 mysql)。
验证改完的样子(再看一次)Bash
sudo ls -la /data/mysql/data | head -20调整权限(让 MySQL 启动脚本能正常工作)Bash
# 目录给 755(所有者 rwx,其他人 rx)
sudo find /data/mysql/data -type d -exec chmod 755 {} \;
# 普通文件给 644(所有者 rw,其他人 r)
sudo find /data/mysql/data -type f -exec chmod 644 {} \;
# 特殊文件(如 ibdata1、undo_*、mysql.ibd 等)通常保持 660 或 640 也行,但上面 644 够用且安全或者更简单的一次性命令(如果想粗暴点,但生产慎用):Bash
sudo chmod -R u+rwX,go+rX /data/mysql/data(X 会自动只对目录加 x)
改所有者和组(核心命令,递归改成 105:106)Bash
查看容器内的mysql 权限 docker exec java-env id mysql
sudo chown -R 105:106 /data/mysql/data备份一下目录(强烈建议,虽然改权限不会删数据,但以防万一)Bash
sudo cp -a /data/mysql/data /data/mysql/data_backup_$(date +%Y%m%d)停止容器(必须的,避免文件被锁或半写状态)Bash
docker stop java-env
# 可选:如果想彻底清理旧容器状态
# docker rm java-env6. 运行容器(在新服务器 249 上)
使用完整 docker run 命令(和老服务器一致):
docker run -d --name java-env \
-p 8080:80 -p 8086:8086 -p 8083:8083 -p 8082:8082 -p 8081:8081 -p 28760:28760 -p 3306:3306 -p 6379:6379 \
-e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 \
-v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro \
-v /usr/share/zoneinfo:/usr/share/zoneinfo:ro \
-e TZ=Asia/Shanghai \
-e JAVA_OPTS="-Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai" \
-v /etc/timezone:/etc/timezone:ro \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/conf/conf.d:/etc/mysql/conf.d \
-v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
-v /data/mysql/conf/mysql.conf.d:/etc/mysql/mysql.conf.d \
-v /data/redis/data:/data \
-v /data/redis/conf/redis.conf:/etc/redis/redis.conf \
-v /data/nginx-docker/conf.d:/etc/nginx/conf.d \
-v /data/nginx-docker/empty-sites-enabled:/etc/nginx/sites-enabled \
-v /home/ubuntu/botsoftware/manageplatform/ui:/usr/share/nginx/html \
-v /home/ubuntu/botsoftware/serverside/ai-anes:/app/ai-anes \
-v /home/ubuntu/botsoftware/serverside/xxl-job:/app/xxl-job \
-v /home/ubuntu/botsoftware/serverside/license:/home/ubuntu/botsoftware/serverside/license \
-v /home/ubuntu/botsoftware/botdownload:/botdownload \
--restart unless-stopped \
java-env-image:latest
1 安装 JDK 17
执行:
sudo apt update
sudo apt install -y openjdk-17-jdk
安装完成后验证:
java -version
jpom 需要
直接把 JPOM 目录权限改成 ubuntu。
执行:
sudo chown -R ubuntu:ubuntu /home/ubuntu/botsoftware
然后重新启动:
cd ~/botsoftware/serverside/jpom/server/bin
./Server.sh start
7. 验证与收尾
- 测试服务
- MySQL:
docker exec -it java-env mysql -uroot -p - Redis:
docker exec -it java-env redis-cli - UI:浏览器 http://192.168.0.249:8080
- JPOM:检查日志是否有 agent/server 启动信息,或访问对应端口
- MySQL:
防火墙放行(如果 ufw 开启)
ufw allow 8080 3306 6379 # 根据需要
ufw reload
检查容器状态
docker ps
docker logs -f java-env
常见坑 & 解决
- Permission denied → 用 root chown + 755/644 宽松权限
- 挂载类型不匹配(如 redis.conf 变目录)→
rm -rf后再 scp 单文件 - 文件路径扁平化 → rsync 源路径带 / 结尾导致,需手动 mv 或重新 rsync 不带 /
- 用户不存在(ubuntu:ubuntu)→ 统一用 root:root
- 镜像未加载 → docker load 前确认 tar 文件完整