Containers: integration fixes before first flip — CMD + credentials mount path #27

Closed
opened 2026-04-17 21:17:54 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As an operator flipping an agent from host mode to container mode for
the first time, I want the Dockerfile + just containers-rebuild +
runAgent to actually work end-to-end, so I can pilot container mode
without discovering two blocker bugs one at a time.

Follow-up to #18 / #19 / #20 (PRs #23 / #22 / #21). The three stories
shipped separately and were never exercised in a live end-to-end path.
Reading the landed code surfaces two integration bugs that would each
stop the first container from running.

Acceptance criteria

Bug 1 — Dockerfile has no long-running CMD

  • Dockerfile ends with a directive that keeps the container alive
    (e.g. CMD ["sleep", "infinity"]). Without it, docker run -d … <image> creates the container and immediately exits — docker exec
    fails, just containers-up has nothing to start.

Bug 2 — credentials mount path mismatch between justfile and src/container.ts

  • just containers-rebuild must mount the host credentials file at
    the exact in-container path runAgent expects, which is
    CONTAINER_CREDENTIALS_TARGET from src/container.ts
    /home/claude/.config/claude-code/.credentials.json. Today the
    recipe mounts to /root/.claude/.credentials.json:ro, which the
    claude user cannot read (different user, different path) and the
    Claude CLI isn't looking at anyway.
  • The recipe reads the host-side credentials path from agents.json
    (agents.<name>.container.credentials_host_path) with the same
    fallback container.ts:defaultHostCredentialsPath() uses, so both
    sides of the mount agree with zero config on the default path.

Tests

  • src/container.test.ts gains a test for the recipe/container-path
    agreement: either assert the constant name, or pull the --volume
    string from the rendered recipe and parse it.
  • A smoke recipe (or documented just command) that proves the
    round-trip: just containers-rebuild reviewer
    docker exec claude-hooks-reviewer bun /opt/claude-code/cli.js --version
    must succeed.

Docs

  • README.md (or docs/runner-setup.md) section on first-time
    pilot: provision per-agent creds file, docker buildx build
    locally, just containers-rebuild reviewer, add "container": {"enabled": true} to config/agents.json, restart service.

Out of scope

  • Release-runner docker access + post-publish runtime smoke tests
    (tracked in #26).
  • Rolling out container mode to every agent (boss, dev, reviewer).
    Focus here is on fixing the plumbing so ONE agent can be piloted.

References

  • Parent tracking issue: #17
  • Integration-test gap surfaced during container-mode dry-run attempt.
  • Related: #26 (release runner + runtime image smoke tests).

Dependencies

  • Blocked by: none open (#18, #19, #20 all landed)
  • Blocks: the first in-production use of container mode
  • Branch off: main
  • Full graph: #17
## User story As an **operator** flipping an agent from host mode to container mode for the first time, I want the Dockerfile + `just containers-rebuild` + `runAgent` to actually work end-to-end, so I can pilot container mode without discovering two blocker bugs one at a time. Follow-up to #18 / #19 / #20 (PRs #23 / #22 / #21). The three stories shipped separately and were never exercised in a live end-to-end path. Reading the landed code surfaces two integration bugs that would each stop the first container from running. ## Acceptance criteria ### Bug 1 — Dockerfile has no long-running `CMD` - [ ] `Dockerfile` ends with a directive that keeps the container alive (e.g. `CMD ["sleep", "infinity"]`). Without it, `docker run -d … <image>` creates the container and immediately exits — `docker exec` fails, `just containers-up` has nothing to start. ### Bug 2 — credentials mount path mismatch between `justfile` and `src/container.ts` - [ ] `just containers-rebuild` must mount the host credentials file at the *exact* in-container path `runAgent` expects, which is `CONTAINER_CREDENTIALS_TARGET` from `src/container.ts` — `/home/claude/.config/claude-code/.credentials.json`. Today the recipe mounts to `/root/.claude/.credentials.json:ro`, which the `claude` user cannot read (different user, different path) and the Claude CLI isn't looking at anyway. - [ ] The recipe reads the host-side credentials path from `agents.json` (`agents.<name>.container.credentials_host_path`) with the same fallback `container.ts:defaultHostCredentialsPath()` uses, so both sides of the mount agree with zero config on the default path. ### Tests - [ ] `src/container.test.ts` gains a test for the recipe/container-path agreement: either assert the constant name, or pull the `--volume` string from the rendered recipe and parse it. - [ ] A smoke recipe (or documented `just` command) that proves the round-trip: `just containers-rebuild reviewer` → `docker exec claude-hooks-reviewer bun /opt/claude-code/cli.js --version` must succeed. ### Docs - [ ] `README.md` (or `docs/runner-setup.md`) section on first-time pilot: provision per-agent creds file, `docker buildx build` locally, `just containers-rebuild reviewer`, add `"container": {"enabled": true}` to `config/agents.json`, restart service. ## Out of scope - Release-runner docker access + post-publish runtime smoke tests (tracked in #26). - Rolling out container mode to every agent (boss, dev, reviewer). Focus here is on fixing the plumbing so ONE agent can be piloted. ## References - Parent tracking issue: #17 - Integration-test gap surfaced during container-mode dry-run attempt. - Related: #26 (release runner + runtime image smoke tests). ## Dependencies - **Blocked by:** none open (#18, #19, #20 all landed) - **Blocks:** the first in-production use of container mode - **Branch off:** `main` - **Full graph:** #17
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#27
No description provided.