You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构建以非root用户运行的Ubuntu容器遇权限问题求助

Ubuntu 24.04容器挂载主机目录权限问题解决

问题背景

要构建Ubuntu 24.04镜像用于代码构建,要求以非root用户(builder)运行容器,主机与容器共享源码目录,但容器内写入目录时出现权限拒绝。对比Ubuntu 20.04镜像无此问题,同时使用-u $(id -u)运行容器时,会出现无用户名、用户不在sudo组的异常。

涉及的Dockerfile

FROM ubuntu:24.04
USER root

RUN apt-get update -y
RUN apt-get install sudo useradd adduser -y

RUN useradd -ms /bin/bash builder | chpasswd
RUN adduser builder sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER jenkins
RUN mkdir -p /home/builder/workspace
WORKDIR /home/builder/workspace

权限问题现象

容器内builder用户uid为1001,主机用户uid为1000,挂载主机目录后无法写入:

builder@95cfd88194e0:~/workspace$ touch x
touch: cannot touch 'x': Permission denied

使用-u $(id -u)运行时的异常:

I have no name!@0123456789ab:/my/path$ id
uid=1005 gid=0(root) groups=0(root)

问题原因

  1. Linux权限本质:文件系统权限基于uid/gid而非用户名,主机与容器uid不匹配时,容器用户无对应目录的读写权限。
  2. Ubuntu 20.04 vs 24.04差异:Ubuntu 24.04基础镜像对用户权限、文件系统权限的默认配置更严格,没有兼容uid不匹配的场景;而20.04镜像或当时的Docker版本可能对挂载目录权限有宽松处理,掩盖了uid不匹配的问题。

解决方案

方案一:启动容器时动态创建匹配主机uid/gid的用户(推荐)

无需修改主机配置,也不用固定容器内的uid,灵活适配不同主机环境。

步骤1:调整Dockerfile

FROM ubuntu:24.04
USER root

# 安装必要工具,gosu用于安全切换用户
RUN apt-get update -y && apt-get install -y sudo gosu && rm -rf /var/lib/apt/lists/*

# 创建工作目录
RUN mkdir -p /home/builder/workspace
WORKDIR /home/builder/workspace

# 添加启动脚本
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
CMD ["bash"]

步骤2:编写entrypoint.sh脚本

#!/bin/bash
set -e

# 从环境变量获取主机的uid/gid,默认值设为1000(常见普通用户uid)
HOST_UID=${HOST_UID:-1000}
HOST_GID=${HOST_GID:-1000}

# 创建匹配主机gid的用户组
if ! getent group "${HOST_GID}" > /dev/null; then
    groupadd -g "${HOST_GID}" builder-group
fi

# 创建匹配主机uid的用户,并加入sudo组
if ! getent passwd "${HOST_UID}" > /dev/null; then
    useradd -m -u "${HOST_UID}" -g "${HOST_GID}" -s /bin/bash builder
    usermod -aG sudo builder
    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
fi

# 切换到builder用户执行容器命令
exec gosu builder "$@"

步骤3:构建并运行容器

# 构建镜像
docker build --tag build .

# 运行容器,传入主机当前用户的uid和gid
docker run -it \
  -v /home/myname/workspace:/home/builder/workspace \
  -e HOST_UID=$(id -u) \
  -e HOST_GID=$(id -g) \
  build

方案二:临时调整主机目录权限(不推荐,安全性低)

直接给主机共享目录添加其他用户的写入权限:

chmod o+w /home/myname/workspace

此方法简单但会降低目录安全性,仅适合测试场景。

方案三:挂载主机用户信息文件

通过挂载主机的/etc/passwd和/etc/group,让容器直接使用主机的用户命名空间:

docker run -it \
  -v /home/myname/workspace:/home/builder/workspace \
  -u $(id -u):$(id -g) \
  -v /etc/passwd:/etc/passwd:ro \
  -v /etc/group:/etc/group:ro \
  build

此方法无需修改镜像,但需确保主机用户信息在容器中有效,若需要sudo权限,需额外配置容器内的sudo规则。


内容的提问来源于stack exchange,提问作者Uri London

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:02:37