Skip to content

Fix devcontainer startup: resolve Docker context + propagate feature containerEnv - #31

Merged
devpg merged 2 commits into
mainfrom
claude/gracious-greider-861f4f
Jun 19, 2026
Merged

Fix devcontainer startup: resolve Docker context + propagate feature containerEnv#31
devpg merged 2 commits into
mainfrom
claude/gracious-greider-861f4f

Conversation

@devpg

@devpg devpg commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Two independent bugs each blocked human agent start from launching a devcontainer. Both are fixed here as separate, atomic commits.

[HUM-122] Resolve active Docker context in both engine clients (462fff4)

The Docker SDK's FromEnv only honors DOCKER_HOST and ignores the active docker CLI context, so human couldn't reach the engine out-of-the-box on colima / OrbStack / Rancher / Docker-Desktop / Podman, where the socket/pipe is exposed via a context. The failure surfaced only as the opaque starting agent container.

  • New internal/dockerhost.Resolve: a shared, cross-platform resolver mirroring the docker CLI's context precedence (explicit DOCKER_HOST/DOCKER_CONTEXT win → config.json currentContext → platform default). Handles unix sockets and Windows named pipes.
  • NewDockerClient and NewEngineDockerClient both layer the resolved host onto FromEnv via the one resolver (no divergence).
  • Docker connection failures now surface an actionable error naming the active context and attempted endpoint.
  • github.com/docker/cli promoted to a direct dependency.

[HUM-125] Propagate feature containerEnv to later installs and image (74b2eb2)

A devcontainer feature's containerEnv (FeatureMeta.ContainerEnv) was parsed but never applied, so the node feature's PATH/NVM additions never reached the features installed after it nor the committed image. claude-code then couldn't find node/npm and its install.sh failed — again surfacing only as starting agent container. (Distinct from the already-merged installsAfter ordering fix, HUM-121.)

  • InstallFeatures accumulates each feature's containerEnv, expands ${VAR} against the container's real base env, feeds it to later features' install.sh, and returns it.
  • ContainerCommit extended to bake the accumulated env into the image as sorted ENV directives; ImageBuilder.Puller made injectable for tests.
  • Diagnosability: execInContainer refactored to a shared execCapture core; the "exec failed" error now carries the command's stdout tail (where feature scripts print their fatal reason).

Testing

  • make check green (lint 0 issues, govulncheck/gitleaks clean); total coverage 81.7%. One unrelated flaky test (internal/chrome/TestMcpTranslator_SubprocessExit, untouched package, subprocess timing) failed once and passes on retry.
  • New unit tests: cross-platform context resolution (unix + npipe, DOCKER_HOST/DOCKER_CONTEXT set/unset, malformed store); containerEnv propagation to later installs; containerEnv baked into the commit; ${VAR} expansion; both engine constructors apply the resolved host.
  • End-to-end via real human agent start on colima/macOS: all four features install (incl. claude-code + treehouse/human), Image cached, Devcontainer running / Agent started, container Up. Runtime check: the cached image's ENV resolves node v22.23.0, go, npm directly.

🤖 Generated with Claude Code

devpg and others added 2 commits June 19, 2026 09:23
The Docker SDK's FromEnv only honors DOCKER_HOST and ignores the active
docker CLI context, so human could not reach the engine out-of-the-box on
colima/OrbStack/Rancher/Docker-Desktop/Podman, where the socket/pipe is
exposed via a context rather than DOCKER_HOST. The failure surfaced only as
the opaque "starting agent container".

Add internal/dockerhost.Resolve, a shared cross-platform resolver mirroring
the docker CLI context precedence (explicit DOCKER_HOST/DOCKER_CONTEXT win,
else config.json currentContext, else the platform default), handling unix
sockets and Windows named pipes. NewDockerClient and NewEngineDockerClient
both layer the resolved host onto FromEnv via the one resolver so they never
diverge, and Docker connection failures now surface an actionable error
naming the active context and attempted endpoint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A devcontainer feature's containerEnv (FeatureMeta.ContainerEnv) was parsed
but never applied, so the node feature's PATH/NVM additions never reached the
features installed after it nor the committed image. A dependent feature such
as ghcr.io/anthropics/devcontainer-features/claude-code then could not find
node/npm and its install.sh failed, surfacing only as "starting agent
container".

InstallFeatures now accumulates each feature's containerEnv, expanding ${VAR}
against the container's real base environment, feeds it to the install.sh of
later features, and returns it so buildWithFeatures bakes it into the image
via an extended ContainerCommit (sorted ENV directives). The puller is made
injectable for testing. execInContainer is refactored to a shared execCapture
core and now carries the command's stdout tail in the failure error, since
feature scripts print their fatal reason there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@devpg
devpg merged commit e6c0543 into main Jun 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant