主题
Docker 存储
容器文件系统是临时的(可写层),容器删除后数据随之消失。本文讲解 Docker 的三种数据持久化方式及实战。
存储类型对比
| 方式 | 命令/语法 | 生命周期 | 典型用途 |
|---|---|---|---|
| 数据卷 Volume | -v myvol:/data | 独立于容器,需显式删除 | 数据库数据、共享数据 |
| 绑定挂载 Bind mount | -v /host/path:/data | 跟随宿主机文件 | 配置文件、开发热重载 |
| tmpfs | --tmpfs /tmp | 仅内存,容器停即失 | 敏感临时文件、密钥 |
数据卷 Volume
Volume 由 Docker 管理,位于 /var/lib/docker/volumes/,是最推荐的持久化方式。
bash
# 创建
docker volume create mydata
# 使用
docker run -d --name db -v mydata:/var/lib/mysql mysql:8
# 查看详情(含宿主机实际路径)
docker volume inspect mydata
# 列出 / 删除
docker volume ls
docker volume rm mydata
docker volume prune # 删除未被引用的卷多容器共享同一卷:
bash
docker run -d --name writer -v shared:/data busybox sh -c "while true; do date >> /data/log; sleep 1; done"
docker run -d --name reader -v shared:/data busybox cat /data/log绑定挂载 Bind mount
直接把宿主机目录/文件挂进容器,适合挂载配置与开发调试:
bash
# 挂载目录
docker run -d -v $(pwd)/html:/usr/share/nginx/html nginx
# 只读挂载(推荐配置类)
docker run -d -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro nginx
# 挂载单个文件
docker run -d -v /etc/localtime:/etc/localtime:ro myapp生产环境挂载配置文件建议加
:ro只读,防止容器误写宿主机。
tmpfs 挂载
仅存在于内存,适合存临时密钥:
bash
docker run -d --tmpfs /run/secrets:size=1m myapp容器可写层与存储驱动
容器对文件系统的修改发生在可写层(upperdir),由存储驱动(overlay2 等)管理。重要结论:
- 写入可写层性能差且不可持久,数据库等 IO 密集场景务必挂 Volume。
- 生产环境
--storage-driver推荐overlay2(默认)。
查看存储驱动:
bash
docker info | grep "Storage Driver"磁盘占用与日志轮转
Docker 默认不对容器 stdout/stderr 日志做限制,可能打满磁盘。配置 /etc/docker/daemon.json:
json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}注意:JSON 配置中注释需独立成行,勿写行尾注释。修改后
sudo systemctl restart docker。
每个容器单独限制日志:
yaml
# docker-compose.yml
services:
app:
image: myapp
logging:
driver: json-file
options:
max-size: "100m"
max-file: "3"清理磁盘:
bash
docker system df # 查看占用
docker system prune -a --volumes # 清理未使用资源最佳实践
- 数据库、消息队列等有状态服务一律使用 Volume。
- 配置文件用 Bind mount 且尽量
:ro。 - 配置日志轮转,避免磁盘被撑满。
- 生产环境将
/var/lib/docker挂载到大容量独立磁盘。 - 删除容器时若需连带删匿名卷用
docker rm -v。