Docker挂载读写权限核心在于挂载模式(:ro/:rw)与用户权限(UID/GID匹配)双重控制;默认rw但实际写入需容器用户对宿主机目录有对应文件权限,常见解决方案包括--user指定UID、chown调整目录属主、SELinux加:z标签及--read-only加固根文件系统。

在 Docker 中配置容器挂载的读写权限,核心在于明确“谁在访问”和“挂载点是否允许写入”两个层面。默认情况下,无论是 volume 还是 bind mount,挂载都是可读写的(RW: true),但实际能否写入,还取决于容器内进程的用户身份、宿主机目录权限、SELinux/AppArmor 等安全策略。
一、确认挂载本身是否启用读写
挂载时可通过 :ro 或 :rw 显式声明权限,不写则默认为 rw:
-
docker run -v myvol:/app ubuntu→ 默认可读写 -
docker run -v /host/data:/app:ro ubuntu→ 容器内/app只读,宿主机仍可写 -
docker run -v /host/data:/app:rw ubuntu→ 显式声明可读写(等同于不加后缀)
可通过 docker inspect 容器名 查看 Mounts 字段中的 RW 值验证。
二、解决“能挂但不能写”的常见原因
即使挂载设为 rw,仍可能因以下原因报 Permission denied:
- UID/GID 不匹配:容器内进程 UID(如 1000)在宿主机上无权写入该目录(比如目录属主是 UID 1001)
-
宿主机目录权限不足:目录权限未开放给容器用户(例如只有
755,但容器用户既不是所有者也不在所属组) -
SELinux 阻断:在 CentOS/RHEL 等系统中,需加
:z或:Z标签让 SELinux 自动打标
推荐做法:
– 挂载时加 :z(共享标签,多容器可读写)或 :Z(私有标签,仅当前容器可用)
– 或提前运行 chown -R 1000:1000 /host/path 和 chmod -R 775 /host/path
三、安全加固:只读根文件系统 + 按需开放可写路径
对生产环境,建议用 --read-only 锁死整个根文件系统,再为必要路径单独挂载可写空间:
-
--read-only:使/及所有未显式挂载的路径只读 -
--tmpfs /tmp:rw,size=10M:为临时目录提供内存级可写空间 -
--tmpfs /run:rw:满足 nginx、supervisord 等需要存 PID/socket 的需求 -
-v mydata:/app/uploads:rw:用命名卷持久化上传内容 -
-v /host/logs:/var/log/app:rw,z:绑定挂载日志目录并适配 SELinux
未被上述方式覆盖的路径(如 /app/cache)仍将保持只读,尝试 touch /app/cache/test 会失败。
四、运行时指定用户,避免 root 权限越界
不要依赖容器内 root 写宿主机目录。更稳妥的方式是:
- 在 Dockerfile 中创建与宿主机 UID 匹配的非 root 用户:
RUN addgroup -g 1001 -f appgroup && adduser -S appuser -u 1001 - 启动时用
--user 1001:1001强制以该用户运行 - 宿主机目录也设为
chown 1001:1001 /host/path
这样既满足最小权限原则,又规避了 root_squash、SELinux 等带来的权限断裂问题。


















