From e45c31caaac6caa7a769a025ef2ea6fce9a81a31 Mon Sep 17 00:00:00 2001 From: Jeffrey Smith Date: Thu, 2 Apr 2026 09:09:06 +0000 Subject: [PATCH] Fix CI DinD networking: host network mode + curl timeout The previous fix (container IP resolution) still failed because the CI runner and compose containers are on separate Docker networks. - Add docker-compose.ci.yml override with network_mode: host so the container shares the runner's network stack directly - Add --connect-timeout 2 to curl in wait-for-healthy.sh so it fails fast instead of hanging indefinitely on unreachable hosts - Cap health check at 30s (server boots in 5-10s) Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitea/workflows/ci.yaml | 22 ++++++---------------- ci/wait-for-healthy.sh | 2 +- docker-compose.ci.yml | 7 +++++++ 3 files changed, 14 insertions(+), 17 deletions(-) create mode 100644 docker-compose.ci.yml diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index b66804e..1b16634 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -385,42 +385,32 @@ jobs: uses: actions/checkout@v4 - name: Build Docker image - run: docker compose build + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml build - - name: Boot server (SQLite) + - name: Boot server (SQLite, host networking) env: BUNDLED_PACKAGES: '*' ARMATURE_ADMIN_USERNAME: admin ARMATURE_ADMIN_PASSWORD: admin ARMATURE_ADMIN_EMAIL: admin@test.local - run: docker compose up -d - - # In DinD (Gitea runner pods), port-mapped localhost doesn't reach - # the compose container. Resolve the container IP on its Docker - # network so curl / Playwright can connect directly on port 80. - - name: Resolve container IP - id: container-ip - run: | - IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' armature) - echo "SERVER_URL=http://${IP}:80" >> "$GITHUB_OUTPUT" - echo "Resolved container IP → ${IP}" + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml up -d - name: Wait for healthy - run: ./ci/wait-for-healthy.sh ${{ steps.container-ip.outputs.SERVER_URL }} + run: ./ci/wait-for-healthy.sh http://localhost:80 30 - name: Install Playwright run: npx playwright install --with-deps chromium - name: Run surface tests env: - SERVER_URL: ${{ steps.container-ip.outputs.SERVER_URL }} + SERVER_URL: http://localhost:80 ADMIN_USER: admin ADMIN_PASS: admin run: ./ci/run-surface-tests.sh - name: Teardown if: always() - run: docker compose down -v + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml down -v # ── Stage 2: Build, Database, Deploy ───────── # diff --git a/ci/wait-for-healthy.sh b/ci/wait-for-healthy.sh index 18008b8..c903aaf 100755 --- a/ci/wait-for-healthy.sh +++ b/ci/wait-for-healthy.sh @@ -10,7 +10,7 @@ MAX_RETRIES="${2:-60}" echo "Waiting for ${HOST} to be healthy..." for i in $(seq 1 "$MAX_RETRIES"); do - if curl -sf "${HOST}/api/v1/auth/login" -o /dev/null 2>/dev/null; then + if curl -sf --connect-timeout 2 "${HOST}/api/v1/auth/login" -o /dev/null 2>/dev/null; then echo "Server healthy after ${i}s" exit 0 fi diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml new file mode 100644 index 0000000..343e7e6 --- /dev/null +++ b/docker-compose.ci.yml @@ -0,0 +1,7 @@ +# CI override — uses host networking so the container is reachable +# from the Gitea runner pod without cross-network routing. +# +# Usage: docker compose -f docker-compose.yml -f docker-compose.ci.yml up -d +services: + armature: + network_mode: host