1. 概述
Docker 是目前最流行的容器化工具之一,允许开发者构建、传输和运行容器化应用。
这些容器具有轻量、可移植、自包含等特点,只要宿主机安装了 Docker 引擎,就可以在任何环境中运行。Docker 容器将应用与其底层系统和依赖隔离开来,从而提升了应用的稳定性与安全性。
在本教程中,我们将学习如何在 Docker 容器中设置用户,并使其与宿主机上的用户保持一致。
2. Docker 容器中的用户机制
在深入设置用户之前,我们先理解一下 Docker 容器中的用户机制。
默认情况下,容器以 root
用户身份运行(取决于所使用的 base image)。每个 Docker 镜像中都预设了一个默认用户及其 UID(用户 ID)和 GID(组 ID)。通常,容器中运行的用户 UID 和 GID 与启动容器的宿主机用户一致。但也可以手动指定其他用户,以增强安全性并限制对资源的访问。
3. 使用 Dockerfile 设置用户
✅ 最佳实践建议:避免以 root 用户运行容器,以减少权限风险和潜在的文件权限问题。
我们可以在 Dockerfile 中使用 ARG
、RUN
和 USER
指令来创建一个非 root 用户,并在容器中切换为该用户:
FROM alpine:latest
ARG DOCKER_USER=default_user
RUN addgroup -S $DOCKER_USER && adduser -S $DOCKER_USER -G $DOCKER_USER
USER $DOCKER_USER
CMD ["whoami"]
这段 Dockerfile 的工作流程如下:
- 使用 Alpine Linux 最新版本作为基础镜像;
- 使用
ARG
指令定义一个构建参数DOCKER_USER
,默认值为default_user
; - 通过
RUN
指令添加一个系统用户和组,-S
表示创建系统用户; - 使用
USER
指令切换容器启动时使用的用户; CMD
指令运行whoami
,用于验证当前用户。
构建镜像时可以传入自定义用户名:
$ docker build --build-arg DOCKER_USER=baeldung -t dynamicuser .
运行容器:
$ docker run --rm --name dynamicuser dynamicuser
baeldung
输出结果验证了容器内确实以 baeldung
用户身份运行。
4. 使用 --user
参数在运行时指定用户
✅ 优点:可以在运行时动态指定用户 UID 和 GID,更加灵活。
我们也可以在执行 docker run
命令时,通过 --user
参数将宿主机的用户身份映射到容器中。具体步骤如下:
- 获取当前用户的 UID 和 GID:
$ export UID=$(id -u)
$ export GID=$(id -g)
- 运行容器时传入用户信息:
$ docker run --rm \
--user $UID:$GID \
--workdir="/home/$USER" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
alpine ash -c "whoami"
输出示例:
centos
说明容器内成功使用了宿主机的 centos
用户。
💡 关键点:
--user $UID:$GID
:设置容器内运行的用户身份;--workdir
:设置容器内的工作目录;--volume
:挂载/etc/passwd
、/etc/group
、/etc/shadow
等文件,使容器可以识别宿主机用户信息;ash -c "whoami"
:执行命令验证当前用户。
⚠️ 缺点:
这种方式相比 Dockerfile 更复杂,需要在运行前导出 UID/GID,并挂载多个系统文件,适用于临时调试或 CI/CD 场景。
5. 总结
我们介绍了两种在 Docker 容器中设置用户的方法:
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Dockerfile | 简单、可复用、适合镜像构建 | 用户固定,灵活性差 | 构建生产镜像时推荐 |
--user 参数 |
运行时动态设置用户,灵活 | 配置复杂,需挂载系统文件 | 调试或临时使用 |
📌 推荐实践:
- 在构建镜像时就使用非 root 用户,提升安全性;
- 如果需要根据运行环境动态设置用户,可以结合
--user
参数和 shell 脚本实现自动配置。