fix(docker): pin container-side workspace and config dirs in compose#77446
Conversation
|
Codex review: needs maintainer review before merge. Summary Reproducibility: yes. by source inspection for the env leak: setup writes host-side paths to Next step before merge Security Review detailsBest 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 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:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 103cdd9d96f8. |
52b41b2 to
18347cf
Compare
|
Rebased onto current |
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.
18347cf to
5db7774
Compare
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:
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
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