From ff25e5a084784a39481c8c8864a26fe939c4a392 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 10 Apr 2026 06:49:09 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20bug:=20dispatcher=20should=20use=20docke?= =?UTF-8?q?r=20run,=20not=20docker=20compose=20run=20=E2=80=94=20compose?= =?UTF-8?q?=20context=20unavailable=20in=20edge=20container=20(#529)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- docker/edge/dispatcher.sh | 55 ++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/docker/edge/dispatcher.sh b/docker/edge/dispatcher.sh index cd10ff2..b375108 100755 --- a/docker/edge/dispatcher.sh +++ b/docker/edge/dispatcher.sh @@ -9,7 +9,7 @@ # 3. Verify TOML arrived via merged PR with admin merger (Forgejo API) # 4. Validate TOML using vault-env.sh validator # 5. Decrypt .env.vault.enc and extract only declared secrets -# 6. Launch: docker run --rm disinto-agents:latest +# 6. Launch: docker run --rm disinto/agents:latest # 7. Write .result.json with exit code, timestamp, logs summary # # Part of #76. @@ -408,16 +408,42 @@ launch_runner() { local secrets_array secrets_array="${VAULT_ACTION_SECRETS:-}" - # Build docker compose run command (delegates to compose runner service) - # The runner service definition handles image, network, volumes, and base env. - # The dispatcher only adds declared secrets and the ops repo mount. - # - # The edge container has docker-compose.yml mounted at /opt/docker-compose.yml. - # --project-directory tells docker compose to resolve relative paths (volumes, - # env_file) against the HOST project root so the Docker daemon finds them. - local compose_file="${COMPOSE_FILE:-/opt/docker-compose.yml}" - local project_dir="${HOST_PROJECT_DIR:-.}" - local -a cmd=(docker compose -f "$compose_file" --project-directory "$project_dir" run --rm) + # Build docker run command (self-contained, no compose context needed). + # The edge container has the Docker socket but not the host's compose project, + # so docker compose run would fail with exit 125. docker run is self-contained: + # the dispatcher knows the image, network, env vars, and entrypoint. + local -a cmd=(docker run --rm + --name "vault-runner-${action_id}" + --network host + --entrypoint bash + -e DISINTO_CONTAINER=1 + -e "FORGE_URL=${FORGE_URL}" + -e "FORGE_TOKEN=${FORGE_TOKEN}" + -e "FORGE_REPO=${FORGE_REPO:-disinto-admin/disinto}" + -e "FORGE_OPS_REPO=${FORGE_OPS_REPO:-}" + -e "PRIMARY_BRANCH=${PRIMARY_BRANCH:-main}" + ) + + # Pass through optional env vars if set + if [ -n "${ANTHROPIC_API_KEY:-}" ]; then + cmd+=(-e "ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}") + fi + if [ -n "${CLAUDE_MODEL:-}" ]; then + cmd+=(-e "CLAUDE_MODEL=${CLAUDE_MODEL}") + fi + + # Mount docker socket, claude binary, and claude config + cmd+=(-v /var/run/docker.sock:/var/run/docker.sock) + if [ -f /usr/local/bin/claude ]; then + cmd+=(-v /usr/local/bin/claude:/usr/local/bin/claude:ro) + fi + local runtime_home="${HOME:-/home/debian}" + if [ -d "${runtime_home}/.claude" ]; then + cmd+=(-v "${runtime_home}/.claude:/home/agent/.claude") + fi + if [ -f "${runtime_home}/.claude.json" ]; then + cmd+=(-v "${runtime_home}/.claude.json:/home/agent/.claude.json:ro") + fi # Add environment variables for secrets (if any declared) if [ -n "$secrets_array" ]; then @@ -441,7 +467,6 @@ launch_runner() { local mounts_array mounts_array="${VAULT_ACTION_MOUNTS:-}" if [ -n "$mounts_array" ]; then - local runtime_home="${HOME:-/home/debian}" for mount_alias in $mounts_array; do mount_alias=$(echo "$mount_alias" | xargs) [ -n "$mount_alias" ] || continue @@ -467,10 +492,10 @@ launch_runner() { # Mount the ops repo so the runner entrypoint can read the action TOML cmd+=(-v "${OPS_REPO_ROOT}:/home/agent/ops:ro") - # Service name and action-id argument - cmd+=(runner "$action_id") + # Image and entrypoint arguments: runner entrypoint + action-id + cmd+=(disinto/agents:latest /home/agent/disinto/docker/runner/entrypoint-runner.sh "$action_id") - log "Running: docker compose run --rm runner ${action_id} (secrets: ${secrets_array:-none}, mounts: ${mounts_array:-none})" + log "Running: docker run --rm vault-runner-${action_id} (secrets: ${secrets_array:-none}, mounts: ${mounts_array:-none})" # Create temp file for logs local log_file