Docker 备份与恢复数据:卷、绑定目录和数据库
容器可以删除和重建,业务数据不能依赖容器可写层。备份前先找出命名卷、绑定目录、Compose 文件、.env 和数据库,再选择与存储类型匹配的方法。
本文是通用方法,不绑定 Ollama、MySQL 或某个业务项目。Ollama 模型目录的项目示例见站内 Docker 部署 Ollama。
2026-09-11 在 Apple silicon macOS、Docker Desktop 4.86.0 和 Engine 29.7.2 环境实测通过命名卷写入、只读挂载归档、恢复到空白新卷和文件读取。2026-09-12 依据 PostgreSQL、MySQL 和 SQLite 官方文档补齐数据库恢复路径;数据库命令、跨主机复制、SELinux 与生产应用恢复仍需按目标项目单独验证。
备份结论
| 数据类型 | 推荐方法 | 恢复重点 |
|---|---|---|
| 命名卷 | 临时工具容器归档 | 恢复到同名或新卷并检查权限 |
| 绑定目录 | tar/文件同步 | 保留目录结构、属主和权限 |
| SQLite | 停止写入后复制数据库和配置 | 先校验文件再启动应用 |
| PostgreSQL/MySQL | 使用原生 dump 工具 | 先恢复数据库,再恢复上传文件 |
| Compose 配置 | 单独归档 compose.yaml、.env | 先运行 docker compose config |
先判断数据能否重建。缓存、可重新拉取的镜像和可再生成的索引通常不需要进入业务备份;账号、数据库、上传文件、加密密钥和无法重新取得的模型或制品需要纳入恢复方案。一个服务同时使用数据库和文件目录时,只备份其中一侧通常无法完整恢复。
1. 盘点数据边界
docker volume ls
docker volume inspect project_data
docker ps --format 'table {{.Names}}\t{{.Mounts}}'
docker inspect app --format '{{json .Mounts}}'
docker compose config --volumes记录每个挂载的源路径、容器路径、卷名和所属服务。Compose 声明中的 data 可能在 Docker 中变成 <project>_data;使用 docker volume ls 和 docker volume inspect 确认实际卷名,不要只照抄 YAML 中的逻辑名称。镜像本身可重新拉取,镜像备份不能替代业务数据备份。
2. 备份命名卷
先停止会写入卷的服务,避免归档得到不一致快照:
cd /opt/project
docker compose stop app
mkdir -p backups
docker run --rm \
-v project_data:/data:ro \
-v "$PWD/backups:/backup" \
alpine:3.20 \
tar czf "/backup/project-data-$(date +%F).tar.gz" -C /data .
docker compose start app检查归档:
tar tzf backups/project-data-YYYY-MM-DD.tar.gz | head
sha256sum backups/project-data-YYYY-MM-DD.tar.gzproject_data 必须替换为实际卷名;不要把备份目录挂载到待备份卷内部。备份副本应复制到异机或对象存储,并按权限和加密策略保存。
3. 备份绑定目录和配置
cd /opt/project
tar --numeric-owner -czf "backups/project-files-$(date +%F).tar.gz" data uploads compose.yaml .env.env 可能包含密钥,备份文件不得进入公开仓库或聊天记录。若应用持续写入上传目录,先停服务或使用应用提供的快照能力。
恢复时不要直接覆盖正在使用的目录。先解压到空白目录并检查内容:
mkdir -p restore/project-files
tar --numeric-owner -xzf backups/project-files-YYYY-MM-DD.tar.gz \
-C restore/project-files
find restore/project-files -maxdepth 2 -type f | head停止服务后,将 Compose 的绑定路径临时指向恢复目录,运行 docker compose config 确认最终路径,再启动并完成业务验收。确认恢复副本可用前保留原目录,不要把解压命令指向生产目录。
4. 数据库备份
数据库不要只复制容器目录。使用数据库原生工具,并单独备份 Compose 配置和上传文件:
# PostgreSQL 示例
docker compose exec -T db pg_dump -U app -d app -Fc > backups/app-$(date +%F).dump
# MySQL 示例
docker compose exec -T db mysqldump --single-transaction -uapp -p app > backups/app-$(date +%F).sql密码应通过容器环境、交互输入或临时凭据注入,避免出现在 Shell 历史。完成后检查 dump 文件非空,并使用对应数据库工具检查归档可读性,不能只看命令退出码。大型数据库、主从复制和持续写入系统应使用项目或数据库官方的在线备份方案,不能套用文件复制。
SQLite 应优先使用应用自带导出功能或 SQLite 在线备份命令。无法确认应用是否使用 WAL、附属文件或额外上传目录时,先停止写入,再把数据库、-wal/-shm 文件、配置和上传目录作为一个恢复单元。可以在宿主机对停止写入后的数据库副本执行完整性检查:
sqlite3 backups/app-YYYY-MM-DD.db 'PRAGMA integrity_check;'输出 ok 才表示 SQLite 文件结构通过检查;应用级记录和附件仍要在恢复环境中验收。
5. 恢复到新卷
危险操作提醒: 恢复会覆盖目标目录;先确认服务已停止、备份日期正确,并在隔离环境演练。恢复命名卷:
cd /opt/project
docker compose stop app
docker volume create project_data_restore
docker run --rm \
-v project_data_restore:/data \
-v "$PWD/backups:/backup:ro" \
alpine:3.20 \
sh -c 'tar xzf /backup/project-data-YYYY-MM-DD.tar.gz -C /data'project_data_restore 应是空白目标卷。检查文件、属主和权限后,再把 Compose 的卷引用切换到该卷并启动服务;不要直接向仍含旧文件的生产卷叠加解压。恢复绑定目录时,把归档解压到确认过的宿主机目录,并核对属主、权限和 SELinux 标签(适用时)。恢复数据库时,先恢复数据库,再恢复文件:
docker compose stop app
docker compose exec -T db pg_restore -U app -d app --clean --if-exists < backups/app-YYYY-MM-DD.dump
docker compose start app--clean 会删除目标数据库对象,只能对确认过的目标执行。
MySQL/MariaDB 应先创建空白测试数据库,再导入 SQL:
docker compose stop app
docker compose exec -T db mysql -uapp -p app_restore < backups/app-YYYY-MM-DD.sql
docker compose start app数据库名、账号、字符集和版本必须与目标服务匹配。不要先清空唯一的生产数据库来验证备份;恢复演练使用独立数据库或隔离环境。SQLite 文件也先恢复为新文件并执行 PRAGMA integrity_check,再让应用指向副本验证。
6. 恢复验收
docker compose ps
docker compose logs --tail=100 app
curl -fsS http://127.0.0.1:8080/health登录应用,检查一条已知记录、一个上传文件和关键配置。容器启动成功或 tar 解压成功,都不能证明业务恢复完整;至少保留一次定期恢复演练记录。
恢复验收至少回答四个问题:服务能否启动、已知记录能否读取、上传或附件是否匹配、原有凭据或加密数据能否正常使用。需要回到生产时,记录备份时间、恢复目标、应用版本和验收结果,避免以后无法判断某份归档是否真的可用。
7. 自动化、保留和异机副本
定时任务应调用经过人工演练的备份脚本,并让失败产生可见告警。脚本至少检查命令退出码、归档是否非空、剩余磁盘空间和副本上传结果;只生成一个每天覆盖的本地文件不构成可靠备份。
保留策略按业务恢复目标决定,可以采用“每日若干份、每周若干份、每月若干份”的分层方式。至少保留一份不在当前 Docker 主机上的副本,并定期从异机副本恢复到隔离环境。备份中的 .env、数据库和用户文件可能包含敏感信息,应加密保存并限制读取权限;加密密钥不能只存在于被备份的同一台主机。
安全边界
备份文件可能包含密码、令牌、用户数据和私密配置。限制备份目录权限,传输和异机存储时使用加密,避免把 .env、数据库 dump 或模型文件提交到公开仓库。恢复前确认目标主机、卷名和备份日期,防止覆盖错误环境。
常见问题
备份文件为空或内容不一致
检查服务是否仍在写入,先停止服务或使用数据库原生快照,再重新备份。
恢复后应用没有权限读取文件
检查 docker inspect 的挂载路径、宿主机属主和容器运行用户;按项目文档修正权限,不要直接对整个目录执行 chmod 777。
找不到卷
使用 docker volume ls 和 docker compose config 核对 Compose 项目名前缀。不要凭记忆猜卷名。
建立备份后
为当前服务记录数据清单、恢复时间目标和可接受的数据丢失窗口,设置定时任务、异机副本和保留周期。每次应用升级前做一次数据库和文件备份,升级后在隔离环境验证恢复。
总结
Docker 备份的对象是卷、绑定目录、数据库和配置,而不是容器本身。停止写入、按存储类型选择工具、恢复后检查业务记录,才能把归档文件变成可用的恢复方案。