From 0137a5005b3ff0eaee4a0d34c514641b5a773371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rling?= Date: Tue, 19 May 2026 21:21:36 +0200 Subject: [PATCH] feat: add production deploy pipeline and nginx config for bilhej.se MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a manually-triggered deploy workflow that builds production Docker images and starts the stack on the srvr.nu server. - : workflow_dispatch with version input, writes production .env from Forgejo secrets, builds and starts the docker-compose.prod.yml stack, runs health checks via temporary curl containers on the bilhej_default Docker network, tags the git commit. - : nginx server block for bilhej.se. Handles HTTP→HTTPS redirect, SSL termination with Let's Encrypt certs, and proxies all traffic to the bilhej-frontend-prod container on the Docker 'web' network. The frontend container handles /api/ proxying to the backend internally. To deploy: 1. Add production secrets to Forgejo (Settings → Actions → Secrets) 2. Trigger deploy from Actions → Deploy to Production 3. Run certbot for bilhej.se SSL (one-time setup) 4. Add docker/bilhej.nginx.conf to srvr.nu nginx container 5. Point bilhej.se DNS A record to srvr.nu IP --- .forgejo/workflows/deploy.yml | 87 +++++++++++++++++++++++++++++++++++ docker/bilhej.nginx.conf | 42 +++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 .forgejo/workflows/deploy.yml create mode 100644 docker/bilhej.nginx.conf diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml new file mode 100644 index 0000000..98107ca --- /dev/null +++ b/.forgejo/workflows/deploy.yml @@ -0,0 +1,87 @@ +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 ${{ github.event.inputs.version }} + git push origin ${{ github.event.inputs.version }} + + - name: Write production .env + run: | + cat > .env << 'EOF' + 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 }} + EOF + + - name: Build and start production stack + run: | + docker compose -f docker-compose.prod.yml up --build -d + + - name: Wait for services + run: sleep 20 + + - name: Health check — backend API + run: | + for i in 1 2 3 4 5; do + if docker run --rm --network bilhej_default curlimages/curl:8.5.0 \ + -sf http://bilhej-backend-prod:8080/api/vehicles/ZZZ999; then + echo "Backend is healthy" + exit 0 + fi + echo "Attempt $i failed, retrying in 5s..." + sleep 5 + done + echo "Backend health check failed" + exit 1 + + - name: Health check — frontend + run: | + for i in 1 2 3 4 5; do + if docker run --rm --network bilhej_default curlimages/curl:8.5.0 \ + -sf http://bilhej-frontend-prod/ | grep -qi "bilhej\|Bilhej\|BilHej"; then + echo "Frontend is serving" + exit 0 + fi + echo "Attempt $i failed, retrying in 5s..." + sleep 5 + done + echo "Frontend health check failed" + exit 1 + + - name: Print deploy status + run: | + echo "" + echo "═══════════════════════════════════════════════════" + echo " Deployed ${{ github.event.inputs.version }} to production" + echo "═══════════════════════════════════════════════════" + echo "" + docker compose -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 "" diff --git a/docker/bilhej.nginx.conf b/docker/bilhej.nginx.conf new file mode 100644 index 0000000..2cbcdae --- /dev/null +++ b/docker/bilhej.nginx.conf @@ -0,0 +1,42 @@ +# Nginx server block for bilhej.se +# Add this to /etc/nginx/conf.d/ inside the nginx container on srvr.nu + +server { + listen 80; + server_name bilhej.se www.bilhej.se; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + server_name bilhej.se www.bilhej.se; + + ssl_certificate /etc/letsencrypt/live/bilhej.se/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/bilhej.se/privkey.pem; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + + add_header Strict-Transport-Security "max-age=63072000" always; + + location / { + proxy_pass http://bilhej-frontend-prod:80; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_buffering off; + } + + # The frontend container proxies /api/ to the backend internally. + # No need for a separate /api/ block here. +}