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

Docker构建切换非root用户时出现/dev/stdout权限拒绝问题

解决Docker切换USER后执行RUN出现/dev/stdout权限拒绝的问题

问题原因

你遇到的是Docker 20.10.x早期版本与CentOS 7内核、容器运行时(runc)的兼容性bug:当通过USER指令切换到非root用户执行RUN步骤时,runc会尝试修改容器内/dev/stdout、/dev/stderr等伪终端设备的属主,但这些设备实际是从主机挂载而来,容器内非root用户没有权限修改,从而触发权限拒绝错误。

根本解决方案

1. 升级Docker版本

Docker在20.10.21及更高版本中修复了该权限处理bug,直接升级到稳定版即可解决:

# 停止Docker服务
systemctl stop docker

# 升级Docker(CentOS 7 yum安装方式)
yum update docker-ce docker-ce-cli containerd.io

# 重启Docker服务
systemctl start docker

2. 启用用户命名空间映射(无法升级Docker时)

通过配置Docker的用户命名空间映射,隔离容器内用户与主机用户,避免权限冲突:

  • 创建或编辑/etc/docker/daemon.json,添加以下内容:
    {
      "userns-remap": "default"
    }
    
  • 重启Docker服务:
    systemctl restart docker
    

注意:该配置会改变现有容器的用户映射关系,若有正在运行的容器,需提前备份或迁移。

3. 调整用户组权限(临时兼容方案)

容器内/dev/stdout等设备默认属于tty组,创建用户时将其加入该组可绕过权限问题:
修改useradd命令,添加--groups tty参数:

FROM centos:7

ARG username

RUN useradd \
    --home-dir /home/$username \
    --gid users \
    --groups tty \
    --shell /bin/bash \
    --create-home \
    $username

WORKDIR /home/$username
USER $username

RUN touch /tmp/d

临时规避方案优化

你当前使用的su命令规避可以调整为更简洁的写法:

# 替代USER指令,在RUN中直接切换用户执行命令
RUN su - $username -c "touch /tmp/d"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:55:19