Docker 数据卷管理完整教程
Docker 容器是临时性的,当容器被删除时,容器内部的所有数据也会随之消失。为了实现数据持久化,Docker 提供了数据卷(Volume)机制。在搬瓦工 VPS 上运行数据库、文件存储等有状态应用时,正确管理数据卷至关重要。本文将全面介绍 Docker 数据卷的各种使用方式和管理技巧。
一、数据持久化的三种方式
Docker 提供三种数据持久化方式:
- 命名卷(Named Volumes):由 Docker 管理,存储在
/var/lib/docker/volumes/目录下。推荐用于生产环境。 - 绑定挂载(Bind Mounts):直接映射主机目录到容器内。适合开发环境和需要直接访问文件的场景。
- tmpfs 挂载:数据存储在内存中,容器停止后数据消失。适合临时数据和敏感信息。
二、命名卷操作
2.1 基本操作
# 创建命名卷
docker volume create my-data
# 查看所有卷
docker volume ls
# 查看卷详细信息
docker volume inspect my-data
# 删除卷
docker volume rm my-data
# 删除所有未使用的卷
docker volume prune -f
2.2 在容器中使用命名卷
# 使用 -v 参数挂载
docker run -d --name mysql-server \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=password \
mysql:8.0
# 使用 --mount 参数(推荐,语法更清晰)
docker run -d --name mysql-server \
--mount source=mysql-data,target=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=password \
mysql:8.0
如果指定的卷不存在,Docker 会自动创建它。
2.3 在 Docker Compose 中使用
services:
db:
image: mysql:8.0
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
redis:
image: redis:7
volumes:
- redis-data:/data
volumes:
db-data:
redis-data:
driver: local
driver_opts:
type: none
device: /data/redis
o: bind
三、绑定挂载
绑定挂载将主机上的指定目录或文件映射到容器内部:
# 绑定挂载目录
docker run -d --name web \
-v /home/www:/usr/share/nginx/html:ro \
-p 80:80 \
nginx
# 使用 --mount 语法
docker run -d --name web \
--mount type=bind,source=/home/www,target=/usr/share/nginx/html,readonly \
-p 80:80 \
nginx
挂载选项说明:
ro或readonly:只读挂载,容器无法修改主机上的文件。- 如果主机目录不存在,使用
-v会自动创建空目录,而--mount会报错。
3.1 绑定挂载的使用场景
- 配置文件:将主机上的配置文件挂载到容器中。
- 开发环境:将源代码目录挂载到容器中,实现代码热更新。
- 日志收集:将容器日志目录挂载到主机,方便集中管理。
- 备份方便:数据直接存放在主机目录,备份更直观。
四、tmpfs 挂载
# 使用 tmpfs 挂载
docker run -d --name app \
--tmpfs /tmp:rw,size=100m,mode=1777 \
myapp
# 使用 --mount 语法
docker run -d --name app \
--mount type=tmpfs,destination=/tmp,tmpfs-size=104857600 \
myapp
tmpfs 适合存放临时文件和敏感数据(如密钥),因为数据不会写入磁盘,也不会留在容器层中。
五、数据卷备份与恢复
5.1 备份数据卷
# 方法一:使用临时容器备份
docker run --rm \
-v mysql-data:/source:ro \
-v /backup:/backup \
alpine tar czf /backup/mysql-data-$(date +%Y%m%d).tar.gz -C /source .
# 方法二:使用 docker cp 从容器中拷贝
docker cp mysql-server:/var/lib/mysql /backup/mysql-data/
5.2 恢复数据卷
# 创建新卷并恢复数据
docker volume create mysql-data-restored
docker run --rm \
-v mysql-data-restored:/target \
-v /backup:/backup:ro \
alpine tar xzf /backup/mysql-data-20260101.tar.gz -C /target
5.3 自动备份脚本
cat > /opt/backup-volumes.sh <<'EOF'
#!/bin/bash
BACKUP_DIR="/backup/docker-volumes"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# 获取所有命名卷
for vol in $(docker volume ls -q); do
echo "Backing up volume: $vol"
docker run --rm \
-v ${vol}:/source:ro \
-v ${BACKUP_DIR}:/backup \
alpine tar czf /backup/${vol}_${DATE}.tar.gz -C /source .
done
# 清理30天前的备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
echo "Backup completed at $(date)"
EOF
chmod +x /opt/backup-volumes.sh
# 添加定时任务:每天凌晨2点备份
# crontab 中添加:
# 0 2 * * * /opt/backup-volumes.sh >> /var/log/volume-backup.log 2>&1
六、数据卷迁移
在搬瓦工 VPS 之间迁移数据卷:
# 在源服务器上导出
docker run --rm -v my-data:/source:ro -v /tmp:/export \
alpine tar czf /export/my-data.tar.gz -C /source .
# 传输到目标服务器
scp /tmp/my-data.tar.gz user@new-server:/tmp/
# 在目标服务器上导入
docker volume create my-data
docker run --rm -v my-data:/target -v /tmp:/import:ro \
alpine tar xzf /import/my-data.tar.gz -C /target
七、数据卷最佳实践
- 使用命名卷:生产环境中优先使用命名卷而非绑定挂载,由 Docker 统一管理。
- 只读挂载:配置文件、静态资源等不需要容器修改的数据,使用只读挂载。
- 定期备份:重要数据务必设置定期备份策略。
- 避免在卷中存放大文件:搬瓦工 VPS 磁盘空间有限,定期清理不需要的数据。
- 使用 .dockerignore:在构建镜像时排除不需要的文件。
八、常见问题
权限问题
# 容器内用户与主机用户 UID 不匹配导致的权限错误
# 解决方法一:指定容器运行用户
docker run -d --user $(id -u):$(id -g) -v /data:/app/data myapp
# 解决方法二:修改主机目录权限
chown -R 1000:1000 /data
数据卷占用空间过大
# 查看各卷占用的实际空间
docker system df -v | grep -A 100 "Local Volumes"
# 查看 Docker 卷目录大小
du -sh /var/lib/docker/volumes/*/
总结
数据卷是 Docker 数据持久化的核心机制,在搬瓦工 VPS 上正确管理数据卷可以确保应用数据安全。建议生产环境使用命名卷并设置定期备份,开发环境可以使用绑定挂载提高效率。更多 Docker 基础知识请参考 Docker 安装教程,网络配置请参考 Docker 网络详解,磁盘清理请参考 Docker 自动清理教程。选购搬瓦工 VPS 请访问 bwh81.net,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣。