统一 UID/GID 是什么
容器里的用户权限最终按数字 UID/GID 匹配,用户名只是给人看的别名。跨镜像、跨主机共享挂载目录时,只要数字不一致,就会出现「同一份卷,一个容器能写、另一个写不进去」的现象。解决办法是在团队内规划固定数字(例如统一用 10001),构建期创建用户时写死,部署时宿主目录的属主也按这个数字对齐。
基本信息
| 核心原则 | 权限按数字 UID/GID 判定,与用户名无关 |
|---|---|
| 镜像内做法 | useradd -u 10001 -g 10001 app 后用 USER 10001:10001 |
| 宿主对齐 | chown -R 10001:10001 /srv/app-data |
| 常见内置账号 | node 镜像的 node 为 1000;nginx 镜像为 101 |
| 排查命令 | 容器内 id;宿主 ls -ln 看数字属主 |
| 适用场景 | 多容器共享卷、宿主目录挂载、日志采集目录 |
典型使用场景
- 多个容器读写同一份数据卷,需要统一身份才能互写
- 离线部署包要求宿主目录属主与镜像内用户对齐
- 日志与上传目录挂载到宿主,避免产出 root 属主文件
- 遵守集群安全基线,要求镜像以非 root 且固定 UID 运行
- 把 UID 规划写进部署文档与 CI 模板,避免各处各写一个值
镜像与宿主两侧对照
镜像与宿主两侧对照
# 构建期:创建固定数字的专用用户,并把应用目录授权给它
RUN groupadd -g 10001 app && useradd -u 10001 -g 10001 -m -s /sbin/nologin app
WORKDIR /srv/app
COPY --chown=10001:10001 ./dist /srv/app
USER 10001:10001部署期对齐宿主目录
部署期对齐宿主目录
# 宿主目录按同一数字授权(用数字而不是用户名,避免同名不同号)
sudo install -d -o 10001 -g 10001 -m 0750 /srv/app-data
# 核对容器内身份
docker run --rm app/web:1.0 id
# 核对宿主侧写入结果:应显示 10001 而不是 root
ls -ln /srv/app-data
# 多容器共享卷时,逐个确认身份一致
docker exec api id && docker exec worker id常见权限现象判读
| 现象 | 含义 | 处理方向 |
|---|---|---|
| 容器内写卷报 Permission denied | 容器进程 UID 与卷内属主不一致 | 统一 UID 或重建卷 |
| 宿主目录出现 root 属主文件 | 容器以 root 运行 | 镜像内声明非 root 用户 |
| 文件属主显示成宿主某用户名 | 该数字在宿主上对应的正是这个账号 | 按数字核对即可,不代表挂载错 |
| 一个容器写入后另一个读不到 | 两容器 UID 不同或权限位过严 | 统一 UID 与组权限 |
| 删除文件报权限不足 | 目录属主可写但文件属主不同 | 目录需要写权限覆盖删除操作 |
数字 UID 一旦对外承诺就不要随意更改:改了镜像里的 UID 意味着已有卷里的文件属主全部失配,迁移成本很高。规划阶段预留一段专用号段更稳妥。
宿主上不要为了绕过权限问题直接把目录改成 777。放宽权限会连带影响同主机上的其他服务,正确做法是对齐 UID/GID 并保持最小权限。