Docker 数据挂载与共享
上一章的命名卷由 Docker 管理;本章的 bind mount 则直接把宿主机上的目录或文件「贴」进容器,宿主机改什么容器立刻看到什么,特别适合放配置、日志和开发中的代码。
bind mount:绝对路径挂载
写法是 -v 宿主机绝对路径:容器内路径,宿主机路径必须写绝对路径:
docker run -d --name web \
-v /opt/nginx/html:/usr/share/nginx/html:ro \
-v /opt/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine
上述命令把宿主机 /opt/nginx/html 目录、nginx.conf 文件分别挂进容器;路径尾部加 :ro 表示只读(详见下文)。用 -v 绑定时若宿主机路径不存在会自动创建为目录,因此挂载单个文件前务必确认宿主机文件已存在。
典型场景:配置、日志、代码
| 场景 | 挂载示例 | 好处 |
|---|---|---|
| 配置文件 | -v /opt/app/config.yaml:/app/config.yaml | 改配置即生效,无需重建镜像 |
| 应用日志 | -v /var/log/app:/app/logs | 宿主机直接查看、统一收集日志 |
| 开发代码 | -v /home/dev/project:/app | 宿主机改代码,容器内即刻可见 |
开发时把项目代码挂进容器是最常用的组合,例如挂一个应用目录:
docker run -d --name pyapp \
-v /home/dev/project:/app \
-w /app python:3.12 python app.py # -w 指定容器内的工作目录
只读挂载 :ro 防篡改
挂配置文件、密钥等不想被容器改动的路径时加 :ro,容器内对该路径只有读权限:
docker run -d --name web \
-v /opt/nginx/html:/usr/share/nginx/html:ro nginx:alpine
docker exec web sh -c 'echo x > /usr/share/nginx/html/a.txt'
# 输出:sh: can't create ... Read-only file system
tmpfs:内存挂载
tmpfs 不写磁盘,内容只存在宿主机内存中,容器停止即清空,适合放缓存、临时文件:
docker run --rm \
--mount type=tmpfs,target=/cache \
ubuntu:22.04 sh -c 'echo data > /cache/tmp.txt && cat /cache/tmp.txt'
# 输出:data(容器退出后 /cache 内容一并消失)
tmpfs 也可以简写成 --tmpfs /cache;它不持久化,切勿存放重要数据。
三种挂载方式对比
| 方式 | 写法 | 生命周期 | 典型用途 |
|---|---|---|---|
| 命名卷 | -v myvol:/data | Docker 管理,容器删除仍在 | 数据库等重要数据 |
| bind mount | -v /宿主机绝对路径:/data | 跟随宿主机路径 | 配置、日志、开发代码 |
| tmpfs | --mount type=tmpfs,target=/data | 存内存,停止即丢 | 缓存、临时文件 |
小结
bind mount 用绝对路径把宿主机目录或文件挂进容器,适合配置文件、日志与开发代码;tmpfs 只进内存适合临时数据;配合上一章的命名卷,按「要不要持久化、由谁管理」三选一即可,并用 :ro 防止容器篡改只读内容。