USER 是什么
USER 切换其后所有指令以及容器启动进程的身份,是容器非 root 运行的基础手段。容器内默认是 root,一旦应用存在提权漏洞,攻击者拿到的就是容器内的完整权限,换成普通用户能把影响面收窄一大截。
基本信息
| 用途 | 指定构建剩余步骤与运行时的用户、用户组 |
|---|---|
| 语法 | USER 用户名[:组],或 USER UID:GID 数字形式 |
| 位置 | 放在需要 root 的安装、复制步骤之后 |
| 作用范围 | 之后的 RUN、CMD、ENTRYPOINT 全部以该身份执行 |
| 验证 | docker exec <容器> id 看实际身份 |
典型使用场景
- 让服务以非 root 身份运行,缩小容器内漏洞被利用后的破坏范围
- 满足安全基线要求:很多合规检查直接判定 root 运行不合格
- 配合 COPY --chown 让应用目录属主正确,进程能正常写日志与临时文件
- 多架构、多基础镜像复用时统一用数字 UID:GID,不依赖镜像里是否建过同名账号
- 编排环境里统一约束运行身份,镜像与 Pod 策略保持同一套账号口径
示例
示例
# Debian/Ubuntu 系基础镜像
RUN groupadd -r -g 10001 app && useradd -r -u 10001 -g app -m app
# Alpine 系基础镜像,命令与参数写法不同
RUN addgroup -S -g 10001 app && adduser -S -u 10001 -G app app
COPY --chown=10001:10001 ./dist /app
USER 10001:10001
CMD ["/app/server"]非 root 前后要检查的点
| 检查项 | 常见问题 | 处理办法 |
|---|---|---|
| 工作目录属主 | 目录仍属 root,进程写文件失败 | COPY --chown 或 RUN chown 提前改属主 |
| 监听端口 | 绑定 1024 以下端口需要特权 | 改用高位端口,由映射或反向代理对外 |
| 日志与临时目录 | /var/log、/tmp 权限不足 | 预建目录并授权,或直接输出到 stdout |
| 健康检查命令 | 检查脚本依赖只有 root 能执行的命令 | 换成普通用户可执行的等价命令 |
USER 只影响后续指令的执行身份,需要 root 的安装步骤必须放在 USER 之前;切走之后再执行 apt、apk 会因权限不足直接失败。
编排环境里镜像的 USER 可能被 runAsUser、runAsNonRoot 之类的参数覆盖,最终以运行参数为准,验证时进容器执行 id 看实际值。