From 2176b68e50d83fd2a182b1809db8cef7c035cf95 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 5 Apr 2026 22:26:59 +0100 Subject: [PATCH] fix: batch docker config writes --- docs/install/docker.md | 10 +---- scripts/docker/setup.sh | 53 +++++++++++------------ scripts/e2e/openwebui-docker.sh | 77 +++++++++------------------------ src/docker-setup.e2e.test.ts | 8 +--- 4 files changed, 49 insertions(+), 99 deletions(-) diff --git a/docs/install/docker.md b/docs/install/docker.md index 927a3f5e3f7..aa38e1b33e4 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -103,12 +103,7 @@ docker build -t openclaw:local -f Dockerfile . docker compose run --rm --no-deps --entrypoint node openclaw-gateway \ dist/index.js onboard --mode local --no-install-daemon docker compose run --rm --no-deps --entrypoint node openclaw-gateway \ - dist/index.js config set gateway.mode local -docker compose run --rm --no-deps --entrypoint node openclaw-gateway \ - dist/index.js config set gateway.bind lan -docker compose run --rm --no-deps --entrypoint node openclaw-gateway \ - dist/index.js config set gateway.controlUi.allowedOrigins \ - '["http://localhost:18789","http://127.0.0.1:18789"]' --strict-json + dist/index.js config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]' docker compose up -d openclaw-gateway ``` @@ -395,8 +390,7 @@ scripts/sandbox-setup.sh Reset gateway mode and bind: ```bash - docker compose run --rm openclaw-cli config set gateway.mode local - docker compose run --rm openclaw-cli config set gateway.bind lan + docker compose run --rm openclaw-cli config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"}]' docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789 ``` diff --git a/scripts/docker/setup.sh b/scripts/docker/setup.sh index 2be33bdd2f5..fe630101588 100755 --- a/scripts/docker/setup.sh +++ b/scripts/docker/setup.sh @@ -105,33 +105,36 @@ read_env_gateway_token() { fi } -ensure_control_ui_allowed_origins() { - if [[ "${OPENCLAW_GATEWAY_BIND}" == "loopback" ]]; then - return 0 +sync_gateway_config() { + local allowed_origin_json="" + local current_allowed_origins="" + local batch_json="" + + if [[ "${OPENCLAW_GATEWAY_BIND}" != "loopback" ]]; then + allowed_origin_json="$(printf '["http://localhost:%s","http://127.0.0.1:%s"]' "$OPENCLAW_GATEWAY_PORT" "$OPENCLAW_GATEWAY_PORT")" + current_allowed_origins="$( + run_prestart_cli config get gateway.controlUi.allowedOrigins 2>/dev/null || true + )" + current_allowed_origins="${current_allowed_origins//$'\r'/}" fi - local allowed_origin_json - local current_allowed_origins - allowed_origin_json="$(printf '["http://localhost:%s","http://127.0.0.1:%s"]' "$OPENCLAW_GATEWAY_PORT" "$OPENCLAW_GATEWAY_PORT")" - current_allowed_origins="$( - run_prestart_cli config get gateway.controlUi.allowedOrigins 2>/dev/null || true - )" - current_allowed_origins="${current_allowed_origins//$'\r'/}" - - if [[ -n "$current_allowed_origins" && "$current_allowed_origins" != "null" && "$current_allowed_origins" != "[]" ]]; then - echo "Control UI allowlist already configured; leaving gateway.controlUi.allowedOrigins unchanged." - return 0 + batch_json="$(printf '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"%s"}' "$OPENCLAW_GATEWAY_BIND")" + if [[ -n "$allowed_origin_json" ]]; then + if [[ -n "$current_allowed_origins" && "$current_allowed_origins" != "null" && "$current_allowed_origins" != "[]" ]]; then + echo "Control UI allowlist already configured; leaving gateway.controlUi.allowedOrigins unchanged." + else + batch_json+=",{\"path\":\"gateway.controlUi.allowedOrigins\",\"value\":$allowed_origin_json}" + fi fi + batch_json+="]" - run_prestart_cli config set gateway.controlUi.allowedOrigins "$allowed_origin_json" --strict-json \ - >/dev/null - echo "Set gateway.controlUi.allowedOrigins to $allowed_origin_json for non-loopback bind." -} - -sync_gateway_mode_and_bind() { - run_prestart_cli config set gateway.mode local >/dev/null - run_prestart_cli config set gateway.bind "$OPENCLAW_GATEWAY_BIND" >/dev/null + run_prestart_cli config set --batch-json "$batch_json" >/dev/null echo "Pinned gateway.mode=local and gateway.bind=$OPENCLAW_GATEWAY_BIND for Docker setup." + if [[ -n "$allowed_origin_json" ]]; then + if [[ -z "$current_allowed_origins" || "$current_allowed_origins" == "null" || "$current_allowed_origins" == "[]" ]]; then + echo "Set gateway.controlUi.allowedOrigins to $allowed_origin_json for non-loopback bind." + fi + fi } run_prestart_gateway() { @@ -514,11 +517,7 @@ run_prestart_cli onboard --mode local --no-install-daemon echo "" echo "==> Docker gateway defaults" -sync_gateway_mode_and_bind - -echo "" -echo "==> Control UI origin allowlist" -ensure_control_ui_allowed_origins +sync_gateway_config echo "" echo "==> Provider setup (optional)" diff --git a/scripts/e2e/openwebui-docker.sh b/scripts/e2e/openwebui-docker.sh index 71f662a5fd3..08a555fdd2f 100755 --- a/scripts/e2e/openwebui-docker.sh +++ b/scripts/e2e/openwebui-docker.sh @@ -63,68 +63,31 @@ docker run -d \ [ -f "$entry" ] || entry=dist/index.js openai_api_key="${OPENAI_API_KEY:?OPENAI_API_KEY required}" - node - <<'"'"'NODE'"'"' "$openai_api_key" + batch_file="$(mktemp /tmp/openclaw-openwebui-config.XXXXXX.json)" + OPENCLAW_CONFIG_BATCH_PATH="$batch_file" node - <<'"'"'NODE'"'"' "$openai_api_key" const fs = require("node:fs"); -const path = require("node:path"); const openaiApiKey = process.argv[2]; -const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json"); -const config = fs.existsSync(configPath) - ? JSON.parse(fs.readFileSync(configPath, "utf8")) - : {}; -const existingOpenAI = config.models?.providers?.openai ?? {}; -config.models = { - ...(config.models || {}), - providers: { - ...(config.models?.providers || {}), - openai: { - ...existingOpenAI, - baseUrl: - typeof existingOpenAI.baseUrl === "string" && existingOpenAI.baseUrl.trim() - ? existingOpenAI.baseUrl - : process.env.OPENAI_BASE_URL || "https://api.openai.com/v1", - apiKey: openaiApiKey, - models: Array.isArray(existingOpenAI.models) ? existingOpenAI.models : [], - }, +const batchPath = process.env.OPENCLAW_CONFIG_BATCH_PATH; +const entries = [ + { path: "models.providers.openai.apiKey", value: openaiApiKey }, + { + path: "models.providers.openai.baseUrl", + value: (process.env.OPENAI_BASE_URL || "https://api.openai.com/v1").trim(), }, -}; -config.gateway = { - ...(config.gateway || {}), - controlUi: { - ...(config.gateway?.controlUi || {}), - enabled: false, - }, - mode: "local", - bind: "lan", - auth: { - ...(config.gateway?.auth || {}), - mode: "token", - token: process.env.OPENCLAW_GATEWAY_TOKEN, - }, - http: { - ...(config.gateway?.http || {}), - endpoints: { - ...(config.gateway?.http?.endpoints || {}), - chatCompletions: { - ...(config.gateway?.http?.endpoints?.chatCompletions || {}), - enabled: true, - }, - }, - }, -}; -config.agents = { - ...(config.agents || {}), - defaults: { - ...(config.agents?.defaults || {}), - model: { - ...(config.agents?.defaults?.model || {}), - primary: process.env.OPENCLAW_OPENWEBUI_MODEL, - }, - }, -}; -fs.mkdirSync(path.dirname(configPath), { recursive: true }); -fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8"); + { path: "models.providers.openai.models", value: [] }, + { path: "gateway.controlUi.enabled", value: false }, + { path: "gateway.mode", value: "local" }, + { path: "gateway.bind", value: "lan" }, + { path: "gateway.auth.mode", value: "token" }, + { path: "gateway.auth.token", value: process.env.OPENCLAW_GATEWAY_TOKEN }, + { path: "gateway.http.endpoints.chatCompletions.enabled", value: true }, + { path: "agents.defaults.model.primary", value: process.env.OPENCLAW_OPENWEBUI_MODEL }, +]; +fs.writeFileSync(batchPath, `${JSON.stringify(entries, null, 2)}\n`, "utf8"); NODE + node "$entry" config set --batch-file "$batch_file" >/dev/null + rm -f "$batch_file" exec node "$entry" gateway --port '"$PORT"' --bind lan --allow-unconfigured > /tmp/openwebui-gateway.log 2>&1 ' diff --git a/src/docker-setup.e2e.test.ts b/src/docker-setup.e2e.test.ts index 97b08e34ce9..ed5b8bbf899 100644 --- a/src/docker-setup.e2e.test.ts +++ b/src/docker-setup.e2e.test.ts @@ -230,13 +230,7 @@ describe("scripts/docker/setup.sh", () => { "run --rm --no-deps --entrypoint node openclaw-gateway dist/index.js onboard --mode local --no-install-daemon", ); expect(log).toContain( - "run --rm --no-deps --entrypoint node openclaw-gateway dist/index.js config set gateway.mode local", - ); - expect(log).toContain( - "run --rm --no-deps --entrypoint node openclaw-gateway dist/index.js config set gateway.bind lan", - ); - expect(log).toContain( - 'run --rm --no-deps --entrypoint node openclaw-gateway dist/index.js config set gateway.controlUi.allowedOrigins ["http://localhost:18789","http://127.0.0.1:18789"] --strict-json', + 'run --rm --no-deps --entrypoint node openclaw-gateway dist/index.js config set --batch-json [{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]', ); expect(log).not.toContain("run --rm openclaw-cli onboard --mode local --no-install-daemon"); });