fix(update): rewrite file-service URL to internal address for private deployments

UpdateAssetService: add FILE_BASE_URL / FILE_SERVICE_INTERNAL_URL config; any URL
starting with FILE_BASE_URL is rewritten to the internal file-service address instead
of going through the external domain, fixing APK inspect timeout on private deployments.

SystemUpdateService: add patchDockerComposeUpdateService() to inject FILE_BASE_URL and
FILE_SERVICE_INTERNAL_URL into existing customers' docker-compose.yml on update.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-05-22 16:03:09 +08:00
父节点 32aa3c0eef
当前提交 138360b760
共有 2 个文件被更改,包括 39 次插入4 次删除

查看文件

@ -93,6 +93,7 @@ public class SystemUpdateService {
patchNginxFileRoute(emit);
patchNginxUpdateTimeout(emit);
patchDockerComposeFileService(emit);
patchDockerComposeUpdateService(emit);
}
private void patchNginxUpdateTimeout(Consumer<String> emit) {
@ -166,6 +167,32 @@ public class SystemUpdateService {
}
}
private void patchDockerComposeUpdateService(Consumer<String> emit) {
Path composeFile = Paths.get(deployRoot, "docker-compose.yml");
if (!Files.exists(composeFile)) return;
try {
String content = Files.readString(composeFile);
if (content.contains("FILE_SERVICE_INTERNAL_URL")) return;
String consoleDomain = readEnvValue(Paths.get(deployRoot, "config", "xuqm.env"), "CONSOLE_DOMAIN");
if (consoleDomain == null) consoleDomain = "";
String anchor = " SDK_TENANT_SERVICE_URL: \"http://tenant-service:9001\"\n";
if (!content.contains(anchor)) {
emit.accept(" [跳过] docker-compose update-service 补丁锚点未找到,请手动检查");
return;
}
String injection = anchor
+ " FILE_BASE_URL: \"" + consoleDomain + "\"\n"
+ " FILE_SERVICE_INTERNAL_URL: \"http://file-service:8086\"\n";
String patched = content.replace(anchor, injection);
Files.writeString(composeFile, patched, StandardOpenOption.TRUNCATE_EXISTING);
emit.accept(" [已修复] docker-compose: 补齐 update-service 的 FILE_BASE_URL 和 FILE_SERVICE_INTERNAL_URL");
} catch (IOException e) {
emit.accept(" [警告] docker-compose update-service 修复失败: " + e.getMessage());
}
}
// Docker helpers
private void dockerLogin(Consumer<String> emit) {

查看文件

@ -50,9 +50,12 @@ public class UpdateAssetService {
@Value("${update.base-url:https://update.dev.xuqinmin.com}")
private String baseUrl;
@Value("${file.service.internal-url:http://127.0.0.1:8086}")
@Value("${FILE_SERVICE_INTERNAL_URL:${file.service.internal-url:http://file-service:8086}}")
private String fileServiceInternalUrl;
@Value("${FILE_BASE_URL:}")
private String fileBaseUrl;
public UpdateAssetService(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@ -363,10 +366,15 @@ public class UpdateAssetService {
}
private RemotePackage downloadRemotePackage(String packageUrl, boolean tempFile) throws IOException {
// 同一台服务器上的 file-service 使用内部地址避免 Nginx HTTPS 代理的性能损耗
// Rewrite external file-service URLs to the internal Docker network address to avoid
// hairpin NAT / HTTPS overhead when update-service and file-service are co-located.
String internalUrl = packageUrl;
if (packageUrl != null && packageUrl.contains("file.dev.xuqinmin.com")) {
internalUrl = packageUrl.replace("https://file.dev.xuqinmin.com", fileServiceInternalUrl);
if (packageUrl != null) {
if (hasText(fileBaseUrl) && packageUrl.startsWith(fileBaseUrl)) {
internalUrl = fileServiceInternalUrl + packageUrl.substring(fileBaseUrl.length());
} else if (packageUrl.contains("file.dev.xuqinmin.com")) {
internalUrl = packageUrl.replace("https://file.dev.xuqinmin.com", fileServiceInternalUrl);
}
}
HttpURLConnection connection = (HttpURLConnection) new URL(internalUrl).openConnection();
connection.setConnectTimeout(15_000);