fix(docker): HOME=/tmp in --docker sandbox to fix EROFS for tools needing writable $HOME - #18
Merged
Merged
Conversation
…needing writable $HOME The hardened --docker sandbox runs the container with a read-only root filesystem plus only /tmp as a writable tmpfs. Any tool invoked inside (e.g. opencode via the node-red-agents agent node) that writes config/state under $HOME (e.g. $HOME/.local) failed with EROFS, since the container's default HOME sits on the read-only rootfs. Sets HOME=/tmp unconditionally in buildRunArgs() so $HOME always resolves to the writable tmpfs, across all --docker modes (default image, derived image, custom Dockerfile). Fixes #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issues fixed
Fixes #17
Summary
--docker's hardened sandbox (src/docker-run.js) runs the container with a--read-onlyroot filesystem plus only/tmpmounted as a writable tmpfs. Any tool invoked inside the container that writes config/state under$HOME(e.g.opencode, invoked via theagentnode from@tbrandenburg/node-red-agents) failed withEROFS: read-only file system, mkdir '.../.local', since the container's defaultHOME(/root,/home/node, etc., depending on base image) sits on the read-only rootfs.This sets
-e HOME=/tmpunconditionally inbuildRunArgs(), so$HOMEalways resolves onto the writable tmpfs, across all three--dockermodes (default sandbox image, derived image from an arbitrary base, and custom Dockerfile).Research summary (preceding this change)
A dedicated research pass validated the fix approach before implementation:
HOME=/tmpalone (no XDG_* vars) is sufficient —opencodederives all XDG-style paths (.cache,.config,.local/share,.local/state) from$HOMEwhen no XDG var is explicitly set, so a single env var fixes every one of them at once. Setting XDG vars individually is strictly more fragile (each one only covers one subpath; missing any one reintroduces the bug for that path).HOME(used duringRUN npm install -g ...indefaultDockerfile()/derivedDockerfile()) is entirely separate from this runtimedocker runenv var — zero interaction,src/docker-image.jsuntouched.npm_config_cache=/tmp/.npm-cacheenv var (different subpath under the same tmpfs);--tmpfs /tmpis world-writable by default.@tbrandenburg/node-red-agents'sagentnode has noHOME/XDG handling of its own — it purely inheritsprocess.env, confirming the fix belongs innode-red-cli'sdocker-run.js.Validation commands run
make ci(format + lint + test + audit) from the fix branch: 116/116 tests pass (including real Docker integration tests against the local daemon), lint clean, 0 npm audit vulnerabilities.E2E coverage
Real end-to-end verification using an inline
link in -> agent (opencode, direct runtime) -> link out (return)flow, run viabin/node-red-clifrom this branch (fix applied):--user-dir --node-modules @tbrandenburg/node-red-agents):payload: "pong",agentExecution.status: "completed".--docker ghcr.io/tbrandenburg/agentic-workflow-dev-env:latest:payload: "pong",agentExecution.status: "completed", exitCode 0 — noEROFS, confirming the exact reproduction from --docker: hardened read-only rootfs breaks tools needing writable $HOME (e.g. opencode agent node) #17 is now fixed.(Before this fix, the
--dockerrun failed withEROFS: read-only file system, mkdir '/root/.local'/'/home/node/.local'.)Risks / follow-ups
--dockerwithout--node-modulesstill blocks all outbound network by design (--network none) — any agent/tool needing internet access, likeopencodecalling its API, requires--node-modulesto be passed too, as already documented behavior unrelated to this fix.)