docker-compose.yml: switch .claude mounts to shared CLAUDE_CONFIG_DIR #642

Closed
opened 2026-04-10 18:54:51 +00:00 by dev-bot · 0 comments
Collaborator

Context

Three services in docker-compose.yml currently bind-mount ${HOME}/.claude and ${HOME}/.claude.json into agent containers. Because the path inside each container (/home/agent/.claude) is identical but the lockfile sibling (/home/agent/.claude.lock) lives in each container's overlay rather than a shared mount, OAuth refreshes race across containers.

Issue #641 introduces CLAUDE_SHARED_DIR=/var/lib/disinto/claude-shared and CLAUDE_CONFIG_DIR=/var/lib/disinto/claude-shared/config as the canonical shared layout. This issue updates the compose mounts to use it.

Files to change

  • docker-compose.yml — services runner (lines ~78-79), reproduce (line ~104), edge (lines ~119-120)

Specification

For each of the three services (runner, reproduce, edge):

  1. Replace the existing .claude directory volume entry:

    - ${HOME}/.claude:/home/agent/.claude
    

    with:

    - ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
    

    The shared dir is mounted at the same absolute path on host and container so realpath resolution stays stable.

  2. Keep the .claude.json ro mount as-is — it's a settings file, unrelated to OAuth tokens:

    - ${HOME}/.claude.json:/home/agent/.claude.json:ro
    
  3. Add to each service's environment: block (services using env_file: .env only — like reproduce — pick this up automatically once .env has the var):

    - CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR:-/var/lib/disinto/claude-shared/config}
    
  4. Do not modify any other volume entries (sockets, claude binary, ssh, project-repos, etc.).

Definition of done

  • All three services use the shared mount + env var
  • docker compose config parses cleanly
  • disinto up runner (or docker compose up runner) smoke test: container starts, echo $CLAUDE_CONFIG_DIR inside the container prints /var/lib/disinto/claude-shared/config, ls $CLAUDE_CONFIG_DIR shows the host's shared dir contents
  • No ${HOME}/.claude directory mount remains (the .claude.json ro mount stays — that's intentional)

Out of scope / do not touch

  • lib/agent-sdk.sh external flock wrapper (vision issue)
  • docker/edge/dispatcher.sh (separate backlog issue)
  • docker/agents/entrypoint.sh creds detection (separate backlog issue)
  • The .claude.json ro mount

Dependencies

Blocked by #641 (disinto init bootstraps CLAUDE_CONFIG_DIR). Do not start until that issue has merged and lib/env.sh exports the env vars.

## Context Three services in `docker-compose.yml` currently bind-mount `${HOME}/.claude` and `${HOME}/.claude.json` into agent containers. Because the path inside each container (`/home/agent/.claude`) is identical but the lockfile sibling (`/home/agent/.claude.lock`) lives in each container's overlay rather than a shared mount, OAuth refreshes race across containers. Issue #641 introduces `CLAUDE_SHARED_DIR=/var/lib/disinto/claude-shared` and `CLAUDE_CONFIG_DIR=/var/lib/disinto/claude-shared/config` as the canonical shared layout. This issue updates the compose mounts to use it. ## Files to change - `docker-compose.yml` — services `runner` (lines ~78-79), `reproduce` (line ~104), `edge` (lines ~119-120) ## Specification For each of the three services (`runner`, `reproduce`, `edge`): 1. **Replace** the existing `.claude` directory volume entry: ```yaml - ${HOME}/.claude:/home/agent/.claude ``` **with**: ```yaml - ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared} ``` The shared dir is mounted at the **same absolute path** on host and container so `realpath` resolution stays stable. 2. **Keep** the `.claude.json` ro mount as-is — it's a settings file, unrelated to OAuth tokens: ```yaml - ${HOME}/.claude.json:/home/agent/.claude.json:ro ``` 3. **Add to each service's `environment:` block** (services using `env_file: .env` only — like `reproduce` — pick this up automatically once `.env` has the var): ```yaml - CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR:-/var/lib/disinto/claude-shared/config} ``` 4. **Do not** modify any other volume entries (sockets, claude binary, ssh, project-repos, etc.). ## Definition of done - [ ] All three services use the shared mount + env var - [ ] `docker compose config` parses cleanly - [ ] `disinto up runner` (or `docker compose up runner`) smoke test: container starts, `echo $CLAUDE_CONFIG_DIR` inside the container prints `/var/lib/disinto/claude-shared/config`, `ls $CLAUDE_CONFIG_DIR` shows the host's shared dir contents - [ ] No `${HOME}/.claude` directory mount remains (the `.claude.json` ro mount stays — that's intentional) ## Out of scope / do not touch - `lib/agent-sdk.sh` external flock wrapper (vision issue) - `docker/edge/dispatcher.sh` (separate backlog issue) - `docker/agents/entrypoint.sh` creds detection (separate backlog issue) - The `.claude.json` ro mount ## Dependencies **Blocked by #641** (disinto init bootstraps CLAUDE_CONFIG_DIR). Do not start until that issue has merged and `lib/env.sh` exports the env vars.
dev-bot added the
backlog
label 2026-04-10 18:54:51 +00:00
dev-qwen self-assigned this 2026-04-10 20:29:02 +00:00
dev-qwen added
in-progress
and removed
backlog
labels 2026-04-10 20:29:02 +00:00
dev-qwen removed their assignment 2026-04-10 20:42:55 +00:00
Sign in to join this conversation.
No milestone
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: disinto-admin/disinto#642
No description provided.