[Fix] OpenCode SDK server fails to start on Railway: root-owned HOME artifacts in the inference image - #129
Conversation
The runtime-inference-base stage installs and version-checks OpenCode as root with the image's HOME=/tmp, baking root-owned /tmp/.npm and /tmp/.local (OpenCode's data dir) into the layer. The hardened runtime user shares that HOME, so on hosts that run the raw image without a tmpfs over /tmp (Railway) OpenCode dies at startup with PermissionDenied opening its log, taking the LLM router, title refresh, and work-kind classification down with it. Compose deployments mask the problem behind a fresh tmpfs, which is why the acceptance gate never saw it. Remove the artifacts in the same layer, and upgrade the smoke test's candidate check from locating opencode to executing it as the container user.
|
No new code issues found. The previously flagged issue is resolved. See task
Review summaryThe fix correctly targets the root cause: the runtime user shares Sync update (
|
Review found the cleanup allowlist missed /tmp/.config, which the root-run version check also creates. Instead of maintaining an allowlist, run the whole install/check under HOME=/tmp/opencode-build and remove it, so any dotdir npm or OpenCode writes now or in future versions stays out of the shipped layer.
|
Addressed the review finding: rather than adding |
Problem
On nightly (Railway), the LLM router falls back on every request, and task title refresh / work-kind classification fail:
Root cause:
runtime-inference-base(#114) installs OpenCode and runsopencode --versionas root with the image'sHOME=/tmp. That bakes root-owned/tmp/.npmand/tmp/.local/share/opencode/into the image layer. The final stage runs as the hardened non-rootroomote-appuser (#105) with the sameHOME, which cannot write inside those root-owned directories, so the in-process OpenCode SDK server dies at startup.Why nothing caught it:
/tmp, masking the baked artifacts entirely — the skew only bites hosts that run the raw image, i.e. Railway.command -v opencode, which locates the binary without executing it.develop-f68732c7at 20:10 UTC.Fix
.docker/app/Dockerfile: remove/tmp/.npm,/tmp/.local, and/tmp/.cachein the sameRUNlayer that installs and version-checks OpenCode, so the image ships a pristine/tmpand the runtime user creates its ownHOMEstate.deploy/ci/deployment-smoke.sh: the candidate check now executesopencode --versionas the container user instead of just locating it. This verifies runtime executability (startup writes state underHOME); the comment documents that the tmpfs masks the raw-image case, which the Dockerfile layer now prevents.Testing
bash -non the smoke script. Local Docker daemon is unhealthy on this machine, so the image build is validated by this PR's Docker Build checks and, post-merge, by the (re-armed) deployment acceptance gate on the develop publish run.PermissionDenied ... opencode.log, and[LLM Router]lines should stop reportingphase="fallback"with the SDK-server-exit reason.