docker run 中的 -v 参数(或 --volume) 是用于挂载卷(Volume) 或 绑定挂载(Bind Mount) 的核心选项。它能让容器访问宿主机上的文件/目录,实现数据持久化、配置共享、日志保存等功能。
1. 基本语法(Short Syntax)
docker run [其他参数] -v <宿主机路径>:<容器内路径>[:<选项>] 镜像名
或使用 --volume(效果相同):
docker run --volume <宿主机路径>:<容器内路径>[:<选项>] ...
各部分说明:
- 宿主机路径(source):
- 绝对路径:如
/home/user/data或./data(注意:“相对路径”会自动转为“绝对路径”)。 - 已命名的 Volume 名称:如
mydata(Docker 会自动管理存储位置,通常在/var/lib/docker/volumes/下)。
- 绝对路径:如
- 容器内路径(target/destination):
- 容器内的挂载点,必须是绝对路径,如
/app/data或/var/www/html。
- 容器内的挂载点,必须是绝对路径,如
- 选项(可选,多个用逗号分隔):
ro或readonly:只读挂载(容器内无法修改)。rw:读写(默认)。z:用于 SELinux,标记为共享内容(多容器共享时常用)。Z:用于 SELinux,标记为私有内容。consistent/cached/delegated:主要用于 macOS,控制一致性(性能 vs 一致性权衡)。nocopy:(较新版本)防止 Docker 在挂载时自动复制容器内原有内容到卷中。
示例:
# 1. 绑定挂载(Bind Mount)——最常用 docker run -d -v /host/path/data:/container/data nginx # 2. 只读挂载 docker run -d -v /host/config:/app/config:ro nginx # 3. 使用命名 Volume(推荐生产环境) docker run -d -v mydata:/app/data nginx
2. 命名 Volume vs 绑定挂载(Bind Mount)区别
| 类型 | 语法示例 | 存储位置 | 特点与适用场景 | 推荐度 |
|---|---|---|---|---|
| 绑定挂载 (Bind Mount) | -v /host/dir:/container/dir |
宿主机指定目录(你完全控制) | 直接映射宿主机路径,开发调试方便;但路径依赖强,移植性差。 | 开发、简单场景 |
| 命名 Volume | -v myvol:/container/dir |
Docker 管理(/var/lib/docker/volumes/myvol/) |
Docker 自动创建、管理;初始化时会复制容器内内容;更安全、便于备份/迁移。 | 生产环境推荐 |
| 匿名 Volume | -v /container/dir(只写容器路径) |
Docker 自动生成随机名 | 临时持久化,容器删除后可通过 docker volume prune 清理。 |
临时数据 |
重要行为差异:
- 命名 Volume:如果卷是空的,且容器路径下有文件,Docker 会自动复制容器内内容到卷中(初始化)。
- 绑定挂载:直接覆盖,不会自动复制;宿主机路径不存在时,Docker 不会自动创建目录(新版本行为)。
- 推荐生产用命名 Volume,开发时常用绑定挂载(便于直接编辑代码/配置)。
3. 推荐的现代写法:--mount(Long Syntax)
-v 是旧式简写,Docker 官方现在推荐使用 --mount,它功能更完整、清晰,支持更多选项。
语法:
--mount type=<类型>,source=<源>,target=<目标>[,readonly][,其他选项]
类型:
bind:绑定挂载(宿主机路径)volume:命名 Volumetmpfs:内存临时文件系统(不持久化)
示例:
# 绑定挂载(推荐写法) docker run -d \ --mount type=bind,source=/host/data,target=/app/data,readonly \ nginx # 命名 Volume docker run -d \ --mount type=volume,source=mydata,target=/app/data \ nginx
--mount 比 -v 支持更多高级选项(如 consistency、propagation 等),且在 Docker Compose 中更易读。
4. 常见使用场景
- 代码开发:
-v $(pwd):/app(实时同步修改) - 数据库数据持久化:
-v postgres-data:/var/lib/postgresql/data - 配置文件:
-v /host/config:/etc/myapp:ro - 日志:
-v /host/logs:/var/log/app - 多容器共享:多个容器挂载同一个命名 Volume
5. 实用命令
- 查看所有 Volume:
docker volume ls - 详细查看某个 Volume:
docker volume inspect mydata - 删除 Volume:
docker volume rm mydata(容器未使用时) - 清理未使用 Volume:
docker volume prune - 查看容器挂载情况:
docker inspect <容器ID> | grep -A 20 Mounts
6. 注意事项
- 权限问题:容器内进程 UID/GID 与宿主机不一致时,可能出现权限拒绝。解决办法:用
user参数运行容器,或在宿主机提前chown。 - SELinux/AppArmor:Linux 系统下可能需要
z/Z选项。 - Docker Desktop (Mac/Windows):绑定挂载性能较差,命名 Volume 更好。
- Docker Compose:推荐在
compose.yml中用volumes:部分定义,支持 short 和 long 语法。 - 新版本 Docker 中,
-v仍完全支持,但--mount更未来-proof。
如果想看具体例子(如 Nginx + 持久化网站文件、PostgreSQL 数据卷等),或者 Docker Compose 中的写法,告诉我,我可以给出完整命令!
官方文档参考(持续更新):
Docker Compose 中的 -v 的写法
Docker Compose 中 -v(即 volumes)的写法遵循 短语法 和 长语法 两种规范,核心用于挂载宿主机目录、具名卷或匿名卷,实现数据持久化与共享。
核心语法总览
表格
| 类型 | 短语法 (Short Syntax) | 长语法 (Long Syntax) | 适用场景 |
|---|---|---|---|
| 绑定挂载 | ./src:/app/src:ro |
type: bind, source: ./src, target: /app/src, read_only: true |
宿主机与容器双向同步代码 |
| 具名卷 | pgdata:/var/lib/postgresql/data |
type: volume, source: pgdata, target: /var/lib/postgresql/data |
持久化数据,便于管理与备份 |
| 匿名卷 | /var/lib/postgresql/data |
不推荐直接使用 | 临时数据,容器删除后自动清理 |
详细写法与示例
1. 短语法 (Short Syntax)
格式:[宿主机路径:]容器路径[:权限模式]
- 宿主机路径:支持绝对路径、相对路径(以
.或..开头)或具名卷名;省略则为匿名卷。 - 容器路径:容器内的绝对路径。
- 权限模式:
ro(只读)、rw(读写,默认)。
示例:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
# 1. 绑定挂载 - 相对路径(当前目录 ./conf 挂载到容器 /etc/nginx/conf.d)
- ./conf:/etc/nginx/conf.d:ro
# 2. 绑定挂载 - 绝对路径
- /var/log/nginx:/var/log/nginx
# 3. 具名卷(需在顶级 volumes 定义)
- pgdata:/var/lib/postgresql/data
# 4. 匿名卷
- /tmp/cache
# 顶级定义具名卷
volumes:
pgdata:
2. 长语法 (Long Syntax)
优势:结构清晰,支持更丰富的配置(如绑定传播、卷驱动选项等),推荐复杂场景使用。格式:通过 type、source、target 等键值对明确配置。
示例:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
# 绑定挂载 + 只读
- type: bind
source: ./conf
target: /etc/nginx/conf.d
read_only: true
# 具名卷 + 自定义驱动选项
- type: volume
source: pgdata
target: /var/lib/postgresql/data
volume:
nocopy: true # 禁止容器初始化时从镜像复制数据
# 顶级定义具名卷
volumes:
pgdata:
driver: local
关键注意事项
- 路径顺序:始终为 宿主机路径在前,容器路径在后,切勿颠倒。
- 相对路径:必须以
.或..开头(如./src),否则 Docker 会将其识别为具名卷。 - 权限问题:
- 绑定挂载时,容器内用户需有宿主机路径的读写权限。
- 生产环境避免使用
:rw权限过大,优先使用:ro提升安全性。
- 具名卷管理:
- 需在顶级
volumes块显式声明,便于统一管理。 - 使用
docker volume ls查看所有具名卷,docker volume inspect <卷名>查看详情。
- 需在顶级
- 匿名卷清理:匿名卷不会随容器自动删除,需使用
docker-compose down -v一并清理。
常见场景速查
表格
| 场景 | 推荐写法 | 说明 |
|---|---|---|
| 开发环境代码热重载 | ./app:/app:rw |
宿主机代码修改实时同步到容器 |
| 生产环境数据持久化 | pgdata:/var/lib/postgresql/data |
具名卷管理数据库数据,安全可靠 |
| 配置文件挂载 | ./config:/config:ro |
只读挂载配置,避免容器误修改 |
| 共享 Socket 文件 | /var/run/docker.sock:/var/run/docker.sock |
允许容器访问 Docker 引擎(需谨慎) |
最佳实践
- 区分用途:开发环境用绑定挂载(
./src:/app),生产环境用具名卷(pgdata:/data)。 - 统一配置:所有具名卷在顶级
volumes定义,便于维护和版本控制。 - 最小权限:非必要不使用读写权限,优先配置只读(
ro)。 - 定期清理:使用
docker-compose down -v清理无用卷,避免磁盘空间占用。
结合具体服务(如 Go 应用、数据库)提供可直接复制的 docker-compose.yml 挂载配置模板
给你整理了开发 / 生产都能用、最常见的 4 套模板,包含:
- 前端 / 后端代码热更新
- MySQL 数据库持久化
- Redis 持久化
- Nginx 配置挂载
全部是标准 -v 写法,直接复制到 docker-compose.yml 即可运行。
一、通用完整版(推荐直接用)
包含 Web 服务 + MySQL + Redis + Nginx,全覆盖
version: '3.8'
services:
# 1. 你的后端/前端应用(代码热更新)
app:
image: node:18 # 可换成 java/python/go/php
volumes:
# 🔥 代码挂载(本地修改 → 容器实时生效)
- ./app:/app
# 🔥 临时目录(匿名卷)
- /app/node_modules
# 🔥 日志挂载
- ./logs:/app/logs
# 2. MySQL 数据库(数据永久保存)
mysql:
image: mysql:8
volumes:
# 🔥 数据持久化(具名卷,不会丢失)
- mysql_data:/var/lib/mysql
# 初始化 SQL
- ./mysql/init:/docker-entrypoint-initdb.d
# 3. Redis(缓存持久化)
redis:
image: redis:alpine
volumes:
- redis_data:/data
# 4. Nginx(配置挂载)
nginx:
image: nginx:alpine
volumes:
# 🔥 只读挂载配置文件(安全)
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/html:/usr/share/nginx/html
- ./nginx/logs:/var/log/nginx
# 🔥 必须在这里声明具名卷(数据持久化核心)
volumes:
mysql_data:
redis_data:
二、极简版(只跑后端 + 数据库)
version: '3.8'
services:
backend:
build: .
volumes:
- ./:/app # 代码热更新
mysql:
image: mysql:8
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
三、你必须记住的 3 种 -v 写法(万能公式)
1. 代码 / 配置挂载(开发必备)
- 本地路径 : 容器路径 : 权限 - ./src:/app:ro
./src= 你电脑当前目录下的 src/app= 容器里的路径ro= 只读(推荐),rw= 读写
2. 数据库持久化(生产必备)
- 卷名 : 容器路径 - mysql_data:/var/lib/mysql
- 必须在文件最下方
volumes:声明卷名
3. 匿名卷(屏蔽依赖文件夹)
- /app/node_modules - /app/vendor
- 不写本地路径,只写容器路径
- 防止覆盖容器里的依赖包