bilhej/.forgejo/workflows/deploy.yml
Joakim Mörling db56fc58de
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 1m52s
CI / E2E browser tests (push) Successful in 46s
Add deploy failure diagnostics and safer backend health check.
Production deploy failed with no backend logs before rollback. Print
backend and postgres logs on failure, wait longer for JVM startup, and
probe /api/payment/swish-info instead of vehicle lookup (no external scrape).

- Document proof-first troubleshooting in README
- No volume reset workflow; fix only after reading job logs
2026-05-21 16:39:13 +02:00

129 lines
5.8 KiB
YAML

name: Deploy to Production
on:
workflow_dispatch:
inputs:
version:
description: 'Version tag (e.g., v0.1.0)'
required: true
default: 'v0.1.0'
jobs:
deploy:
name: Build and deploy
runs-on: ubuntu-latest
steps:
- name: Checkout repository
run: |
git init
git remote add origin https://x-access-token:${FORGEJO_TOKEN}@srvr.nu/git/jocke/bilhej.git
git fetch --depth 1 origin ${GITHUB_SHA}
git checkout FETCH_HEAD
- name: Tag version
run: |
git tag -d ${{ github.event.inputs.version }} 2>/dev/null || true
git push origin --delete ${{ github.event.inputs.version }} 2>/dev/null || true
git tag ${{ github.event.inputs.version }}
git push origin ${{ github.event.inputs.version }}
- name: Write production .env
env:
POSTGRES_DB: ${{ secrets.POSTGRES_DB }}
POSTGRES_USER: ${{ secrets.POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }}
STRIPE_PRICE_ID: ${{ secrets.STRIPE_PRICE_ID }}
SWISH_NUMBER: ${{ secrets.SWISH_NUMBER }}
ADMIN_EMAIL: ${{ secrets.ADMIN_EMAIL }}
ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }}
run: |
# Docker Compose treats $ as variable interpolation in .env files.
# Escape literal dollar signs (e.g. in passwords) as $$.
escape() { printf '%s' "$1" | sed 's/\$/$$/g'; }
{
printf 'POSTGRES_DB=%s\n' "$(escape "$POSTGRES_DB")"
printf 'POSTGRES_USER=%s\n' "$(escape "$POSTGRES_USER")"
printf 'POSTGRES_PASSWORD=%s\n' "$(escape "$POSTGRES_PASSWORD")"
printf 'JWT_SECRET=%s\n' "$(escape "$JWT_SECRET")"
printf 'STRIPE_SECRET_KEY=%s\n' "$(escape "$STRIPE_SECRET_KEY")"
printf 'STRIPE_WEBHOOK_SECRET=%s\n' "$(escape "$STRIPE_WEBHOOK_SECRET")"
printf 'STRIPE_PRICE_ID=%s\n' "$(escape "$STRIPE_PRICE_ID")"
printf 'SWISH_NUMBER=%s\n' "$(escape "$SWISH_NUMBER")"
printf 'ADMIN_EMAIL=%s\n' "$(escape "$ADMIN_EMAIL")"
printf 'ADMIN_PASSWORD=%s\n' "$(escape "$ADMIN_PASSWORD")"
} > .env
- name: Build and start production stack
run: |
docker compose -p bilhej-prod -f docker-compose.prod.yml down
docker compose -p bilhej-prod -f docker-compose.prod.yml up --build -d
- name: Health checks with rollback
run: |
echo "Waiting for services to start..."
sleep 30
BACKEND_OK=false
for i in 1 2 3 4 5 6 7 8 9 10; do
if docker run --rm --network bilhej-prod_default curlimages/curl:8.5.0 \
-sf http://bilhej-backend-prod:8080/api/payment/swish-info > /dev/null; then
echo "Backend is healthy"
BACKEND_OK=true
break
fi
echo "Backend check attempt $i failed, retrying in 5s..."
sleep 5
done
FRONTEND_OK=false
for i in 1 2 3 4 5; do
if docker run --rm --network bilhej-prod_default curlimages/curl:8.5.0 \
-s http://bilhej-frontend-prod/ | grep -qi "bilhej\|Bilhej\|BilHej"; then
echo "Frontend is serving"
FRONTEND_OK=true
break
fi
echo "Frontend check attempt $i failed, retrying in 5s..."
sleep 5
done
if [ "$BACKEND_OK" != "true" ] || [ "$FRONTEND_OK" != "true" ]; then
echo ""
echo "═══════════════════════════════════════════════════"
echo " HEALTH CHECK FAILED — DIAGNOSTICS"
echo "═══════════════════════════════════════════════════"
echo ""
docker compose -p bilhej-prod -f docker-compose.prod.yml ps
echo ""
echo "--- Backend logs ---"
docker logs bilhej-backend-prod 2>&1 | tail -80 || true
echo ""
echo "--- Postgres logs ---"
docker logs bilhej-postgres-prod 2>&1 | tail -30 || true
echo ""
echo "═══════════════════════════════════════════════════"
echo " ROLLING BACK DEPLOYMENT"
echo "═══════════════════════════════════════════════════"
echo ""
docker compose -p bilhej-prod -f docker-compose.prod.yml down
echo ""
echo "Rolled back. Containers stopped. DB volume preserved."
echo "Read Backend logs above to find the root cause before redeploying."
exit 1
fi
- name: Print deploy status
run: |
echo ""
echo "═══════════════════════════════════════════════════"
echo " Deployed ${{ github.event.inputs.version }} to production"
echo "═══════════════════════════════════════════════════"
echo ""
docker compose -p bilhej-prod -f docker-compose.prod.yml ps
echo ""
echo "Containers running. Update nginx config on srvr.nu"
echo "to point bilhej.se to the frontend container."
echo ""