Skip to main content

agent_home_mounts

Function agent_home_mounts 

Source
fn agent_home_mounts(
    container_name: &str,
    spec: &ContainerMountSpec,
) -> Vec<Mount>
Expand description

The mounts that make up the agent’s home dir inside the container.

The per-agent named volume stays mounted at CONTAINER_CLAUDE_DIR exactly as before, and a bound account contributes ONE extra mount: its .credentials.json, bind-mounted as a single file on top of that volume.

Binding the account’s whole config dir over …/.claude would be the more obvious shape, and it does NOT work — both failures verified live on 2026-09-02 against ghcr.io/agentmuxai/agent-claude:latest:

  1. That dir’s projects entry is a symlink into the shared identities tree, which does not resolve in-container (ls → “No such file or directory”).
  2. Shadowing it with a nested volume at …/.claude/projects SILENTLY does not mount — Docker will not mount over a path that is a symlink inside a bind mount. mount shows only the parent 9p bind, and the CLI is left writing session state through the broken link. Chowning does not help; there is nothing there to chown.

Keeping the volume and binding just the credential file avoids both, and preserves the existing ownership story: the volume is initialised from the image, so projects/sessions stay writable by uid 1000. Verified end to end — a container agent using this shape completed a real turn against the bound account ("result":"AUTH_OK", is_error: false).

Known limitation — HOST UID PARITY. A bind preserves the host file’s owner and mode (.credentials.json is typically 0600), while the image always execs as agent, uid 1000. On a host whose AgentMux user is not uid 1000, the container cannot read the token and authentication stays broken there.

That is deliberately NOT worked around here. It is the container design’s pre-existing, documented assumption — “agent non-root user (UID 1000) … Host filesystem UID parity” (SPEC_CONTAINER_PANE_SUPPORT_2026_06_11.md § “What claw’s containers provide”; the Dockerfile renames node:22-slim’s uid-1000 user for exactly this) — and the /workspace bind below has the identical problem: at uid != 1000 the agent cannot write its own workspace either. Special-casing credentials would fix one symptom of that assumption and leave the other, while adding a second provisioning path to maintain. The real fix is to exec as the host uid/gid, which is an architectural change affecting every mount, and belongs in its own PR.

Known limitation: a single-file bind follows the inode. If the CLI ever replaces .credentials.json by atomic rename rather than writing in place, a refreshed token would land on the host but not be seen by the running container until it is recreated. Reads — the case that was totally broken — are unaffected.