容器可以删,数据卷不能乱;真正要保护的是配置、数据库和上传文件。

\n
Docker 新手最容易误会的一点,是把容器当成数据保险箱。容器本身可以重建,镜像可以重新拉,真正要保护的是挂进去的目录和卷。一次 docker rm、一次 Compose 项目名变化、一次路径写错,都可能让应用看起来像“数据没了”。很多时候数据并没有消失,只是你已经不知道它原来放在哪里。

我排查数据问题时,第一步永远是看 Mounts,而不是先猜应用 bug。

docker inspect reader --format '{{json .Mounts}}'
docker volume ls
docker volume inspect volume_name

这些命令能告诉我容器实际看到的存储来自哪里:宿主机路径、named volume、匿名卷,还是容器自己的可写层。

匿名卷的风险

匿名卷最麻烦的地方不是不能持久化,而是名字不直观,跟项目和服务的关系不容易看出来。某些镜像在 Dockerfile 里声明了 VOLUME,你即使没有在 Compose 里写挂载,Docker 也可能创建匿名卷。服务运行时一切正常,等你重建、迁移或清理卷时,就很容易分不清哪个卷属于哪个服务。

对关键数据,我不把希望放在匿名卷上。要么明确写 named volume,并记录备份方式;要么使用 bind mount,让数据落在项目目录里。

services:
  reader:
    image: example/reader:1.0.0
    restart: unless-stopped
    volumes:
      - /srv/docker/reader/config:/config
      - /srv/docker/reader/data:/data

这段配置看起来普通,但好处是明确。配置和数据在哪里,文件管理器能看到,备份工具能扫到,迁移时也能按目录处理。

bind mount 的优点和代价

HomeLab 里我偏向 bind mount,因为它符合家庭维护的直觉:数据就在宿主机目录里,权限、大小、备份状态都能直接检查。它的代价也很明显,路径依赖宿主机。换机器时必须先恢复同样的目录结构,否则容器可能创建空目录,应用就会像第一次启动。

所以我会把路径写成稳定前缀,例如 /srv/docker/app/data,而不是散落在用户下载目录或桌面目录。NAS 上也一样,尽量用长期存在的共享目录,不用临时挂载点。

挂载会遮住镜像里的文件

另一个常见坑是空目录挂载。镜像里某个路径本来带默认配置,你把宿主机空目录挂上去以后,容器看到的就是空目录。这不是镜像文件被删了,而是挂载覆盖了视图。遇到应用提示缺默认配置,我会先看镜像文档,确认是否需要复制初始化文件,或者第一次启动是否会自动生成。

只读挂载也值得用。公开资料、归档文件、只供应用读取的目录,能加 :ro 就加上:

volumes:
  - /srv/archive:/archive:ro

这样即使应用或配置出错,也不容易反向修改宿主机资料。

恢复演练比备份截图有用

备份真正有用,要靠恢复演练证明。我会在服务稳定后做一次小演练:停容器,复制当前 configdata,在测试目录里恢复,改一个临时端口启动,确认页面、账号、关键数据都能打开。演练不一定每周做,但重要服务至少要做过一次。

常用流程是:

docker compose down
tar -czf backup-reader-$(date +%F).tar.gz config data
mkdir -p /srv/docker-restore-test/reader
tar -xzf backup-reader-2026-06-13.tar.gz -C /srv/docker-restore-test/reader
docker compose config
docker compose up -d

如果恢复时发现路径写死、权限不对、缺少 .env,说明备份方案还不完整。等真正故障发生时再发现这些问题,会比现在演练贵得多。

数据卷管理的原则可以很简单:关键数据不要匿名,挂载路径要明确,备份后要试着恢复。做到这三点,删容器、升级镜像、迁移机器时心里会稳很多。

最后修改:2026 年 06 月 13 日
如果觉得我的文章对你有用,请随意赞赏