Skip to content

fix(docker): pin container-side workspace and config dirs in compose#77446

Merged
vincentkoc merged 1 commit intoopenclaw:mainfrom
lonexreb:fix/77436-docker-workspace-host-leak
May 4, 2026
Merged

fix(docker): pin container-side workspace and config dirs in compose#77446
vincentkoc merged 1 commit intoopenclaw:mainfrom
lonexreb:fix/77436-docker-workspace-host-leak

Conversation

@lonexreb
Copy link
Copy Markdown
Contributor

@lonexreb lonexreb commented May 4, 2026

Summary

Fixes #77436 — fresh `./scripts/docker/setup.sh` Docker setups on macOS started failing after 04.29 with the first agent reply dying on:

```
EACCES: permission denied, mkdir '/Users'
```

The reporter confirmed the same flow worked on 2026.04.29 and reproduces consistently from 2026.05.02 onward.

Root cause

`scripts/docker/setup.sh` defaults `OPENCLAW_WORKSPACE_DIR` and `OPENCLAW_CONFIG_DIR` from the host `$HOME` (so on macOS this is `/Users//.openclaw/...`), then writes both into repo `.env` so Compose can use them as bind-mount sources for `/home/node/.openclaw` and `/home/node/.openclaw/workspace`.

Both services then loaded the same `.env` via `env_file:` without re-overriding those two variables in the container's `environment:` block. Inside Linux Docker the env vars carried host-style paths, and once a runtime/wizard resolution path persisted that into `agents.defaults.workspace`, the next `ensureAgentWorkspace` on the reply path called `fs.mkdir` against `/Users/...` — which fails because Linux Docker has no `/Users` and the container user cannot create top-level dirs anyway.

The clawsweeper review on the issue traced the chain end-to-end (`scripts/docker/setup.sh:241`, `docker-compose.yml:5`, `src/wizard/setup.ts:567`, `src/auto-reply/reply/get-reply.ts:237`) and recommended fixing the boundary between host bind-mount source and container runtime path.

Fix

Override `OPENCLAW_CONFIG_DIR` and `OPENCLAW_WORKSPACE_DIR` in the `environment:` block on both `openclaw-gateway` and `openclaw-cli` services so they always resolve to the canonical container paths:

```yaml
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
```

