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
相关产品推荐
相关产品推荐

