Docker 存储挂载指南
Docker 常见挂载方式有三种:volume、bind mount、tmpfs。
参考:
- Docker Storage: https://docs.docker.com/engine/storage/
- Docker Volumes: https://docs.docker.com/engine/storage/volumes/
- Docker Bind mounts: https://docs.docker.com/engine/storage/bind-mounts/
- Docker tmpfs mounts: https://docs.docker.com/engine/storage/tmpfs/
快速结论
| 类型 | 位置由谁管理 | 数据生命周期 | 适合场景 |
|---|---|---|---|
volume |
Docker | 独立于容器,容器删除后默认保留 | 数据库、消息队列、应用持久化数据 |
bind mount |
用户指定宿主机路径 | 跟宿主机文件一致 | 源码、配置文件、本地调试 |
tmpfs |
内存 | 容器停止后消失 | 临时缓存、敏感临时文件 |
选择原则:
1 | 持久化数据 -> volume |
容器自身的可写层跟容器生命周期绑定。只要数据需要脱离容器生命周期,就应该挂载出来。
Volume mount
volume 是 Docker 管理的数据目录,适合放数据库和中间件数据。
1 | docker volume create redis-data |
Compose 写法:
1 | services: |
常用命令:
1 | docker volume ls |
Bind mount
bind mount 是把宿主机上的文件或目录直接挂进容器。
1 | docker run --rm -it \ |
Compose 写法:
1 | services: |
注意:
- 宿主机和容器会看到同一份文件。
- 容器进程可能修改宿主机文件。
- 权限问题比
volume更常见。 - Docker Desktop + WSL 场景下,优先挂载 WSL 文件系统路径,例如
~/workspace/<project>,不要长期把主力项目放在/mnt/c/...下运行。
tmpfs mount
tmpfs 是内存挂载,不写入宿主机磁盘。
1 | docker run --rm \ |
Compose 写法:
1 | services: |
适合临时缓存、运行时临时文件、敏感临时数据。
-v 和 --mount
-v 和 --mount 是两种写法,不是两种挂载类型。
1 | # volume |
写文档和学习时建议优先用 --mount,因为 type=volume|bind|tmpfs 更清楚。
判断 -v 的类型:
1 | 左边是 volume 名称 -> volume |
常见判断
1 | -v redis-data:/data -> volume |
生产持久化数据优先考虑 volume。bind mount 更适合开发调试、配置文件,或者明确需要访问宿主机固定路径的场景。
Redis 和 MySQL 挂载实践
开发环境可以用同一套规则:
1 | 数据目录 -> volume |
常见目录:
| 服务 | 容器目录 | 用途 | 推荐挂载 |
|---|---|---|---|
| Redis | /data |
RDB / AOF 数据目录 | volume |
| Redis | /usr/local/etc/redis |
自定义配置目录 | bind mount,只读 |
| MySQL | /var/lib/mysql |
数据目录 | volume |
| MySQL | /etc/mysql/conf.d |
自定义配置目录 | bind mount,只读 |
| MySQL | /docker-entrypoint-initdb.d |
初始化脚本目录 | bind mount,只读 |
| MySQL | /var/log/mysql |
日志目录 | 开发环境通常不挂 |
版本选择:
| 服务 | 日常开发推荐 | 说明 |
|---|---|---|
| Redis | redis:8.8 |
当前 8.x 稳定线;项目没有明确约束时优先用它 |
| MySQL | mysql:8.4 |
LTS 线,兼容性通常比直接追新大版本更稳 |
不要在项目配置里使用 latest。如果需要完全可复现,可以进一步锁定 patch 版本,例如 redis:8.8.0、mysql:8.4.9。版本最终以项目生产环境和团队约定为准。
推荐项目结构:
1 | my-project/ |
项目目录只放配置和初始化脚本;真实数据放 Docker volume,不放 redis/data/ 或 mysql/data/。
Redis 配置示例:
1 | dir /data |
MySQL 配置示例:
1 | [mysqld] |
推荐 Compose 写法:
1 | services: |
单独用 docker run 时:
1 | docker volume create redis-data |
1 | docker volume create mysql-data |
关键注意:
- 不要直接覆盖整个
/etc/mysql,自定义配置放/etc/mysql/conf.d。 /docker-entrypoint-initdb.d只在空数据目录首次初始化时执行。- 开发环境先用
docker logs redis-dev或docker logs mysql-dev看日志;只有明确把日志写到文件时,才挂日志目录。 - 不建议默认使用
/mydata/redis/data:/data或/mydata/mysql/data:/var/lib/mysql。这能跑,但权限、备份、迁移和误删都要自己处理。
如果确实要重新初始化数据库:
1 | docker rm -f mysql-dev |
这个操作会删除数据库数据。
如果项目必须使用 MySQL 5.7,就改成:
1 | image: mysql:5.7 |
新项目不建议默认选 MySQL 5.7,版本应跟实际运行环境一致。
快速检查
1 | docker inspect <container> |
清理未使用 volume 前要确认数据价值:
1 | docker volume prune |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Cele Strong'Blog!
