@@ -105,6 +105,22 @@ func containerNotFound(out []byte) bool {
105105 return false
106106}
107107
108+ // containerStartUnrecoverable 判断 docker start 失败是否因网络已删除等导致无法恢复,需删容器后重建
109+ func containerStartUnrecoverable (out []byte ) bool {
110+ s := string (out )
111+ lower := strings .ToLower (s )
112+ if strings .Contains (lower , "network" ) && (strings .Contains (lower , "not found" ) || strings .Contains (lower , "no such" )) {
113+ return true
114+ }
115+ if strings .Contains (lower , "could not find network" ) || strings .Contains (lower , "could not attach to network" ) {
116+ return true
117+ }
118+ if strings .Contains (lower , "failed to create endpoint" ) || strings .Contains (lower , "failed to get network" ) {
119+ return true
120+ }
121+ return false
122+ }
123+
108124// dockerPermissionDenied 判断是否为访问 Docker 权限/连接错误(宿主机 socket 需对 Manager 容器可访问)
109125func dockerPermissionDenied (out []byte ) bool {
110126 s := string (out )
@@ -180,12 +196,18 @@ func StartRunnerContainer(ctx context.Context, cfg *config.Config, runnerName, i
180196 return dockerCmdError ("docker ps" , out , err )
181197 }
182198 if len (strings .TrimSpace (string (out ))) > 0 {
183- out , err := dockerCmd (ctx , "start" , cn )
184- if err != nil {
185- return dockerCmdError ("docker start" , out , err )
199+ startOut , startErr := dockerCmd (ctx , "start" , cn )
200+ if startErr == nil {
201+ time .Sleep (2 * time .Second )
202+ return CallAgentStart (ctx , cn , cfg .Runners .AgentPort )
203+ }
204+ // start 失败且为网络已删除等不可恢复原因时,删除旧容器并走下方「创建新容器」流程(如 compose down 后网络被删)
205+ if containerStartUnrecoverable (startOut ) {
206+ _ , _ = dockerCmd (ctx , "rm" , "-f" , cn )
207+ // fall through to create new container
208+ } else {
209+ return dockerCmdError ("docker start" , startOut , startErr )
186210 }
187- time .Sleep (2 * time .Second )
188- return CallAgentStart (ctx , cn , cfg .Runners .AgentPort )
189211 }
190212 // 创建新容器
191213 // 容器模式下若 Manager 在容器内(base_path 通常为 /app/runners),未设置 volume_host_path 会导致 docker create -v 使用容器内路径,宿主机上无效
0 commit comments