my own indieAuth provider! indiko.dunkirk.sh/docs
indieauth oauth2-server

feat: add health check for deployment

dunkirk.sh 98f4d8c9 278c6df3

verified
Changed files
+34 -15
.github
workflows
src
+22 -15
.github/workflows/deploy.yaml
··· 11 11 runs-on: ubuntu-latest 12 12 steps: 13 13 - uses: actions/checkout@v3 14 - 14 + 15 15 - name: Setup Tailscale 16 16 uses: tailscale/github-action@v3 17 17 with: ··· 19 19 oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} 20 20 tags: tag:ci 21 21 use-cache: "true" 22 - 22 + 23 23 - name: Configure SSH 24 24 run: | 25 25 mkdir -p ~/.ssh 26 26 echo "StrictHostKeyChecking no" >> ~/.ssh/config 27 - 27 + 28 28 - name: Deploy to server 29 29 run: | 30 30 ssh indiko@terebithia << 'EOF' ··· 34 34 bun install 35 35 sudo /run/current-system/sw/bin/systemctl restart indiko.service 36 36 EOF 37 - 38 - - name: Wait for service to start 39 - run: sleep 10 40 - 37 + 41 38 - name: Health check 42 39 run: | 43 - HEALTH_URL="https://indiko.dunkirk.sh/" 40 + HEALTH_URL="https://indiko.dunkirk.sh/health" 44 41 MAX_RETRIES=6 45 42 RETRY_DELAY=5 46 - 43 + 47 44 for i in $(seq 1 $MAX_RETRIES); do 48 45 echo "Health check attempt $i/$MAX_RETRIES..." 49 46 50 - HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" || echo "000") 47 + RESPONSE=$(curl -s -w "\n%{http_code}" "$HEALTH_URL" || echo "000") 48 + HTTP_CODE=$(echo "$RESPONSE" | tail -n1) 49 + BODY=$(echo "$RESPONSE" | head -n-1) 51 50 52 51 if [ "$HTTP_CODE" = "200" ]; then 53 - echo "✅ Service is healthy (HTTP $HTTP_CODE)" 54 - exit 0 52 + # Validate response contains "status":"ok" 53 + if echo "$BODY" | grep -q '"status":"ok"'; then 54 + echo "✅ Service is healthy (HTTP $HTTP_CODE)" 55 + echo "Response: $BODY" 56 + exit 0 57 + else 58 + echo "❌ Health check returned 200 but invalid body" 59 + echo "Response: $BODY" 60 + fi 61 + else 62 + echo "❌ Health check failed with HTTP $HTTP_CODE" 63 + echo "Response: $BODY" 55 64 fi 56 65 57 - echo "❌ Health check failed with HTTP $HTTP_CODE" 58 - 59 66 if [ $i -lt $MAX_RETRIES ]; then 60 67 echo "Retrying in ${RETRY_DELAY}s..." 61 68 sleep $RETRY_DELAY 62 69 fi 63 70 done 64 - 71 + 65 72 echo "❌ Health check failed after $MAX_RETRIES attempts" 66 73 exit 1
+12
src/index.ts
··· 95 95 port: env.PORT ? Number.parseInt(env.PORT, 10) : 3000, 96 96 routes: { 97 97 "/": indexHTML, 98 + "/health": () => { 99 + try { 100 + // Verify database is accessible 101 + db.query("SELECT 1").get(); 102 + return Response.json({ status: "ok", timestamp: new Date().toISOString() }); 103 + } catch { 104 + return Response.json( 105 + { status: "error", error: "Database unavailable" }, 106 + { status: 503 } 107 + ); 108 + } 109 + }, 98 110 "/admin": adminHTML, 99 111 "/admin/invites": adminInvitesHTML, 100 112 "/admin/apps": () => Response.redirect("/admin/clients", 302),