特权Docker容器使用docker exec访问ttyUSB提示Permission denied如何解决
核心问题原因
你碰到的是两个Docker环境下设备访问的典型权限匹配问题:
- 容器启动时指定的普通用户是后续才创建并加入dialout组的,容器初始进程以及默认exec启动的非登录进程,都不会自动刷新用户的附加组权限,进程的组权限在创建时就已固定
- 容器内
dialout组的GID和宿主机上/dev/ttyUSB0所属的组GID不匹配,即使用户加入容器内的dialout组,也没有对应设备的访问权限
修复方案
方案1:启动容器时提前做好用户和组匹配(推荐,一次配置永久生效)
- 先在宿主机查询串口设备的所属组GID:
stat -c "%g" /dev/ttyUSB0
- 启动容器前先获取相关ID参数,启动时完成权限映射:
# 宿主机执行,获取当前用户UID、GID,以及串口所属组GID(默认dialout组GID为20) HOST_UID=$(id -u) HOST_GID=$(id -g) SERIAL_GID=$(stat -c "%g" /dev/ttyUSB0) # 启动特权容器 docker run -itd --user ${HOST_UID}:${HOST_GID} --name test --privileged -v /dev:/dev ubuntu # 进入容器以root身份创建用户、匹配组ID docker exec -it --user 0 test sh -c " groupadd -g ${HOST_GID} user && \ groupadd -g ${SERIAL_GID} serial_access && \ useradd -m -u ${HOST_UID} -g ${HOST_GID} -G serial_access user && \ apt update && apt install -y picocom "
- 测试访问时指定启动登录shell,自动加载最新的组权限配置:
docker exec -it test sh -l -c "picocom /dev/ttyUSB0"
方案2:针对已运行容器的临时修复
如果容器已经启动无法重启,可以选择以下任意一种方式快速解决:
- 临时修改串口设备的全局访问权限:
# 以root身份进入容器修改设备权限 docker exec -it --user 0 test chmod 666 /dev/ttyUSB0 # 再用普通用户即可正常访问
- 不想修改设备全局权限的话,exec时加
-l参数启动登录shell,自动加载你后续配置的用户组权限:
docker exec -it test sh -l -c "picocom /dev/ttyUSB0"
内容的提问来源于stack exchange,提问作者wilson1994
相关产品推荐
相关产品推荐

