Appearance
绑定挂载
绑定挂载(Bind Mount)将宿主机的文件或目录直接挂载到容器中,是开发环境中最常用的数据共享方式。
绑定挂载与数据卷的区别
| 特性 | 绑定挂载 | 数据卷 |
|---|---|---|
| 存储位置 | 宿主机任意目录 | Docker 管理目录 |
| 管理方式 | 由宿主机操作系统管理 | 由 Docker 管理 |
| 可见性 | 双向可见(宿主机和容器) | 主要在容器中 |
| 适用场景 | 开发调试、配置文件 | 生产数据持久化 |
| 跨平台性能 | macOS/Windows 较慢 | 性能更好 |
基本用法
-v 语法
bash
# 挂载目录
docker run -d \
-v /host/path:/container/path \
nginx
# 挂载单个文件
docker run -d \
-v /host/nginx.conf:/etc/nginx/nginx.conf \
nginx
# 只读挂载(:ro)
docker run -d \
-v /host/config:/app/config:ro \
myapp--mount 语法(推荐,更清晰)
bash
# 挂载目录
docker run -d \
--mount type=bind,source=/host/path,target=/container/path \
nginx
# 只读挂载
docker run -d \
--mount type=bind,source=/host/config,target=/app/config,readonly \
myapp
# 挂载文件
docker run -d \
--mount type=bind,source=/host/nginx.conf,target=/etc/nginx/nginx.conf,readonly \
nginx开发环境应用
Node.js 开发热更新
bash
# 挂载源码,配合 nodemon 实现热更新
docker run -d \
--name node-dev \
-v $(pwd):/app \
-w /app \
-p 3000:3000 \
node:20-alpine \
sh -c "npm install && npx nodemon app.js"package.json 中的 dev 脚本:
json
{
"scripts": {
"dev": "nodemon --watch src src/app.js"
}
}Python Django 开发
bash
docker run -d \
--name django-dev \
-v $(pwd):/app \
-w /app \
-p 8000:8000 \
python:3.12-slim \
sh -c "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:8000"Vue/React 前端开发
bash
docker run -d \
--name frontend-dev \
-v $(pwd):/app \
-v /app/node_modules \ # 排除 node_modules(使用容器内的)
-w /app \
-p 5173:5173 \
node:20-alpine \
sh -c "npm install && npm run dev -- --host"技巧:使用
-v /app/node_modules创建匿名卷,覆盖宿主机的node_modules,避免宿主机和容器的依赖冲突(尤其是 macOS 和 Linux 的原生模块差异)。
挂载配置文件
Nginx 配置挂载
bash
# 挂载自定义 Nginx 配置
docker run -d \
--name nginx \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $(pwd)/conf.d:/etc/nginx/conf.d:ro \
-v $(pwd)/html:/usr/share/nginx/html:ro \
-p 80:80 \
nginx:alpineMySQL 配置挂载
bash
docker run -d \
--name mysql \
-v $(pwd)/my.cnf:/etc/mysql/conf.d/custom.cnf:ro \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
mysql:8.0my.cnf 示例:
ini
[mysqld]
max_connections=200
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2路径注意事项
Linux/macOS
bash
# 使用绝对路径
docker run -v /home/user/data:/data nginx
# 使用 $PWD 当前目录
docker run -v $(pwd)/data:/data nginx
# 使用 ~ 家目录
docker run -v ~/data:/data nginxWindows
powershell
# PowerShell
docker run -v C:\Users\user\data:/data nginx
# 使用 $PWD
docker run -v ${PWD}\data:/data nginx
# 或者用正斜杠
docker run -v //c/Users/user/data:/data nginx权限问题
容器内文件权限
bash
# 查看文件权限
docker exec mycontainer ls -la /app
# 挂载时设置权限
docker run -d \
--mount type=bind,source=$(pwd),target=/app \
--user $(id -u):$(id -g) \ # 使用当前用户的 UID:GID
node:20-alpine \
node app.jsSELinux 标签(CentOS/RHEL)
bash
# :z 自动重新标记(共享)
docker run -v $(pwd):/app:z myapp
# :Z 专用标签(不共享)
docker run -v $(pwd):/app:Z myapp绑定挂载的性能优化
在 macOS 上,Docker 通过虚拟机访问宿主机文件系统,性能较慢。优化方式:
使用 :cached 或 :delegated(旧版优化,已被 virtiofs 替代)
bash
# macOS Docker Desktop 使用 virtiofs(更快的文件共享)
# 在 Settings → General 中开启 "Use VirtioFS"将频繁访问的目录放在容器卷中
bash
# node_modules 放在容器内(避免跨系统同步)
docker run -d \
-v $(pwd):/app \
-v /app/node_modules \ # 匿名卷,覆盖宿主机的 node_modules
node:20-alpine \
npm start常见问题
挂载目录为空
原因:挂载的宿主机目录覆盖了容器内的目录内容。
bash
# 如果需要容器内的初始文件,先复制出来
docker run --rm -v $(pwd)/config:/tmp/config nginx:alpine \
cp -r /etc/nginx/conf.d/. /tmp/config/
# 查看复制的内容
ls -la ./config/权限被拒绝(Permission denied)
bash
# 方法一:以 root 用户运行(不推荐生产)
docker run -u root myapp
# 方法二:在容器内修改权限
docker run -d myapp
docker exec -u root myapp chown -R appuser:appuser /app
# 方法三:使用正确的 UID 运行
docker run --user $(id -u):$(id -g) myapp总结
绑定挂载的核心使用场景:
- 开发环境:挂载代码目录,修改即生效,无需重建镜像
- 配置文件:挂载外部配置,灵活修改不重建镜像
- 日志输出:将容器日志输出到宿主机,便于收集
- 静态资源:Nginx 静态文件服务
原则:开发用绑定挂载(灵活),生产用命名卷(稳定可靠)。