From 821745de6bf1429ed2761d22a21a7e2ce20ecd5e Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Wed, 24 Jun 2026 16:04:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(tenant-service):=20check-update=20nginx=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E8=AF=BB=E5=8F=96=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从运行容器的真实镜像读取版本标签,而非构造 registry/nginx:latest。 nginx 使用官方镜像(nginx:1.27-alpine),构造路径本地不存在导致 "no such object" 错误。 同时修复 docker inspect 错误退出码未判断的问题,避免将错误信息写入版本号字段。 Co-Authored-By: Claude Sonnet 4.6 --- .../tenant/service/SystemUpdateService.java | 56 ++++++++++++++----- 1 file changed, 42 insertions(+), 14 deletions(-) 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)。 *