Docker 容器备份:数据卷别丢了,重装那天才后悔

容器删了数据还在吗?Docker 数据卷备份全图解:命名卷、tar 打包、定时备份三步走,数据丢了能找回来。一步一步跟着做就能上线。

我是小够,只推够用的 VPS。

Docker 新手最容易栽的跟头:容器跑得好好的,一句 docker rm 或者一次重装,数据全没了。为什么?因为数据写在了容器的可写层里,容器一删,数据跟着陪葬。数据卷(volume) 就是解决这个问题的:把数据存到容器外面,容器删了,数据还在。

但这只是第一步。数据卷在宿主机上,宿主机挂了、VPS 到期了,数据照样没。所以完整姿势是三步:用命名卷 + 打包备份 + 定时异地。这篇一次讲透。

第一步:用命名卷,别用匿名卷

启动容器挂载数据,有两种写法:

# 匿名卷:Docker 自动生成一串乱码名字,删容器时容易误删
docker run -v /data mysql

# 命名卷:名字是你定的,清清楚楚
docker run -v mysql-data:/var/lib/mysql mysql

永远用命名卷。匿名卷的名字是一串哈希,时间久了你根本分不清哪个卷是谁的,清理时极容易误删。命名卷一眼就知道归属,备份时也好找。

已经在用匿名卷了?别慌,把数据拷出来重建:

docker run --rm -v 老匿名卷名:/from -v 新命名卷名:/to alpine cp -a /from/. /to/

compose 用户更简单,在 docker-compose.yml 里声明:

volumes:
  mysql-data:

services:
  db:
    image: mysql
    volumes:
      - mysql-data:/var/lib/mysql

顶层声明 volumes,compose 会帮你建好命名卷,docker compose down 默认不会删卷,数据是安全的。但注意 docker compose down -v 那个 -v 会连卷一起删,手别抖。

第二步:打包备份,一条命令

命名卷在宿主机的 /var/lib/docker/volumes/ 下,直接 tar 打包就行。备份单个卷:

docker run --rm -v mysql-data:/data -v /root/backup:/backup alpine tar czf /backup/mysql-data-$(date +%F).tar.gz -C /data .

拆解一下:起一个临时的 alpine 容器,把数据卷挂到 /data,把宿主机的备份目录挂到 /backup,在容器里 tar 打包。容器用完 --rm 自动删除,干干净净。

想一次备份所有卷,写个小脚本:

#!/bin/bash
BACKUP_DIR=/root/backup
mkdir -p $BACKUP_DIR
for vol in $(docker volume ls -q); do
  docker run --rm -v $vol:/data -v $BACKUP_DIR:/backup alpine \
    tar czf /backup/$vol-$(date +%F).tar.gz -C /data .
done
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

备份所有卷、文件名带日期、自动删 7 天前的,存成 /root/backup-volumes.sh,chmod +x,后面配 cron 用。

第三步:定时 + 异地

备份在宿主机上,宿主机挂了等于没备。两件事:

定时:cron 每天凌晨跑:

0 3 * * * /root/backup-volumes.sh >> /root/backup.log 2>&1

异地:备份完同步到别处。最简单的是另一台 VPS 或对象存储,一条 rsync:

rsync -avz /root/backup/ 用户名@另一台IP:/backup/

免密登录配好 SSH key,cron 里再加一行,备份自动异地。两台机器同时挂的概率,比你中彩票还低。

恢复:真到用的时候

备份的价值在恢复那一刻。恢复命令和备份是镜像的:

docker run --rm -v mysql-data:/data -v /root/backup:/backup alpine tar xzf /backup/mysql-data-2026-02-16.tar.gz -C /data

注意:恢复前先停掉用这个卷的容器,恢复完再启动。顺序是:停容器 → 解包覆盖 → 起容器 → 验证数据。先在测试环境练一遍,别等真出事了现学。

小够提醒

  • 备份了没验证等于没备份:每季度解包一次看看文件在不在,坏掉的备份比没有更坑人
  • 数据库容器备份前最好先停写或用数据库自带工具导一份,tar 打包正在写的数据库文件可能得到损坏的备份
  • 够用主义:个人博客每天一次、保留 7 天完全够用,别搞每小时备份那种大厂架势,硬盘和时间都浪费