diff --git a/tenant-service/src/main/java/com/xuqm/tenant/service/SystemUpdateService.java b/tenant-service/src/main/java/com/xuqm/tenant/service/SystemUpdateService.java index 382b744..b2c992f 100644 --- a/tenant-service/src/main/java/com/xuqm/tenant/service/SystemUpdateService.java +++ b/tenant-service/src/main/java/com/xuqm/tenant/service/SystemUpdateService.java @@ -49,6 +49,16 @@ public class SystemUpdateService { "file-service", "tenant-web", "im-service", "push-service", "update-service", "license-service", "bugcollect-service", "nginx" ); + // 镜像名与 compose service 名不一致的例外(历史命名遗留) + private static final Map SERVICE_IMAGE_OVERRIDES = Map.of( + "bugcollect-service", "xuqm-bugcollect-service" + ); + + // 使用 docker compose profile 的服务(未声明 profile 的服务不在此表中) + private static final Map SERVICE_COMPOSE_PROFILES = Map.of( + "bugcollect-service", "bugcollect" + ); + // 健康检查配置:新容器需在此时间内保持 running 状态才视为健康 private static final int HEALTH_CHECK_TIMEOUT_SEC = 60; private static final int HEALTH_STABLE_REQUIRED_SEC = 10; @@ -169,11 +179,13 @@ public class SystemUpdateService { List allServices = new ArrayList<>(OTHER_SERVICES); allServices.add("tenant-service"); for (String svc : allServices) { + String imageName = resolveServiceImageName(svc); + if (imageName == null) { versions.put(svc, "unknown"); continue; } try { Process p = new ProcessBuilder( "docker", "inspect", "--format", "{{index .Config.Labels \"com.xuqm.version\"}}", - "xuqmgroup/" + svc + ":latest" + imageName ).redirectErrorStream(true).start(); String out = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim(); p.waitFor(); @@ -311,10 +323,10 @@ public class SystemUpdateService { emit.accept(">>> 拉取镜像(" + toUpdate.size() + " 个服务)..."); for (String svc : toUpdate) { emit.accept(" pulling " + svc + " ..."); - exec(emit, "docker", "compose", "-f", composeFile, "pull", "--quiet", svc); + exec(emit, composeCmd(composeFile, svc, "pull", "--quiet", svc)); } emit.accept(" pulling tenant-service ..."); - exec(emit, "docker", "compose", "-f", composeFile, "pull", "--quiet", "tenant-service"); + exec(emit, composeCmd(composeFile, "tenant-service", "pull", "--quiet", "tenant-service")); emit.accept(">>> 镜像拉取完成"); restartAndSelfUpdate(emit, composeFile, oldImageIds); @@ -797,8 +809,7 @@ public class SystemUpdateService { for (String svc : OTHER_SERVICES) { emit.accept(" restarting " + svc + " ..."); - exec(emit, "docker", "compose", "-f", composeFile, - "up", "-d", "--no-deps", "--force-recreate", svc); + exec(emit, composeCmd(composeFile, svc, "up", "-d", "--no-deps", "--force-recreate", svc)); // 拿到 compose up 之后最新创建的容器 ID,排除旧容器干扰 String newContainerId = getNewestContainerId(svc); emit.accept(" [debug] " + svc + " newContainerId=" + newContainerId); @@ -1027,7 +1038,8 @@ public class SystemUpdateService { return ok; } - /** 从 .env 读取 REGISTRY 和 IMAGE_TAG,拼接服务完整镜像名(registry/service:tag)。 */ + /** 从 .env 读取 REGISTRY 和 IMAGE_TAG,拼接服务完整镜像名(registry/image:tag)。 + * 部分服务镜像名与 compose service 名不同,通过 SERVICE_IMAGE_OVERRIDES 处理。 */ private String resolveServiceImageName(String service) { try { Path envFile = Paths.get(deployRoot, ".env"); @@ -1035,12 +1047,24 @@ public class SystemUpdateService { String imageTag = readEnvValue(envFile, "IMAGE_TAG"); if (registry == null) return null; if (imageTag == null || imageTag.isBlank()) imageTag = "latest"; - return registry + "/" + service + ":" + imageTag; + String imageName = SERVICE_IMAGE_OVERRIDES.getOrDefault(service, service); + return registry + "/" + imageName + ":" + imageTag; } catch (Exception e) { return null; } } + /** 构造 docker compose 命令,自动注入该服务所需的 --profile 参数。 */ + private String[] composeCmd(String composeFile, String service, String... subCmd) { + List cmd = new ArrayList<>(); + cmd.add("docker"); cmd.add("compose"); + String profile = SERVICE_COMPOSE_PROFILES.get(service); + if (profile != null) { cmd.add("--profile"); cmd.add(profile); } + cmd.add("-f"); cmd.add(composeFile); + cmd.addAll(Arrays.asList(subCmd)); + return cmd.toArray(new String[0]); + } + // ── 配置文件热修复 ────────────────────────────────────────────────────────── private void patchConfigs(Consumer emit) {