feat(webterm): YAML-first 部署独立测速服务

This commit is contained in:
Codex
2026-07-11 13:53:14 +02:00
parent d60991c3c6
commit da57a60ce2
2 changed files with 42 additions and 0 deletions
+8
View File
@@ -242,6 +242,14 @@ targets:
- source: /root/user_uploads
target: /root/user_uploads
readOnly: false
networkSpeedTest:
enabled: true
containerName: web-terminal-7683-speed-test
hostPort: 7783
containerPort: 7781
publicUrl: "http://{hostname}:7783"
downloadBytes: 16777216
uploadBytes: 8388608
autoStartSessions:
- title: 决策中心
cwd: /root/unidesk
+34
View File
@@ -79,6 +79,7 @@ interface WebtermTarget {
privileged: boolean;
pid: "host" | "container";
sourceMounts: Array<{ source: string; target: string; readOnly: boolean }>;
networkSpeedTest: { enabled: boolean; containerName: string; hostPort: number; containerPort: number; publicUrl: string; downloadBytes: number; uploadBytes: number } | null;
autoStartSessions: Array<{ title: string; cwd: string; command: string; cols: number; rows: number; resumePrompt: boolean; fallbackShell: boolean }>;
sessionStartModes: SessionStartModes;
autoResumePrompt: AutoResumePrompt;
@@ -351,6 +352,16 @@ function parseTarget(
const environment = parseEnvironment(recordField(runtime, "environment", `${path}.runtime`), `${path}.runtime.environment`);
const sourceMounts = parseSourceMounts(runtime.sourceMounts, `${path}.runtime.sourceMounts`);
const autoStartSessions = parseAutoStartSessions(runtime.autoStartSessions, `${path}.runtime.autoStartSessions`);
const speedRaw = runtime.networkSpeedTest === undefined ? null : recordField(runtime, "networkSpeedTest", `${path}.runtime`);
const networkSpeedTest = speedRaw === null ? null : {
enabled: booleanField(speedRaw, "enabled", `${path}.runtime.networkSpeedTest`),
containerName: stringField(speedRaw, "containerName", `${path}.runtime.networkSpeedTest`),
hostPort: portField(speedRaw, "hostPort", `${path}.runtime.networkSpeedTest`),
containerPort: portField(speedRaw, "containerPort", `${path}.runtime.networkSpeedTest`),
publicUrl: stringField(speedRaw, "publicUrl", `${path}.runtime.networkSpeedTest`),
downloadBytes: integerField(speedRaw, "downloadBytes", `${path}.runtime.networkSpeedTest`),
uploadBytes: integerField(speedRaw, "uploadBytes", `${path}.runtime.networkSpeedTest`),
};
const target: WebtermTarget = {
id: stringField(record, "id", path),
enabled: booleanField(record, "enabled", path),
@@ -368,6 +379,7 @@ function parseTarget(
privileged: booleanField(runtime, "privileged", `${path}.runtime`),
pid: parsePid(stringField(runtime, "pid", `${path}.runtime`), `${path}.runtime.pid`),
sourceMounts,
networkSpeedTest,
autoStartSessions,
sessionStartModes,
autoResumePrompt,
@@ -421,6 +433,11 @@ function renderCompose(target: WebtermTarget): string {
BROWSER_TERMINAL_HISTORY_JSON: JSON.stringify(target.runtime.browserTerminalHistory),
BROWSER_OUTPUT_POLICY_JSON: JSON.stringify(target.runtime.browserOutputPolicy),
BROWSER_PERFORMANCE_JSON: JSON.stringify(target.runtime.browserPerformance),
...(target.runtime.networkSpeedTest?.enabled ? {
NETWORK_SPEED_TEST_PUBLIC_URL: target.runtime.networkSpeedTest.publicUrl,
NETWORK_SPEED_TEST_DOWNLOAD_BYTES: String(target.runtime.networkSpeedTest.downloadBytes),
NETWORK_SPEED_TEST_UPLOAD_BYTES: String(target.runtime.networkSpeedTest.uploadBytes),
} : {}),
};
const envLines = Object.entries(environment)
.map(([key, value]) => ` ${key}: ${quoteYaml(value)}`)
@@ -428,6 +445,21 @@ function renderCompose(target: WebtermTarget): string {
const volumeLines = target.runtime.sourceMounts
.map((mount) => ` - ${quoteYaml(`${mount.source}:${mount.target}${mount.readOnly ? ":ro" : ""}`)}`)
.join("\n");
const speed = target.runtime.networkSpeedTest;
const speedTestService = speed?.enabled ? `
network-speed-test:
image: ${target.runtime.image}
container_name: ${speed.containerName}
restart: unless-stopped
command: ["node", "src/speed-server.js"]
ports:
- "${speed.hostPort}:${speed.containerPort}"
volumes:
- "/root/webterm/src:/app/src:ro"
environment:
SPEED_TEST_HOST: "0.0.0.0"
SPEED_TEST_PORT: "${speed.containerPort}"
` : "";
return `name: ${target.runtime.composeProject}
services:
@@ -445,6 +477,7 @@ services:
${volumeLines}
environment:
${envLines}
${speedTestService}
`;
}
@@ -474,6 +507,7 @@ function policyChecks(target: WebtermTarget, compose: string): Array<Record<stri
{ name: "public-https", ok: target.publicExposure.publicBaseUrl.startsWith("https://"), detail: target.publicExposure.publicBaseUrl },
{ name: "compose-port", ok: compose.includes(`"${target.runtime.hostPort}:${target.runtime.containerPort}"`), detail: `${target.runtime.hostPort}:${target.runtime.containerPort}` },
{ name: "source-mounts-present", ok: target.runtime.sourceMounts.length >= 3, detail: `mounts=${target.runtime.sourceMounts.length}` },
{ name: "network-speed-test", ok: !target.runtime.networkSpeedTest?.enabled || compose.includes(`container_name: ${target.runtime.networkSpeedTest.containerName}`), detail: target.runtime.networkSpeedTest?.enabled ? `${target.runtime.networkSpeedTest.hostPort}:${target.runtime.networkSpeedTest.containerPort}` : "disabled" },
];
}