朕喜技术(ZhenxiJS)
2026.09.05
1 分钟阅读
Docker permission denied docker non-root user named volume owner root docker compose chown Errno 13 Permission denied docker 容器内非root写入挂载卷失败
Docker named volume 非 root 用户 Permission denied 解决
关键词:Docker permission denied、docker non-root user、named volume owner root、docker compose chown、Errno 13 Permission denied docker、容器内非root写入挂载卷失败
问题背景
Docker 容器以非 root 用户(如 appuser uid=1000)运行,数据目录 /data/uploads 挂载了 named volume。应用写入文件时报:
PermissionError: [Errno 13] Permission denied
ls -la 显示挂载目录 owner 是 root(0:0),而运行用户 uid=1000 无写权限。
复现步骤
# scenario/2026-09-05-0001/
docker compose up -d --build
docker compose exec app python3 /app/app.py
复现 Dockerfile 片段(问题版本):
RUN useradd -m -u 1000 appuser
RUN mkdir -p /data/uploads # root 创建,未 chown
USER appuser
根本原因
Docker named volume 首次挂载时,会从镜像中挂载点目录继承所有权(owner/group/权限)。因 Dockerfile 用 root 创建了 /data/uploads 且未 chown,volume 的 owner 也变成 root。容器内以 appuser(uid=1000) 运行,对 root 拥有的目录无写权限。
一句话:named volume 默认以 root 持有所有权,需在镜像构建时把挂载点 chown 给运行用户。
解决办法
修改 Dockerfile,在 USER appuser 之前 chown 挂载目录:
RUN mkdir -p /data/uploads && chown -R appuser:appuser /data/uploads
然后必须删除旧 volume 再重建(否则旧 volume 仍是 root owner,改动不生效):
docker compose down -v # 注意会清除 volume 数据
docker compose up -d --build
验证
docker compose exec app python3 /app/app.py
# → 目录所有者为 appuser(uid=1000):appuser(gid=1000)
# → 成功写入 /data/uploads/hello.txt ✓
经验与避坑
- 改 Dockerfile 只对全新 volume 有效:named volume 首次创建时才从镜像挂载点继承所有权。volume 已存在则需
docker compose down -v删除重建。生产删卷前务必备份。 - 更健壮的生产方案:用 entrypoint 动态 chown——容器以 root 启动 → entrypoint 里执行
chown -R appuser:appuser /data/uploads→ 用gosu/su降权切换到 appuser 运行应用。这样即使 volume 已存在也能动态修复,且不删数据。 - K8s 场景:用
securityContext.fsGroup让集群自动 chown 持久卷,或加一个initContainer负责 chown。 - 检查权限问题的命令:
docker compose exec app id看运行 uid;docker compose exec app ls -la /data看挂载目录 owner。
技术栈与环境
- Linux + Docker Compose v2
- 镜像:
python:3.11-slim - Python 应用(
os.access/open判断写权限) - 非 root 用户
appuser(uid=1000)
可复现命令
cd scenario/2026-09-05-0001
docker compose up -d --build
docker compose exec app python3 /app/app.py # 复现:PermissionError
# 修复后重新验证:
docker compose down -v && docker compose up -d --build
docker compose exec app python3 /app/app.py # 成功写入 ✓
