From 17907bc2cdd38db377c64a74c91f54114d9fdac3 Mon Sep 17 00:00:00 2001 From: Zee Zheng Date: Fri, 29 May 2026 16:45:35 +0800 Subject: [PATCH] fix(clawdock): load compose override file Load `docker-compose.override.yml` when ClawDock builds its explicit Docker Compose file list, preserving standard Compose override behavior while keeping `docker-compose.extra.yml` as the final OpenClaw overlay. Update Docker docs so manual Compose users include the same override order, and keep the regression test for the generated `_clawdock_compose` arguments. Fixes #49909. Thanks @spacegeologist. Co-authored-by: zhengzuo0-ai --- docs/install/docker.md | 4 +- scripts/clawdock/README.md | 15 ++++--- scripts/clawdock/clawdock-helpers.sh | 3 ++ test/scripts/clawdock-helpers.test.ts | 64 +++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 test/scripts/clawdock-helpers.test.ts diff --git a/docs/install/docker.md b/docs/install/docker.md index 7fecbefe4e3e..47cc29a4e848 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -109,7 +109,9 @@ docker compose up -d openclaw-gateway Run `docker compose` from the repo root. If you enabled `OPENCLAW_EXTRA_MOUNTS` or `OPENCLAW_HOME_VOLUME`, the setup script writes `docker-compose.extra.yml`; -include it with `-f docker-compose.yml -f docker-compose.extra.yml`. +include it after any standard override file, for example +`-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.extra.yml` +when both override files exist. diff --git a/scripts/clawdock/README.md b/scripts/clawdock/README.md index 05ede8ed2253..109cfe0ac19b 100644 --- a/scripts/clawdock/README.md +++ b/scripts/clawdock/README.md @@ -141,13 +141,14 @@ The Docker setup uses three config files on the host. The container never stores ### Docker Files -| File | Purpose | -| -------------------------- | -------------------------------------------------------------------------- | -| `Dockerfile` | Builds the `openclaw:local` image (Node 22, pnpm, non-root `node` user) | -| `docker-compose.yml` | Defines `openclaw-gateway` and `openclaw-cli` services, bind-mounts, ports | -| `scripts/docker/setup.sh` | First-time setup — builds image, creates `.env` from `.env.example` | -| `.env.example` | Template for `/.env` with all supported vars and docs | -| `docker-compose.extra.yml` | Optional overrides — auto-loaded by ClawDock helpers if present | +| File | Purpose | +| ----------------------------- | ------------------------------------------------------------------------------ | +| `Dockerfile` | Builds the `openclaw:local` image (Node 22, pnpm, non-root `node` user) | +| `docker-compose.yml` | Defines `openclaw-gateway` and `openclaw-cli` services, bind-mounts, ports | +| `docker-compose.override.yml` | Standard Docker Compose overrides — auto-loaded by ClawDock helpers if present | +| `docker-compose.extra.yml` | Additional overrides — loaded after the standard override if present | +| `scripts/docker/setup.sh` | First-time setup — builds image, creates `.env` from `.env.example` | +| `.env.example` | Template for `/.env` with all supported vars and docs | ### Config Files diff --git a/scripts/clawdock/clawdock-helpers.sh b/scripts/clawdock/clawdock-helpers.sh index 31d77d3139bd..7c392c6569b2 100755 --- a/scripts/clawdock/clawdock-helpers.sh +++ b/scripts/clawdock/clawdock-helpers.sh @@ -151,6 +151,9 @@ _clawdock_ensure_dir() { _clawdock_compose() { _clawdock_ensure_dir || return 1 local compose_args=(-f "${CLAWDOCK_DIR}/docker-compose.yml") + if [[ -f "${CLAWDOCK_DIR}/docker-compose.override.yml" ]]; then + compose_args+=(-f "${CLAWDOCK_DIR}/docker-compose.override.yml") + fi if [[ -f "${CLAWDOCK_DIR}/docker-compose.extra.yml" ]]; then compose_args+=(-f "${CLAWDOCK_DIR}/docker-compose.extra.yml") fi diff --git a/test/scripts/clawdock-helpers.test.ts b/test/scripts/clawdock-helpers.test.ts new file mode 100644 index 000000000000..06e38fc75116 --- /dev/null +++ b/test/scripts/clawdock-helpers.test.ts @@ -0,0 +1,64 @@ +import { execFile } from "node:child_process"; +import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; +import { describe, expect, it } from "vitest"; + +const execFileAsync = promisify(execFile); +const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); + +describe("scripts/clawdock/clawdock-helpers.sh", () => { + it("loads the standard docker-compose.override.yml before ClawDock extra overrides", async () => { + const tempDir = await mkdtemp(path.join(tmpdir(), "openclaw-clawdock-")); + try { + const projectDir = path.join(tempDir, "project"); + const binDir = path.join(tempDir, "bin"); + const argsFile = path.join(tempDir, "docker-args.txt"); + await mkdir(projectDir); + await mkdir(binDir); + await writeFile(path.join(projectDir, "docker-compose.yml"), "services: {}\n"); + await writeFile(path.join(projectDir, "docker-compose.override.yml"), "services: {}\n"); + await writeFile(path.join(projectDir, "docker-compose.extra.yml"), "services: {}\n"); + await writeFile( + path.join(binDir, "docker"), + `#!/usr/bin/env bash +printf '%s\\n' "$@" > "$CLAWDOCK_DOCKER_ARGS_FILE" +`, + { mode: 0o755 }, + ); + + await execFileAsync( + "bash", + ["-c", "source scripts/clawdock/clawdock-helpers.sh; _clawdock_compose config"], + { + cwd: repoRoot, + env: { + ...process.env, + CLAWDOCK_DIR: projectDir, + CLAWDOCK_DOCKER_ARGS_FILE: argsFile, + HOME: path.join(tempDir, "home"), + PATH: `${binDir}${path.delimiter}${process.env.PATH ?? ""}`, + }, + }, + ); + + await expect(readFile(argsFile, "utf8")).resolves.toBe( + [ + "compose", + "-f", + path.join(projectDir, "docker-compose.yml"), + "-f", + path.join(projectDir, "docker-compose.override.yml"), + "-f", + path.join(projectDir, "docker-compose.extra.yml"), + "config", + "", + ].join("\n"), + ); + } finally { + await rm(tempDir, { force: true, recursive: true }); + } + }); +});