fix: [nomad-prep] P6 — externalize host paths in docker-compose via env vars (#795)
Replace hardcoded host-side bind-mount paths with env vars so Nomad
jobspecs can reuse the same variables at cutover:
- CLAUDE_BIN_DIR: path to claude CLI binary (resolved at init time)
- CLAUDE_CONFIG_FILE: path to .claude.json (default ${HOME}/.claude.json)
- CLAUDE_DIR: path to .claude directory (default ${HOME}/.claude)
- AGENT_SSH_DIR: path to SSH keys (default ${HOME}/.ssh)
- SOPS_AGE_DIR: path to SOPS age keys (default ${HOME}/.config/sops/age)
generators.sh now writes CLAUDE_BIN_DIR to .env instead of sed-replacing
CLAUDE_BIN_PLACEHOLDER in docker-compose.yml.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6a4ca5c3a0
commit
19f10e33e6
3 changed files with 52 additions and 34 deletions
10
.env.example
10
.env.example
|
|
@ -109,6 +109,16 @@ ANTHROPIC_BASE_URL= # [CONFIG] e.g. http://host.docker.in
|
|||
# ── Tuning ────────────────────────────────────────────────────────────────
|
||||
CLAUDE_TIMEOUT=7200 # [CONFIG] max seconds per Claude invocation
|
||||
|
||||
# ── Host paths (Nomad-portable) ────────────────────────────────────────────
|
||||
# These env vars externalize host-side bind-mount paths from docker-compose.yml.
|
||||
# At cutover, Nomad jobspecs reference the same vars — no path translation.
|
||||
# Defaults point at current paths so an empty .env override still works.
|
||||
CLAUDE_BIN_DIR=/usr/local/bin/claude # [CONFIG] host path to claude CLI binary (resolved by `disinto init`)
|
||||
CLAUDE_CONFIG_FILE=${HOME}/.claude.json # [CONFIG] host path to claude config JSON file
|
||||
CLAUDE_DIR=${HOME}/.claude # [CONFIG] host path to .claude directory (reproduce/edge)
|
||||
AGENT_SSH_DIR=${HOME}/.ssh # [CONFIG] host path to SSH keys directory
|
||||
SOPS_AGE_DIR=${HOME}/.config/sops/age # [CONFIG] host path to SOPS age key directory
|
||||
|
||||
# ── Claude Code shared OAuth state ─────────────────────────────────────────
|
||||
# Shared directory used by every factory container so Claude Code's internal
|
||||
# proper-lockfile-based OAuth refresh lock works across containers. Both
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ services:
|
|||
- agent-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
|
||||
- ${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
- ${HOME}/.ssh:/home/agent/.ssh:ro
|
||||
- ${HOME}/.config/sops/age:/home/agent/.config/sops/age:ro
|
||||
- ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro
|
||||
- ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro
|
||||
- ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro
|
||||
- ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro
|
||||
- woodpecker-data:/woodpecker-data:ro
|
||||
environment:
|
||||
- FORGE_URL=http://forgejo:3000
|
||||
|
|
@ -76,10 +76,10 @@ services:
|
|||
- agent-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
|
||||
- ${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
- ${HOME}/.ssh:/home/agent/.ssh:ro
|
||||
- ${HOME}/.config/sops/age:/home/agent/.config/sops/age:ro
|
||||
- ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro
|
||||
- ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro
|
||||
- ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro
|
||||
- ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro
|
||||
- woodpecker-data:/woodpecker-data:ro
|
||||
environment:
|
||||
- FORGE_URL=http://forgejo:3000
|
||||
|
|
@ -134,9 +134,9 @@ services:
|
|||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- agent-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- ${HOME}/.claude:/home/agent/.claude
|
||||
- /usr/local/bin/claude:/usr/local/bin/claude:ro
|
||||
- ${HOME}/.ssh:/home/agent/.ssh:ro
|
||||
- ${CLAUDE_DIR:-${HOME}/.claude}:/home/agent/.claude
|
||||
- ${CLAUDE_BIN_DIR:-/usr/local/bin/claude}:/usr/local/bin/claude:ro
|
||||
- ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
|
|
@ -150,9 +150,9 @@ services:
|
|||
- apparmor=unconfined
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /usr/local/bin/claude:/usr/local/bin/claude:ro
|
||||
- ${HOME}/.claude.json:/root/.claude.json:ro
|
||||
- ${HOME}/.claude:/root/.claude:ro
|
||||
- ${CLAUDE_BIN_DIR:-/usr/local/bin/claude}:/usr/local/bin/claude:ro
|
||||
- ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/root/.claude.json:ro
|
||||
- ${CLAUDE_DIR:-${HOME}/.claude}:/root/.claude:ro
|
||||
- disinto-logs:/opt/disinto-logs
|
||||
environment:
|
||||
- FORGE_SUPERVISOR_TOKEN=${FORGE_SUPERVISOR_TOKEN:-}
|
||||
|
|
|
|||
|
|
@ -109,9 +109,9 @@ _generate_local_model_services() {
|
|||
- agents-${service_name}-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- \${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:\${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
|
||||
- \${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
- \${HOME}/.ssh:/home/agent/.ssh:ro
|
||||
- \${CLAUDE_CONFIG_FILE:-\${HOME}/.claude.json}:/home/agent/.claude.json:ro
|
||||
- \${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro
|
||||
- \${AGENT_SSH_DIR:-\${HOME}/.ssh}:/home/agent/.ssh:ro
|
||||
environment:
|
||||
FORGE_URL: http://forgejo:3000
|
||||
FORGE_REPO: ${FORGE_REPO:-disinto-admin/disinto}
|
||||
|
|
@ -339,10 +339,10 @@ services:
|
|||
- agent-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
|
||||
- ${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
- ${HOME}/.ssh:/home/agent/.ssh:ro
|
||||
- ${HOME}/.config/sops/age:/home/agent/.config/sops/age:ro
|
||||
- ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro
|
||||
- ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro
|
||||
- ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro
|
||||
- ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro
|
||||
- woodpecker-data:/woodpecker-data:ro
|
||||
- ./projects:/home/agent/disinto/projects:ro
|
||||
- ./.env:/home/agent/disinto/.env:ro
|
||||
|
|
@ -414,10 +414,10 @@ COMPOSEEOF
|
|||
- agent-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
|
||||
- ${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
- ${HOME}/.ssh:/home/agent/.ssh:ro
|
||||
- ${HOME}/.config/sops/age:/home/agent/.config/sops/age:ro
|
||||
- ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro
|
||||
- ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro
|
||||
- ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro
|
||||
- ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro
|
||||
- woodpecker-data:/woodpecker-data:ro
|
||||
environment:
|
||||
FORGE_URL: http://forgejo:3000
|
||||
|
|
@ -516,7 +516,7 @@ LLAMAEOF
|
|||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./secrets/tunnel_key:/run/secrets/tunnel_key:ro
|
||||
- ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}
|
||||
- ${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-fsS", "http://localhost:2019/config/"]
|
||||
interval: 30s
|
||||
|
|
@ -586,7 +586,7 @@ LLAMAEOF
|
|||
memswap_limit: 512m
|
||||
volumes:
|
||||
# Mount claude binary from host (same as agents)
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
- ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro
|
||||
# Throwaway named volume for chat config (isolated from host ~/.claude)
|
||||
- chat-config:/var/chat/config
|
||||
# Chat history persistence: per-user NDJSON files on bind-mounted host volume
|
||||
|
|
@ -649,20 +649,28 @@ COMPOSEEOF
|
|||
fi
|
||||
|
||||
# Append local-model agent services if any are configured
|
||||
# (must run before CLAUDE_BIN_PLACEHOLDER substitution so the placeholder
|
||||
# in local-model services is also resolved)
|
||||
_generate_local_model_services "$compose_file"
|
||||
|
||||
# Patch the Claude CLI binary path — resolve from host PATH at init time.
|
||||
# Resolve the Claude CLI binary path and persist as CLAUDE_BIN_DIR in .env.
|
||||
# docker-compose.yml references ${CLAUDE_BIN_DIR} so the value must be set.
|
||||
local claude_bin
|
||||
claude_bin="$(command -v claude 2>/dev/null || true)"
|
||||
if [ -n "$claude_bin" ]; then
|
||||
# Resolve symlinks to get the real binary path
|
||||
claude_bin="$(readlink -f "$claude_bin")"
|
||||
sed -i "s|CLAUDE_BIN_PLACEHOLDER|${claude_bin}|g" "$compose_file"
|
||||
else
|
||||
echo "Warning: claude CLI not found in PATH — update docker-compose.yml volumes manually" >&2
|
||||
sed -i "s|CLAUDE_BIN_PLACEHOLDER|/usr/local/bin/claude|g" "$compose_file"
|
||||
echo "Warning: claude CLI not found in PATH — set CLAUDE_BIN_DIR in .env manually" >&2
|
||||
claude_bin="/usr/local/bin/claude"
|
||||
fi
|
||||
# Persist CLAUDE_BIN_DIR into .env so docker-compose can resolve it.
|
||||
local env_file="${FACTORY_ROOT}/.env"
|
||||
if [ -f "$env_file" ]; then
|
||||
if grep -q "^CLAUDE_BIN_DIR=" "$env_file" 2>/dev/null; then
|
||||
sed -i "s|^CLAUDE_BIN_DIR=.*|CLAUDE_BIN_DIR=${claude_bin}|" "$env_file"
|
||||
else
|
||||
printf 'CLAUDE_BIN_DIR=%s\n' "$claude_bin" >> "$env_file"
|
||||
fi
|
||||
else
|
||||
printf 'CLAUDE_BIN_DIR=%s\n' "$claude_bin" > "$env_file"
|
||||
fi
|
||||
|
||||
# In build mode, replace image: with build: for locally-built images
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue