根本原因是容器内运行用户uid/gid(默认998)与宿主机挂载目录所有者不匹配;需统一uid,推荐方案为chown -r 998:998调整宿主机目录属主,或启动时--user指定匹配uid/gid,或构建自定义镜像预设用户。

GitLab Runner 容器启动后对挂载目录(如 /etc/gitlab-runner、/cache)完全无法读写,根本原因不是路径错了,而是容器内运行用户 UID/GID 与宿主机目标目录所有者不匹配。官方镜像默认以 UID=998/GID=998 的非 root 用户运行,若宿主机上该 UID 无对应用户或目录归属为其他 UID(比如 1000),就会触发全链路权限拒绝。
确认当前 Runner 容器实际运行 UID
进入正在运行的容器,查看进程真实身份:
- 执行
docker exec -it gitlab-runner ps aux | head -2,观察第一行 USER 列是否为998或gitlab-runner - 在容器内运行
id,确认 uid/gid 输出值 - 同步检查宿主机挂载目录归属:
ls -ld /opt/gitlab-runner/config /opt/gitlab-runner/cache,比对 owner 数字是否等于容器 UID
三类可靠修复方式(按推荐顺序)
不建议直接 chmod 777 或用 root 运行,应优先保持最小权限原则:
-
方式一:调整宿主机目录属主(最常用)
将挂载目录所有权设为容器 UID 对应值:sudo chown -R 998:998 /opt/gitlab-runner/config /opt/gitlab-runner/cache
注意:若宿主机未创建 UID 998 用户,chown 仍可成功(Linux 只认数字 ID),但需确保该 UID 不被其他服务占用 -
方式二:启动时显式指定 UID/GID(推荐用于多用户环境)
让容器以宿主机当前用户身份运行:docker run -d \--user $(id -u):$(id -g) \-v /opt/gitlab-runner/config:/etc/gitlab-runner \-v /opt/gitlab-runner/cache:/cache \gitlab/gitlab-runner:alpine -
方式三:构建自定义镜像并预设 UID(适合统一运维)
在 Dockerfile 中添加:RUN groupadd -g 1001 runner && useradd -u 1001 -g runner -m runnerUSER runner
再配合--user 1001:1001启动,实现 UID 全局对齐
避免 config.toml 权限反复失效的关键点
Runner 注册后会自动写入 config.toml,若该文件由 root 创建或属主错误,后续重启仍会失败:
- 首次注册前,确保
/opt/gitlab-runner/config目录已由正确 UID 拥有(见上一步) - 注册命令不要加
sudo;如果已用 root 注册过,先清空目录:sudo rm -rf /opt/gitlab-runner/config/*,再 chown 后重试 - 注册完成后,检查
config.toml文件权限:-rw-------是正常状态,但 owner 必须是容器 UID
验证是否真正修复
完成操作后,执行以下检查:
- 重启容器:
docker restart gitlab-runner - 查看日志是否有
Permission denied或open /etc/gitlab-runner/config.toml: permission denied类报错 - 手动触发一次 CI job,确认 cache 目录下生成子目录且能正常读写(如
/cache/project-123/) - 进入容器执行:
touch /etc/gitlab-runner/test && ls -l /etc/gitlab-runner/test,确认文件属主与容器 uid 一致











