Docker Compose 中 Volume 迁移到 Bind Mount 的完整实践

106次阅读
没有评论

(以 Nexterm 为例)

一、背景与目标

在使用 Docker Compose 部署服务时,常见的数据持久化方式有两种:

  1. Docker Volume(命名卷)

  2. Bind Mount(绑定宿主机目录)

本次目标是:

  • 从旧服务器迁移 Nexterm 服务

  • 导出 Docker Compose 自动创建的 volume 中的数据

  • 在新服务器中,改为使用当前目录下的 ./nexterm 作为数据目录

  • 确保 用户、配置、数据完整无损


二、问题现象:导出的 volume 是空的?

现象

  • docker volume ls 能看到 volume

  • docker run -v nexterm:/data 打包成功

  • 但生成的 tar.gz 只有 几十字节

  • 新服务器解压后目录是空的

关键线索

docker volume ls | grep nexterm
local  nexterm_nexterm

而导出时使用的是:

-v nexterm:/data

三、根因解析:Docker Compose 的 volume 命名规则

1️⃣ Compose 不会直接使用你写的 volume 名

docker-compose.yml 中:

volumes:
  nexterm:

Docker Compose 实际创建的 volume 名是:

<项目名>_<volume名>

本例中:

项目
Compose 项目名 nexterm(目录名)
volume 名 nexterm
实际 volume nexterm_nexterm

2️⃣ 为什么不会报错?

当你执行:

docker run -v nexterm:/data ...

如果 nexterm 不存在:

  • Docker 会 自动创建一个新的空 volume

  • 命令执行成功

  • 但打包的是 空数据

👉 这是一个非常容易踩坑、而且不会给任何错误提示的点。


四、如何确认容器正在使用的真实 volume(推荐方法)

方法一:看 volume 列表

docker volume ls

方法二(最稳妥):从容器反查

docker inspect nexterm-nexterm-1 \
  --format '{{ range .Mounts }}{{ if eq .Type "volume" }}{{ .Name }}{{ end }}{{ end }}'

输出的 就是你必须使用的 volume 名


五、正确导出 Docker Volume 数据(旧服务器)

1️⃣ 使用真实 volume 名导出

docker run --rm \
  -v nexterm_nexterm:/data \
  -v $(pwd):/backup \
  busybox \
  tar czf /backup/nexterm-volume-backup.tar.gz -C /data .

2️⃣ 校验备份是否正常

ls -lh nexterm-volume-backup.tar.gz
  • ❌ 几十字节 → 一定有问题

  • ✅ 几十 KB / 几 MB → 正常


六、在新服务器中恢复到 Bind Mount 目录

1️⃣ 创建目标目录

mkdir -p /opt/docker/nexterm/nexterm

2️⃣ 解压数据

tar xzf nexterm-volume-backup.tar.gz -C /opt/docker/nexterm/nexterm

解压后结构示例:

nexterm/
├── logs/
├── nexterm.db
└── sources/

七、修改 docker-compose.yml(从 Volume → Bind Mount)

原配置(命名卷)

volumes:
  - nexterm:/app/data

修改后(绑定目录)

services:
  nexterm:
    image: germannewsmaker/nexterm:1.0.5-OPEN-PREVIEW
    container_name: nexterm
    restart: always
    ports:
      - "6989:6989"
    environment:
      ENCRYPTION_KEY: "your-key"
    volumes:
      - ./nexterm:/app/data

⚠️ 注意事项:

  • 删除 volumes: 全局定义

  • 确保 ./nexterm 已存在并且有数据

  • Compose 执行目录必须是 docker-compose.yml 所在目录


八、启动与验证

docker compose up -d

检查状态:

docker compose ps
docker logs -f nexterm

访问 Web 界面后确认:

  • 用户是否存在

  • 配置是否完整

  • 历史数据是否正常


九、为什么推荐迁移到 Bind Mount?

对比项 Docker Volume Bind Mount
数据可见性
备份便利性 一般 极佳
可控性
适合长期运维 一般 非常适合

绑定目录后,备份极其简单:

tar czf nexterm-backup-$(date +%F).tar.gz nexterm/

或直接纳入你的 rclone / restic / borg 体系。


十、经验总结(重点)

Docker Compose 中,volume 的真实名字 ≠ yml 里写的名字

记住一句话即可避免 90% 的坑:

凡是用 Compose 的 volume,先用 docker volume lsdocker inspect 确认真实名称,再操作


十一、延伸建议(下一步可做)

  • 为所有 Docker 服务统一目录规范
    `/opt/docker/

    /`

  • 数据目录全部使用 bind mount

  • Volume 仅用于临时 / cache / 中间层

  • 给每个服务写一个 backup.sh


正文完
 1