侧边栏壁纸
博主头像
JasonLiu博主等级

Hi~ I'm Jason, Welcome

  • 累计撰写 27 篇文章
  • 累计创建 25 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

Dokploy / Docker Compose 数据不丢失指南:如何迁移 Volume 并创建可长期复用的稳定 Volume

JasonLiu
2025-12-22 / 0 评论 / 0 点赞 / 3 阅读 / 874 字

一、背景说明

在使用 Dokploy(或 Coolify / Docker Compose)部署应用(如 Halo、Typecho、WordPress)时,
很多人以为 “我已经在 compose 里写了 volume,数据就一定安全”

但实际上:

即使你声明了 volume,如果没有使用 external volume,数据仍然可能和项目绑定。

当你:

  • 删除 Dokploy 项目
  • 重建项目(项目名变化)
  • 迁移到新项目

就会出现一个非常诡异的现象:

数据明明还在磁盘上,但新容器却“像是全新安装”。


二、问题现象(典型)

你在 compose 中写了:

volumes:
  - halo_server_data:/root/.halo

volumes:
  halo_server_data:

然后你在服务器上看到真实路径是:

/var/lib/docker/volumes/
└── web-haloserver-nf8kxo_halo_server_data/_data

接着你删除 Dokploy 项目,重新创建一个新项目。

👉 新项目启动后,Halo 变成了全新初始化状态


三、问题根因(非常关键)

1️⃣ Docker Compose 的真实行为

即使你在 compose 里写了:

volumes:
  halo_server_data:

Docker 实际创建的 volume 名字是:

<project_name>_halo_server_data

例如:

web-haloserver-nf8kxo_halo_server_data

也就是说:

这个 volume 并不是全局唯一的,而是“项目私有”的。


2️⃣ Dokploy 的“隐形前缀”问题

Dokploy 会自动生成 project name(如 web-haloserver-nf8kxo),
你在 UI 中是看不到这个前缀的

结果就是:

  • 项目一删
  • 项目名一变
  • 新项目引用的是一个全新的 volume

而旧数据则变成了“孤儿 volume”。


四、正确的解决方案:使用 external volume + 稳定名字

核心原则

生产环境的数据 volume,必须脱离项目生命周期。

这就需要使用 external volume


五、创建一个“稳定名字”的 Volume(只需一次)

docker volume create halo_server_data

这个 volume 的真实路径是:

/var/lib/docker/volumes/halo_server_data/_data

六、正确的 Docker Compose 写法(重点)

services:
  halo_server:
    image: halohub/halo:1.6.1
    restart: unless-stopped
    volumes:
      - halo_server_data:/root/.halo

volumes:
  halo_server_data:
    external: true
    name: halo_server_data

这两行的意义:

external: true
name: halo_server_data

含义是:

  • 这个 volume 已经存在
  • 不要给它加项目名前缀
  • 不要随项目删除

七、如何从“旧项目 volume”迁移数据(安全步骤)

假设你当前的数据在:

web-haloserver-nf8kxo_halo_server_data

而你已经创建了新的稳定 volume:

halo_server_data

使用以下命令迁移数据(推荐)

docker run --rm \
  -v web-haloserver-nf8kxo_halo_server_data:/from \
  -v halo_server_data:/to \
  alpine cp -a /from/. /to/

说明:

  • -a:保留权限和结构
  • /from/.:确保拷贝所有隐藏文件

八、迁移完成后的检查

docker volume ls

你应该看到:

local  halo_server_data

并且 不再依赖任何 web-xxx_ 前缀的 volume


九、最佳实践总结(强烈建议)

✅ 必须做的

  • 所有生产数据使用 external volume

  • volume 名字使用稳定、语义化命名

    • halo_data
    • postgres_data
    • redis_data

❌ 避免做的

  • 依赖 Dokploy 自动生成的 volume
  • 使用带项目名前缀的 volume 作为长期数据
  • 删除项目之前不确认 volume 类型

十、一句话总结

没有 external: true 的 Docker Volume,
在 Dokploy 中只是“暂时安全”,不是“长期安全”。

0

评论区