diff --git a/CLAUDE.md b/CLAUDE.md index dfa0e12..0b2aaff 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -230,7 +230,7 @@ Two backends, selected by `CLAYDE_CLAUDE_BACKEND`: - Session resumption: saves `session_id` from JSON output, resumes via `--resume ` - Rate/usage limit detection: text-pattern matching on stdout/stderr - No per-token cost tracking (returns `cost_eur=0.0`) -- Requires: a dedicated Claude config dir dir-mounted from the host (`~/clayde-claude` → `/home/clayde/.claude`); use a separate `CLAUDE_CONFIG_DIR=~/clayde-claude claude login`. Mount the directory, not the `.credentials.json` file — token refresh renames the file (new inode) and a single-file mount goes stale. See docker-compose.yml / README. +- Requires: a dedicated Claude config dir dir-mounted from the host (`~/clayde-claude` → `/home/clayde/.claude`); use a separate `CLAUDE_CONFIG_DIR=~/clayde-claude claude login`. Mount the directory, not the `.credentials.json` file — token refresh renames the file (new inode) and a single-file mount goes stale. The container itself must also set `CLAUDE_CONFIG_DIR=/home/clayde/.claude`, or the CLI's top-level config file (project trust state) defaults to the unmounted `$HOME/.claude.json` and is lost on every restart. See docker-compose.yml / README. --- diff --git a/README.md b/README.md index bd7ffda..73dcbb4 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,13 @@ container as its Claude config dir. Two things matter here: that state to the container. A separate login also gives the container its own OAuth refresh-token lineage, so its token refreshes can't invalidate your host login (refresh tokens are single-use). +- **The container's `CLAUDE_CONFIG_DIR` must match the mount path + (`/home/clayde/.claude`).** This is set in `docker-compose.yml`, mirroring the + env var used for the one-time login above. Without it, the CLI falls back to + its default `$HOME/.claude.json` for top-level config (project trust state + among it) — a path that sits outside the mount and is wiped on every + container restart, surfacing as "Claude configuration file not found" on the + next run and a loss of trusted-project state after. ### 5. Start the container diff --git a/docker-compose.yml b/docker-compose.yml index e27a1b2..1d7d4d7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,16 @@ services: - "8080" environment: - CLAYDE_ENABLED=true + # Must match the CLAUDE_CONFIG_DIR used for the one-time host login + # below, so the CLI reads/writes its top-level config file inside the + # mounted (persistent) directory instead of defaulting to $HOME/.claude.json + # — a path outside the mount that is wiped on every container restart. + # Without this, the CLI errors with "Claude configuration file not + # found" on the first run after a restart, and the recreated file lacks + # prior project-trust state, so settings.local.json's permissions.allow + # entries get silently ignored until a human re-accepts the trust dialog + # — impossible for a headless scheduled/Pebble run. + - CLAUDE_CONFIG_DIR=/home/clayde/.claude volumes: - ./data:/data # Dedicated Claude config dir for the container (required when