Docker 容器数据丢失?教你正确备份数据
为什么要提前备份容器数据
很多新手以为容器是“永久的”,直接删掉容器重建就好——却发现里面的数据全没了。
Docker 默认将容器内数据写入可写层,一旦容器删除,数据也一同消失。
正确做法是把数据放在 数据卷(Volume) 或 绑定挂载(Bind Mount) 中,并定期备份。
本文不扯概念,只讲怎么备份、怎么恢复,零基础也能直接操作。
备份前必须确认你的数据存在哪
先看看你的容器启动命令或 docker-compose.yml:
- 如果用了
-v myvolume:/container/path,数据存在 Docker 管理的数据卷里。 - 如果用了
-v /host/path:/container/path,数据直接存在宿主机指定目录里。
判断方法:执行 docker inspect 容器名 | grep -i volume,能看到 Name 的就是数据卷,能看到 Source 的就是宿主机路径。
搞清楚之后,按对应方法备份。
备份数据卷(Volume)
数据卷在宿主机上的位置一般是 /var/lib/docker/volumes/卷名/_data,但不能直接复制那个目录,因为 Docker 可能正在写入。
标准做法是用临时容器打包。
备份命令(一行搞定)
docker run --rm -v 卷名:/volume -v $(pwd):/backup alpine tar -czf /backup/volume-backup.tar.gz -C /volume .
解释:
--rm:备份完成后自动删除临时容器。-v 卷名:/volume:把你要备份的卷挂载到容器内的/volume。-v $(pwd):/backup:把当前目录挂载到/backup,备份文件会直接生成在当前目录。alpine:极小的 Linux 镜像,只用来打包。tar -czf /backup/volume-backup.tar.gz -C /volume .:把/volume里的所有文件压缩到备份文件。
执行后当前目录下会出现 volume-backup.tar.gz,这就是你卷的完整数据。
备份绑定挂载(宿主机目录)
绑定挂载的数据本来就在宿主机上,直接 cp 或 tar 即可。先停止容器,防止写入过程中文件不一致。
# 停止使用该目录的容器
docker stop 容器名
# 进入宿主机挂载目录的父目录,打包整个目录
tar -czf /backup/data-backup.tar.gz -C /宿主机/挂载目录/父路径 目录名
例如你的挂载点是 /data/myapp,命令:
docker stop myapp-containertar -czf /backup/myapp-backup.tar.gz -C /data myapp
打包完成后可以重新启动容器。
恢复数据到新容器
恢复分两步:把备份文件解压到指定位置,然后启动容器挂载上去。
恢复数据卷
# 先创建一个空卷(如果不存在)
docker volume create myvolume-restored
# 用临时容器把备份文件解压到新卷
docker run --rm -v myvolume-restored:/volume -v $(pwd):/backup alpine tar -xzf /backup/volume-backup.tar.gz -C /volume
现在新卷 myvolume-restored 里就恢复了原始数据。
启动容器时把该卷挂上去即可。
恢复绑定挂载
# 先恢复到宿主机某个目录
tar -xzf /backup/data-backup.tar.gz -C /目标目录
# 然后启动容器挂载此目录
docker run -d -v /目标目录:/container/path 镜像名
避坑:这些错误容易导致备份失败
- 不要直接复制
/var/lib/docker/volumes/卷名/_data:因为 Docker 可能正在写入,复制出来可能不完整,而且没有锁保护。 - 备份前停掉正在写入数据的容器:尤其是数据库容器,不停容易导致备份文件损坏。
- 恢复后权限不对:数据库等应用对文件权限敏感。挂载时注意用户 ID。可以在
docker run里加--user参数,或者解压后手动chown。 - 备份文件名没有时间戳:建议加上日期,如
backup-2025-04-05.tar.gz,方便管理。
高频问题解答
Q1:我可以用 docker commit 备份整个容器吗?
A:不行。commit 只保存镜像层,数据卷里的内容不会被包含。备份数据必须单独处理卷。
Q2:备份文件太大怎么办?
A:可以在 tar 命令里排除不需要的文件,比如 --exclude='*.log'。或者用 gzip 压缩等级调整 -9。
Q3:如何定期自动备份?
A:写一个 shell 脚本,加入 crontab。比如每天凌晨 3 点备份,保留最近 7 天的文件。脚本里就是上面的一行 docker run 命令。
Q4:恢复后容器启动报错 “permission denied”?
A:大概率是文件所属用户不对。检查容器镜像里的用户 UID(通常用 id -u 查看),然后解压后执行 chown -R UID:GID /挂载点。
下一步:验证备份是否可用
备份再花哨,不能恢复也是白搭。
建议每次备份后立刻验证:
- 创建一个新容器,挂载备份后的数据卷或目录。
- 进入容器查看文件是否完整:
docker exec -it 新容器名 ls /data。 - 如果是数据库,连接试试能否正常读写。
验证通过后再删除旧容器或旧备份文件,避免“备份了个寂寞”。
如果你正被 Docker 容器数据丢失问题困扰,现在就去按上面的步骤给你的数据卷做一个完整的备份吧。
遇到报错别慌,回看避坑和高频问题,基本能解决 90% 的异常。