Github Actions中docker共享卷读写报错Permission denied如何解决?
问题根本原因
权限报错本质是宿主机绑定挂载目录的所有者UID/GID,和容器内运行进程的用户UID/GID不匹配:
- 本地环境下,执行docker-compose的用户UID/GID和容器内运行服务的用户UID/GID刚好一致,所以可以正常读写
- Github Actions的runner默认运行任务的用户UID为1001(不同runner版本可能略有差异),和容器内用户的UID不匹配,挂载的
./cap目录在宿主机上的所有者是runner用户,容器内用户无写入权限
可选解决方案
方法1:指定容器运行用户和CI环境匹配
通过环境变量动态传入Github Actions runner的用户UID/GID,让容器内运行用户和宿主机目录所有者匹配:
- 修改
docker-compose.yml配置,给两个服务增加user字段:
web-api: ... user: "${UID:-1000}:${GID:-1000}" volumes: ... - ./cap:/opt/cap/src/cap cap-client: ... user: "${UID:-1000}:${GID:-1000}" volumes: - ./cap:/opt/cap/src/cap
- 在Github Actions workflow执行docker-compose前,导出当前用户的UID和GID到环境变量:
- name: 注入当前用户UID/GID环境变量 run: | echo "UID=$(id -u)" >> $GITHUB_ENV echo "GID=$(id -g)" >> $GITHUB_ENV
方法2:临时修改挂载目录权限(仅适合CI环境)
运行docker-compose前直接放开./cap目录的读写权限,改动最小:
- name: 修复共享目录权限 run: sudo chmod -R 777 ./cap
该方法安全性较低,仅限CI测试场景使用。
方法3:使用Docker匿名卷做共享存储
如果不需要把共享文件持久化到宿主机,直接用Docker原生匿名卷实现两个容器的文件共享,完全规避绑定挂载的权限问题:
# 声明共享匿名卷 volumes: cap-share: services: web-api: ... volumes: ... - cap-share:/opt/cap/src/cap cap-client: ... volumes: - cap-share:/opt/cap/src/cap
该方法不需要额外配置权限,兼容性最好。
内容的提问来源于stack exchange,提问作者ParthS007
相关产品推荐
相关产品推荐