Compose's `environment:` takes precedence over `env_file:`, so:

  • The bind-mount source on `volumes:` still uses the host-side value substituted from `.env` (correct — that's what we want for the Docker mount).
  • The in-container env always sees the container-side path (correct — that's what runtime code resolves against).

This separates host-mount-source from container-runtime-path the way the existing `HOME=/home/node` override already does for `HOME`. It's defensive against any current or future code path that resolves a workspace from `OPENCLAW_WORKSPACE_DIR`.

Verification

  • `pnpm test src/docker-setup.e2e.test.ts` — 27 passed (1 new sync test locks the contract on both services).
  • `pnpm exec oxfmt --check --threads=1 docker-compose.yml src/docker-setup.e2e.test.ts CHANGELOG.md` — clean.

I did not run the live Docker/Ollama Cloud flow from the reporter (no Docker on this dev machine), matching the read-only constraint clawsweeper noted. The unit-level evidence locks the wire contract: both services emit container-side paths even when `.env` carries host-side ones.

Closes

Fixes #77436

@openclaw-barnacle openclaw-barnacle Bot added docker Docker and sandbox tooling size: XS labels May 4, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 4, 2026

Codex review: needs maintainer review before merge.

Summary
The branch adds container-local OPENCLAW_CONFIG_DIR and OPENCLAW_WORKSPACE_DIR overrides to both Compose services, a Docker setup sync test, and a changelog fix entry.

Reproducibility: yes. by source inspection for the env leak: setup writes host-side paths to .env, Compose imports them into both containers on current main, and the reply path creates the configured workspace. I did not live-reproduce the Docker flow or independently prove the exact /Users persistence step beyond the linked report and PR discussion.

Next step before merge
No repair job is needed; the open PR is a narrow implementation candidate that needs normal maintainer review and checks rather than an automated replacement.

Security
Cleared: The diff pins existing local container path variables, adds a regression assertion, and updates the changelog without adding dependencies, secrets, permissions, downloads, or new execution paths.

Review details

Best possible solution:

Land the focused Compose boundary fix after normal PR checks so #77436 closes through the merge.

Do we have a high-confidence way to reproduce the issue?

Yes by source inspection for the env leak: setup writes host-side paths to .env, Compose imports them into both containers on current main, and the reply path creates the configured workspace. I did not live-reproduce the Docker flow or independently prove the exact /Users persistence step beyond the linked report and PR discussion.

Is this the best way to solve the issue?

Yes; service-level container path overrides are the narrowest maintainable fix because they keep host paths available for bind-mount interpolation while preventing those values from becoming the container runtime env.

What I checked:

  • Current main imports host .env into both services: Both openclaw-gateway and openclaw-cli load .env; current main sets HOME but does not override OPENCLAW_CONFIG_DIR or OPENCLAW_WORKSPACE_DIR in the container environment. (docker-compose.yml:5, 103cdd9d96f8)
  • Setup persists host-side mount paths: scripts/docker/setup.sh defaults config/workspace paths from host $HOME, exports them, and writes them into repo .env, which Compose also uses for the bind-mount sources. (scripts/docker/setup.sh:241, 103cdd9d96f8)
  • Reply path creates the resolved workspace: The reply path resolves the agent workspace and calls ensureAgentWorkspace; that helper resolves the path and immediately runs recursive fs.mkdir, matching the reported failure mode when a host-style /Users/... workspace leaks into runtime config. (src/auto-reply/reply/get-reply.ts:237, 103cdd9d96f8)
  • Compose precedence supports the fix: Docker's official Compose environment precedence page says explicit environment values take precedence over env_file values, so service-level container paths should override .env inside the container without changing Compose interpolation for bind mounts.
  • PR diff matches the intended boundary fix: The patch adds the two container-side path overrides under both service environment blocks, adds a sync test requiring both services to contain those values, and adds a user-facing changelog entry. (docker-compose.yml:8, 18347cf45100)
  • PR discussion records targeted verification: The PR body and follow-up comment report pnpm test src/docker-setup.e2e.test.ts passing 27 tests after rebase, including the new sync test; I did not rerun tests in this read-only review. (src/docker-setup.e2e.test.ts:623, 18347cf45100)

Likely related people:

  • vincentkoc: Recent Docker setup/docs/test stabilization and image work touched the same setup, Compose, and Docker documentation surface. (role: recent Docker setup maintainer; confidence: medium; commits: a7c5a0425988, 601d1ccd2499, 3f3f66a5f75b; files: scripts/docker/setup.sh, docker-compose.yml, docs/install/docker.md)
  • Peter Steinberger: Historical Docker onboarding and mount-validation hardening commits are on the same setup flow and Compose boundary. (role: historical Docker setup owner; confidence: medium; commits: 35976da7a078, dfef943f0a18, 7255c20ddcc3; files: scripts/docker/setup.sh, docker-compose.yml, docs/install/docker.md)
  • jamtujest: Authored the opt-in Docker sandbox support that touched the same Compose, setup script, docs, and Docker setup test boundary. (role: adjacent Docker Compose contributor; confidence: medium; commits: cb491dfde5cb; files: docker-compose.yml, scripts/docker/setup.sh, docs/install/docker.md)

Remaining risk / open question:

  • I did not run the live Docker/Ollama flow or local tests in this read-only pass; validation relies on source inspection, the PR discussion, and the added contract test.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 103cdd9d96f8.

@lonexreb lonexreb force-pushed the fix/77436-docker-workspace-host-leak branch from 52b41b2 to 18347cf Compare May 4, 2026 17:58
@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 4, 2026

Rebased onto current origin/main to address the merge-conflict status. No code change; clawsweeper review confirmed no correctness findings, just the dirty-merge state. Targeted tests still green: 27 passing in src/docker-setup.e2e.test.ts (including the new sync test that locks the contract on both services).

scripts/docker/setup.sh writes the host-side OPENCLAW_WORKSPACE_DIR and
OPENCLAW_CONFIG_DIR (e.g. /Users/<you>/.openclaw/...) into .env so Compose
can use them as bind-mount sources. Both gateway and CLI services then
imported the same .env via env_file, so inside the Linux container the env
vars carried host-style paths. After 04.29 this regressed: the first agent
reply died with 'EACCES: permission denied, mkdir /Users' when the wizard
or runtime resolved a workspace from those env values.

Override OPENCLAW_CONFIG_DIR and OPENCLAW_WORKSPACE_DIR in the environment:
block on both services so the container always sees /home/node/.openclaw
and /home/node/.openclaw/workspace, regardless of what .env carries for
Compose substitution. Compose's environment: takes precedence over
env_file:, so the bind-mount source still uses the host path while the
in-container env stays correct.

Add a sync test alongside the existing docker-compose contract tests that
locks the override on both services so this contract cannot regress
silently.

Fixes openclaw#77436.
@vincentkoc vincentkoc force-pushed the fix/77436-docker-workspace-host-leak branch from 18347cf to 5db7774 Compare May 4, 2026 22:57
@vincentkoc vincentkoc self-assigned this May 4, 2026
@vincentkoc vincentkoc merged commit 34f805a into openclaw:main May 4, 2026
93 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docker Docker and sandbox tooling size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Docker-setup.sh, does not work after 04.29 version

2 participants