feat(docker): add OPENCLAW_SKIP_ONBOARDING env to skip onboarding step

Add support for OPENCLAW_SKIP_ONBOARDING environment variable in
Docker setup script. When set to a truthy value (1, true, yes),
the interactive onboarding step is skipped during container setup.
Gateway defaults and control UI allowlist still run as usual.

This is useful for automated/CI deployments where interactive
onboarding is not needed.

Includes e2e tests for both enabled and disabled cases.
This commit is contained in:
coriasezeng
2026-03-27 10:58:03 +08:00
committed by sallyom
parent 5ef6e82685
commit ba6407a1ad
2 changed files with 59 additions and 15 deletions

View File

@@ -12,6 +12,8 @@ RAW_SANDBOX_SETTING="${OPENCLAW_SANDBOX:-}"
SANDBOX_ENABLED=""
DOCKER_SOCKET_PATH="${OPENCLAW_DOCKER_SOCKET:-}"
TIMEZONE="${OPENCLAW_TZ:-}"
RAW_SKIP_ONBOARDING="${OPENCLAW_SKIP_ONBOARDING:-}"
SKIP_ONBOARDING=""
fail() {
echo "ERROR: $*" >&2
@@ -232,6 +234,9 @@ fi
if is_truthy_value "$RAW_SANDBOX_SETTING"; then
SANDBOX_ENABLED="1"
fi
if is_truthy_value "$RAW_SKIP_ONBOARDING"; then
SKIP_ONBOARDING="1"
fi
OPENCLAW_CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}"
OPENCLAW_WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$HOME/.openclaw/workspace}"
@@ -295,6 +300,7 @@ export OTEL_EXPORTER_OTLP_PROTOCOL="${OTEL_EXPORTER_OTLP_PROTOCOL:-}"
export OTEL_SERVICE_NAME="${OTEL_SERVICE_NAME:-}"
export OTEL_SEMCONV_STABILITY_OPT_IN="${OTEL_SEMCONV_STABILITY_OPT_IN:-}"
export OPENCLAW_OTEL_PRELOADED="${OPENCLAW_OTEL_PRELOADED:-}"
export OPENCLAW_SKIP_ONBOARDING="$SKIP_ONBOARDING"
# Detect Docker socket GID for sandbox group_add.
DOCKER_GID=""
@@ -489,7 +495,8 @@ upsert_env "$ENV_FILE" \
OTEL_EXPORTER_OTLP_PROTOCOL \
OTEL_SERVICE_NAME \
OTEL_SEMCONV_STABILITY_OPT_IN \
OPENCLAW_OTEL_PRELOADED
OPENCLAW_OTEL_PRELOADED \
OPENCLAW_SKIP_ONBOARDING
if [[ "$IMAGE_NAME" == "openclaw:local" ]]; then
echo "==> Building Docker image: $IMAGE_NAME"
@@ -525,22 +532,26 @@ run_prestart_gateway --user root --entrypoint sh openclaw-gateway -c \
[ -d /home/node/.openclaw/workspace/.openclaw ] && chown -R node:node /home/node/.openclaw/workspace/.openclaw || true'
echo ""
echo "==> Onboarding (interactive)"
echo "Docker setup pins Gateway mode to local."
echo "Gateway runtime bind comes from OPENCLAW_GATEWAY_BIND (default: lan)."
echo "Current runtime bind: $OPENCLAW_GATEWAY_BIND"
if is_truthy_value "$OPENCLAW_DISABLE_BONJOUR"; then
echo "Bonjour/mDNS advertising: force disabled (OPENCLAW_DISABLE_BONJOUR=$OPENCLAW_DISABLE_BONJOUR)."
elif [[ -z "$OPENCLAW_DISABLE_BONJOUR" ]]; then
echo "Bonjour/mDNS advertising: auto (disabled inside the Gateway container unless explicitly enabled)."
if [[ -n "$SKIP_ONBOARDING" ]]; then
echo "==> Skipping onboarding (OPENCLAW_SKIP_ONBOARDING is set)"
else
echo "Bonjour/mDNS advertising: explicitly enabled (OPENCLAW_DISABLE_BONJOUR=$OPENCLAW_DISABLE_BONJOUR)."
echo "==> Onboarding (interactive)"
echo "Docker setup pins Gateway mode to local."
echo "Gateway runtime bind comes from OPENCLAW_GATEWAY_BIND (default: lan)."
echo "Current runtime bind: $OPENCLAW_GATEWAY_BIND"
if is_truthy_value "$OPENCLAW_DISABLE_BONJOUR"; then
echo "Bonjour/mDNS advertising: force disabled (OPENCLAW_DISABLE_BONJOUR=$OPENCLAW_DISABLE_BONJOUR)."
elif [[ -z "$OPENCLAW_DISABLE_BONJOUR" ]]; then
echo "Bonjour/mDNS advertising: auto (disabled inside the Gateway container unless explicitly enabled)."
else
echo "Bonjour/mDNS advertising: explicitly enabled (OPENCLAW_DISABLE_BONJOUR=$OPENCLAW_DISABLE_BONJOUR)."
fi
echo "Gateway token: $OPENCLAW_GATEWAY_TOKEN"
echo "Tailscale exposure: Off (use host-level tailnet/Tailscale setup separately)."
echo "Install Gateway daemon: No (managed by Docker Compose)"
echo ""
run_prestart_cli onboard --mode local --no-install-daemon
fi
echo "Gateway token: $OPENCLAW_GATEWAY_TOKEN"
echo "Tailscale exposure: Off (use host-level tailnet/Tailscale setup separately)."
echo "Install Gateway daemon: No (managed by Docker Compose)"
echo ""
run_prestart_cli onboard --mode local --no-install-daemon
echo ""
echo "==> Docker gateway defaults"

View File

@@ -520,6 +520,39 @@ describe("scripts/docker/setup.sh", () => {
expect(result.stderr).toContain("OPENCLAW_TZ must match a timezone in /usr/share/zoneinfo");
});
it("skips onboarding when OPENCLAW_SKIP_ONBOARDING is set", async () => {
const activeSandbox = requireSandbox(sandbox);
await resetDockerLog(activeSandbox);
const result = runDockerSetup(activeSandbox, {
OPENCLAW_SKIP_ONBOARDING: "1",
});
expect(result.status).toBe(0);
const log = await readDockerLog(activeSandbox);
expect(log).not.toContain("onboard");
// Gateway defaults (config set) and control UI allowlist should still run.
expect(log).toContain("config set gateway.mode local");
expect(log).toContain("config set gateway.bind lan");
const envFile = await readFile(join(activeSandbox.rootDir, ".env"), "utf8");
expect(envFile).toContain("OPENCLAW_SKIP_ONBOARDING=1");
});
it("treats OPENCLAW_SKIP_ONBOARDING=0 as disabled and runs onboarding", async () => {
const activeSandbox = requireSandbox(sandbox);
await resetDockerLog(activeSandbox);
const result = runDockerSetup(activeSandbox, {
OPENCLAW_SKIP_ONBOARDING: "0",
});
expect(result.status).toBe(0);
const log = await readDockerLog(activeSandbox);
expect(log).toContain("onboard --mode local --no-install-daemon");
const envFile = await readFile(join(activeSandbox.rootDir, ".env"), "utf8");
expect(envFile).toContain("OPENCLAW_SKIP_ONBOARDING=");
});
it("avoids associative arrays so the script remains Bash 3.2-compatible", async () => {
const script = await readFile(join(repoRoot, "scripts", "docker", "setup.sh"), "utf8");
expect(script).not.toMatch(/^\s*declare -A\b/m);