Skip to content

Commit c8fb6d4

Browse files
committed
fix: docker images build
1 parent 56a3b3c commit c8fb6d4

File tree

6 files changed

+35
-9
lines changed

6 files changed

+35
-9
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# 宿主机映射端口,默认 8080
1111
# MANAGER_PORT=8080
1212
#
13-
# Job 内 Docker 使用 DinD(仅非容器模式时有效):取消下一行注释
13+
# Job 内 Docker 使用 DinD(仅非容器模式时有效)。容器模式下请勿设置此项,Manager 必须用宿主机 socket
1414
# DOCKER_HOST=tcp://runner-dind:2375
1515
#
1616
# 容器模式且 Manager 在容器内时,config.yaml 中 runners.volume_host_path 需为宿主机 runners 的绝对路径,例如:

cmd/runner-manager/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ func main() {
6464
if err != nil {
6565
log.Fatalf("加载配置失败: %v", err)
6666
}
67+
if cfg.Runners.ContainerMode && runner.ManagerDockerHostIsDind() {
68+
log.Printf("警告: 容器模式已开启,但 DOCKER_HOST 指向 TCP(DinD)。Manager 必须使用宿主机 Docker(socket)才能创建/启停 Runner 容器。请在 .env 中移除或注释 DOCKER_HOST=tcp://runner-dind:2375")
69+
}
6770

6871
e := echo.New()
6972
e.HideBanner = true

config.yaml.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ runners:
1212
base_path: ./runners
1313
items: [] # 预置 Runner 列表,也可通过 Web 界面添加
1414

15-
# 容器模式:每个 Runner 运行在独立容器中,Manager 通过 Docker 启停并通过容器内 Agent 获取状态
16-
# 启用后需保证 Manager 能执行 docker 且与 Runner 容器在同一网络(如 docker-compose 挂载宿主机 socket)
15+
# 容器模式:每个 Runner 运行在独立容器中,Manager 通过宿主机 Docker(socket)启停,并与 Runner 容器同网络
16+
# 启用后 Manager 必须使用宿主机 docker(勿设 DOCKER_HOST=tcp://runner-dind:2375);DinD 仅供 Runner 容器内 Job 使用
1717
# container_mode: true
1818
# container_image: ghcr.io/soulteary/runner-fleet-runner:main # 或 CI:ghcr.io/<owner>/<repo>:main-runner
1919
# container_network: runner-net

docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
# - Manager 需能访问宿主机 Docker(创建/启停 Runner 容器):下方已配置 group_add,请将 999 改为宿主机 docker 组 GID(getent group docker | cut -d: -f3);或改用 user: "0:0" 以 root 运行
1616
#
1717
# === 两种运行模式 ===
18-
# - 默认(container_mode: false):Runner 进程在 Manager 容器内运行,Job 需 Docker 时使用 DOCKER_HOST(当前为宿主机 socket)
19-
# - 容器模式(container_mode: true):每个 Runner 独立容器,Manager 通过宿主机 Docker 启停(需 socket,已配置)
20-
# 非容器模式且希望 Job 内 docker 使用 DinD:在 .env 中设置 DOCKER_HOST=tcp://runner-dind:2375(仅非容器模式;容器模式须用宿主机 socket)
18+
# - 默认(container_mode: false):Runner 进程在 Manager 容器内运行,Job 需 Docker 时可在 .env 设 DOCKER_HOST=tcp://runner-dind:2375 使用 DinD
19+
# - 容器模式(container_mode: true):每个 Runner 独立容器,Manager 必须用宿主机 Docker(socket)创建/启停 Runner;DinD 仅供 Runner 容器内 Job 使用。请勿在 .env 中设置 DOCKER_HOST=tcp://runner-dind:2375,否则点击启动会报错
2120

2221
services:
2322
runner-dind:
@@ -39,6 +38,7 @@ services:
3938
container_name: runner-manager
4039
depends_on:
4140
- runner-dind
41+
# 容器模式下必须用宿主机 socket,否则 Manager 无法创建 Runner 容器;默认 unix,勿改为 tcp://runner-dind:2375
4242
environment:
4343
DOCKER_HOST: ${DOCKER_HOST:-unix:///var/run/docker.sock}
4444
ports:

docs/docker.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ docker run -d --name runner-manager \
168168
```
169169

170170
3. **部署要求**:
171-
- Manager 必须能执行 `docker` 且能创建与 Manager 同网络的容器,故需挂载**宿主机** `docker.sock` 并设置 `DOCKER_HOST=unix:///var/run/docker.sock`(仓库内 `docker-compose.yml` 已按此配置)。Manager 镜像以非 root(UID 1001)运行,访问 socket 需加入宿主机 **docker 组**:在 docker-compose 中已配置 `group_add: [ "${DOCKER_GID:-999}" ]`,若宿主机 docker 组 GID 不是 999,请在 `.env` 中设置 `DOCKER_GID=<宿主机 GID>`(可用 `getent group docker | cut -d: -f3` 查看);或改为 `user: "0:0"` 以 root 运行。
171+
- **Manager 必须使用宿主机 Docker**(`unix:///var/run/docker.sock`)创建/启停 Runner 容器,**不能**把 `DOCKER_HOST` 设为 DinD(`tcp://runner-dind:2375`)。DinD 仅供 **Runner 容器内** Job 的 `docker build` 等使用;若在 `.env` 中设置了 `DOCKER_HOST=tcp://runner-dind:2375`,点击「启动」会报错,请移除或注释该行。宿主机需挂载 `docker.sock` 并设置 `DOCKER_HOST=unix:///var/run/docker.sock`(仓库内 `docker-compose.yml` 默认已配置)。Manager 以非 root(UID 1001)运行,访问 socket 需加入宿主机 **docker 组**:`group_add: [ "${DOCKER_GID:-999}" ]`,GID 不对时在 `.env` `DOCKER_GID=`;或改为 `user: "0:0"` 以 root 运行。
172172
- Runner 容器与 Manager、DinD 在同一网络(如 `runner-net`),以便 Manager 访问 Agent、Runner Job 内访问 DinD。
173173
- **Runner 名称**会映射为容器名(如 `github-runner-<名称>`),仅保留字母、数字、`-`、`_`。若两个名称映射后相同(如 `a.b` 与 `a-b`)会冲突,请使用可区分名称。
174174

internal/runner/container.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"fmt"
88
"net/http"
9+
"os"
910
"os/exec"
1011
"path/filepath"
1112
"regexp"
@@ -109,9 +110,14 @@ func dockerPermissionDenied(out []byte) bool {
109110
if strings.Contains(lower, "cannot connect to the docker daemon") || strings.Contains(lower, "is the docker daemon running") {
110111
return true
111112
}
113+
if strings.Contains(lower, "connection refused") {
114+
return true
115+
}
112116
return false
113117
}
114118

119+
const dockerAccessHint = "若 Manager 在容器内,请为 runner-manager 配置 group_add 使用宿主机 docker 组 GID(.env 中 DOCKER_GID=$(getent group docker | cut -d: -f3)),或使用 user: \"0:0\" 以 root 访问 socket"
120+
115121
// ContainerRunning 判断容器是否在运行
116122
func ContainerRunning(ctx context.Context, containerName string) (bool, error) {
117123
out, err := dockerCmd(ctx, "inspect", "-f", "{{.State.Running}}", containerName)
@@ -120,15 +126,32 @@ func ContainerRunning(ctx context.Context, containerName string) (bool, error) {
120126
return false, nil
121127
}
122128
if dockerPermissionDenied(out) {
123-
return false, fmt.Errorf("无法访问 Docker(权限不足或无法连接 daemon)。若 Manager 在容器内,请为 runner-manager 配置 group_add 使用宿主机 docker 组 GID,或使用 user: \"0:0\" 以 root 访问 socket: %w", err)
129+
return false, fmt.Errorf("无法访问 Docker(权限不足或无法连接 daemon)。%s: %w", dockerAccessHint, err)
124130
}
125-
return false, fmt.Errorf("docker inspect: %w", err)
131+
// 其它 exit 1 多为权限/连接问题(如 socket 不可访问),统一给出提示
132+
return false, fmt.Errorf("docker inspect 失败(%w)。%s", err, dockerAccessHint)
126133
}
127134
return strings.TrimSpace(string(out)) == "true", nil
128135
}
129136

137+
// managerMustUseHostDocker 提示:容器模式下 Manager 必须用宿主机 Docker 创建 Runner 容器,不能把 DOCKER_HOST 设为 DinD
138+
const errContainerModeNeedHostDocker = "容器模式下 Manager 必须使用宿主机 Docker(unix socket)创建/启停 Runner 容器,不能使用 DinD。请在 .env 中移除或注释 DOCKER_HOST=tcp://runner-dind:2375,使 Manager 使用默认 unix:///var/run/docker.sock;DinD 仅供 Runner 容器内 Job 的 docker build 等使用"
139+
140+
func managerDockerHostIsDind() bool {
141+
h := os.Getenv("DOCKER_HOST")
142+
return strings.HasPrefix(strings.TrimSpace(h), "tcp://")
143+
}
144+
145+
// ManagerDockerHostIsDind 供启动时检查:若为 true 且开启容器模式,Manager 无法创建 Runner 容器
146+
func ManagerDockerHostIsDind() bool {
147+
return managerDockerHostIsDind()
148+
}
149+
130150
// StartRunnerContainer 若容器不存在则创建并启动,若存在则 start;创建时挂载 installDir 到 /runner
131151
func StartRunnerContainer(ctx context.Context, cfg *config.Config, runnerName, installDir string) error {
152+
if cfg.Runners.ContainerMode && managerDockerHostIsDind() {
153+
return fmt.Errorf("%s", errContainerModeNeedHostDocker)
154+
}
132155
cn := ContainerName(runnerName)
133156
running, err := ContainerRunning(ctx, cn)
134157
if err != nil {

0 commit comments

Comments
 (0)