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 b2c992f..9ed5c33 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 @@ -173,30 +173,58 @@ public class SystemUpdateService { /** * 读取本地各服务的版本号(从 Docker 镜像 LABEL 中读取)。 + * 优先从运行中容器的真实镜像读取(避免 nginx 等使用官方镜像的服务构造出不存在的 registry 路径), + * 容器不存在时回退到 resolveServiceImageName 构造的路径。 */ public Map readLocalServiceVersions() { Map versions = new LinkedHashMap<>(); 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\"}}", - imageName - ).redirectErrorStream(true).start(); - String out = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim(); - p.waitFor(); - versions.put(svc, out.isEmpty() ? "unknown" : out); - } catch (Exception e) { - versions.put(svc, "unknown"); - } + versions.put(svc, readServiceVersion(svc)); } return versions; } + private String readServiceVersion(String service) { + // 优先:从运行中容器的真实镜像读取 + try { + Process ps = new ProcessBuilder( + "docker", "ps", + "--filter", "label=com.docker.compose.service=" + service, + "--format", "{{.Image}}" + ).redirectErrorStream(true).start(); + String imageRef = new String(ps.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim(); + ps.waitFor(); + if (!imageRef.isEmpty()) { + String version = readVersionLabel(imageRef.split("\n")[0].trim()); + if (version != null) return version; + } + } catch (Exception ignored) {} + + // 回退:构造期望镜像名(服务未运行时) + String imageName = resolveServiceImageName(service); + if (imageName == null) return "unknown"; + String version = readVersionLabel(imageName); + return version != null ? version : "unknown"; + } + + private String readVersionLabel(String imageName) { + try { + Process p = new ProcessBuilder( + "docker", "inspect", "--format", + "{{index .Config.Labels \"com.xuqm.version\"}}", + imageName + ).redirectErrorStream(true).start(); + String out = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim(); + int code = p.waitFor(); + if (code != 0 || out.isBlank()) return null; + return out; + } catch (Exception e) { + return null; + } + } + /** * 读取版本清单(versions.json)。 *