非 root 用户运行
容器默认以 root 运行,存在安全风险,下面介绍如何切换为非 root 用户。
USER 指令
Dockerfile 中切换
dockerfile
FROM node:18-alpine
# 创建用户
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
# 切换用户
USER appuser
WORKDIR /app
COPY . .
CMD ["node", "server.js"]
USER 指令切换后,后续指令和容器进程都以指定用户运行。
运行时指定
Bash
# -u 参数指定用户
docker run -d -u 1001:1001 my-app
# 使用用户名
docker run -d -u appuser my-app
# 仅指定 UID
docker run -d -u 1001 my-app
最佳实践
创建专用用户
dockerfile
# Alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Debian/Ubuntu
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
# 使用
USER appuser
文件权限
dockerfile
FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
# 先以 root 拷贝
COPY . .
# 修改属主
RUN chown -R appuser:appgroup /app
# 切换用户
USER appuser
CMD ["node", "server.js"]
验证用户
Bash
# 查看容器内用户
docker exec my-app whoami
# 输出
appuser
# 查看 UID
docker exec my-app id
# 输出
uid=1001(appuser) gid=1001(appgroup)
限制
dockerfile
# 非 root 用户无法执行以下操作
# - 监听 1024 以下端口
# - 安装系统包
# - 修改系统文件
# - 访问 root 文件
解决端口限制
Bash
# 使用 1024 以上端口
docker run -d -u 1001 -p 3000:3000 my-app
# 或使用 Capabilities
docker run -d --cap-add NET_BIND_SERVICE my-app
多阶段构建
dockerfile
# 构建阶段(root)
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm run build
# 运行阶段(非 root)
FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/dist ./dist
RUN chown -R appuser:appgroup /app
USER appuser
CMD ["node", "dist/server.js"]
要点总结
- USER 指令在 Dockerfile 中切换用户,避免 root 运行
docker run -u运行时指定用户- 创建专用用户和组,设置正确文件权限
- 非 root 用户无法监听 1024 以下端口和安装系统包
- 生产环境必须使用非 root 用户运行容器
📝 发现内容有误?点击此处直接编辑