1. 概述

Docker 是目前最流行的容器化工具之一,允许开发者构建、传输和运行容器化应用。

这些容器具有轻量、可移植、自包含等特点,只要宿主机安装了 Docker 引擎,就可以在任何环境中运行。Docker 容器将应用与其底层系统和依赖隔离开来,从而提升了应用的稳定性与安全性。

在本教程中,我们将学习如何在 Docker 容器中设置用户,并使其与宿主机上的用户保持一致。

2. Docker 容器中的用户机制

在深入设置用户之前,我们先理解一下 Docker 容器中的用户机制。

默认情况下,容器以 root 用户身份运行(取决于所使用的 base image)。每个 Docker 镜像中都预设了一个默认用户及其 UID(用户 ID)和 GID(组 ID)。通常,容器中运行的用户 UID 和 GID 与启动容器的宿主机用户一致。但也可以手动指定其他用户,以增强安全性并限制对资源的访问。

3. 使用 Dockerfile 设置用户

最佳实践建议:避免以 root 用户运行容器,以减少权限风险和潜在的文件权限问题。

我们可以在 Dockerfile 中使用 ARGRUNUSER 指令来创建一个非 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 参数将宿主机的用户身份映射到容器中。具体步骤如下:

  1. 获取当前用户的 UID 和 GID:
$ export UID=$(id -u)
$ export GID=$(id -g)
  1. 运行容器时传入用户信息:
$ 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 脚本实现自动配置。

原始标题:Setting the User in a Docker Container From the Host