
类型:虚拟化技术
简介:基于操作系统层级的虚拟化技术,将软件与其依赖项打包为容器。
很多镜像默认以 root 用户运行。这样配置简单,但权限过大。对于长期运行的应用容器,建议尽量使用非 root 用户执行进程。非 root 运行不能解决所有安全问题,但能减少容器内进程的权限范围,是容器基础安全的一部分。
一、为什么不要默认 root
root 用户在容器内拥有很高权限。如果应用被错误配置或出现漏洞,攻击面会更大。使用非 root 用户可以限制写入范围和系统级操作。
适合非 root 运行的服务:
- Web API。
- 前端静态服务。
- 后台任务。
- 内部工具。
- 大多数普通业务应用。
二、Dockerfile 中创建用户
示例:
FROM node:20-alpine
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN chown -R app:app /app
USER app
CMD ["node", "server.js"]
关键点是先创建用户,再调整应用目录权限,最后使用 USER 切换运行用户。
三、挂载目录要匹配权限
如果容器需要写入挂载目录,宿主机目录权限也要匹配。否则会出现:
Permission denied
处理方法:
- 确认容器内用户 UID/GID。
- 调整宿主机目录权限。
- 避免把敏感目录挂载为可写。
- 只给应用需要的目录写权限。
四、低端口问题
非 root 用户可能无法绑定 80、443 等低端口。可以让应用监听高端口,例如 3000,再由反向代理转发。
示例:
services:
app:
image: example-app
ports:
- "8080:3000"
这样容器内应用监听 3000,宿主机通过 8080 访问。
五、排查权限错误
排查步骤:
- 查看容器运行用户。
- 查看应用目录所有者。
- 查看挂载目录权限。
- 检查应用写入路径。
- 检查端口绑定。
常用命令:
docker exec -it app id
docker exec -it app ls -l /app
FAQ
问:Docker 容器必须使用非 root 用户吗?
不是强制,但生产应用建议尽量使用非 root 用户运行。
问:非 root 用户会影响应用启动吗?
如果目录权限或端口配置不正确,可能影响启动,需要提前调整。
问:USER 指令放在 Dockerfile 哪里?
通常放在依赖安装、文件复制和权限调整之后,启动命令之前。

