跳转至

数据卷与持久化

Named volume

Docker 管理数据卷的位置和生命周期,适合数据库等持久数据。

docker volume create mysql-data
docker run -d --name mysql \
  -e MYSQL_ROOT_PASSWORD='change-me' \
  -v mysql-data:/var/lib/mysql \
  mysql:8.4

docker volume ls
docker volume inspect mysql-data

Bind mount

将主机目录直接挂入容器,适合开发代码或受版本控制的配置文件。

docker run --rm -v "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro" nginx:alpine

数据库优先使用其逻辑/物理备份工具,不要只复制正在写入的数据目录。机密配置应使用受控权限目录或密钥管理,不要直接写入镜像。

三种持久化选择

类型 生命周期和管理 适用场景
Named Volume Docker 管理,独立于容器 数据库、应用持久数据
Bind Mount 直接映射主机路径 配置、证书、需要明确主机路径的数据
tmpfs 只在主机内存,停止后消失 临时敏感文件、缓存

容器可写层适合临时运行变化,不适合重要数据和高速持续写入。Anonymous Volume 容易在重建后留下难以识别的数据,生产优先明确命名。

只读与权限

docker run --rm \
  --mount type=bind,src=/opt/app/config,dst=/etc/app,readonly \
  --mount type=volume,src=app-data,dst=/var/lib/app \
  app:1.0.0

容器内 UID/GID 仍作用于挂载数据。出现 Permission denied 时先用 docker inspect 确认挂载源和读写模式,再核对容器用户、主机目录 UID/GID、SELinux label 和文件系统权限;不要直接 chmod -R 777

Volume 备份与恢复

文件型数据在应用停止写入或保证一致性后,可用临时容器归档:

docker run --rm \
  -v app-data:/source:ro \
  -v /opt/backup:/backup \
  alpine:3.21 \
  tar -czf /backup/app-data.tar.gz -C /source .

恢复到新 Volume 后先在隔离容器验证文件、权限和应用版本,再切换业务。数据库应使用 mysqldumppg_dump、物理备份/WAL 等原生方法,因为直接复制正在写入的数据目录可能不一致。

Volume 删除保护

docker volume ls
docker volume inspect app-data
docker ps -a --filter volume=app-data
docker system df -v

删除前记录:使用该卷的容器、挂载路径、数据类型、最近备份和恢复验证。docker compose down -vdocker volume prunedocker system prune --volumes 都可能删除数据,不能作为日常无差别清理命令。

磁盘满排障

  1. df -hTdf -ih 区分容量和 inode。
  2. docker system df -v 区分镜像、容器、Volume 和缓存。
  3. 检查容器日志是否未轮转。
  4. 检查数据库/应用自身数据增长。
  5. 清理前确认对象引用,优先处理已确认可重建的缓存和镜像。

官方参考:Docker storageVolumesBind mounts