(以 Nexterm 为例)
一、背景与目标
在使用 Docker Compose 部署服务时,常见的数据持久化方式有两种:
-
Docker Volume(命名卷)
-
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 ls或docker inspect确认真实名称,再操作
十一、延伸建议(下一步可做)
-
为所有 Docker 服务统一目录规范
`/opt/docker//`
-
数据目录全部使用 bind mount
-
Volume 仅用于临时 / cache / 中间层
-
给每个服务写一个
backup.sh