# 08 — Deploy Pipeline Update (Prod) ## Context - **File:** `.gitea/workflows/deploy-prod.yml` - Same changes as test pipeline (`test-env-setup/07-deploy-pipeline-update.md`), adapted for prod paths and prod runner. ## Step 1 — Remove manual cert scp lines from `Initialize Servers` ```yaml # DELETE from "Initialize Servers" step: scp -P 23 ${{ vars.STORAGEBOX_USER }}@${{ vars.STORAGEBOX_USER }}.your-storagebox.de:prod/app/iklim.co/ssl/STAR.iklim.co.full.crt ./STAR.iklim.co.full.crt scp -P 23 ${{ vars.STORAGEBOX_USER }}@${{ vars.STORAGEBOX_USER }}.your-storagebox.de:prod/app/iklim.co/ssl/STAR.iklim.co_key.txt ./STAR.iklim.co_key.txt ``` Also remove from `Prepare Init Files`: ```yaml # DELETE or make conditional: sudo cp STAR.iklim.co.full.crt STAR.iklim.co_key.txt /opt/iklimco/ssl/ ``` ## Step 2 — Add `Prepare SWAG Directories` step Insert **before** `Deploy Swarm Stack`: ```yaml - name: Prepare SWAG Directories run: | set -a; . ./.env; . ./.env.secrets.shared; set +a sudo mkdir -p /opt/iklimco/swag/dns-conf envsubst < swag/dns-conf/godaddy.ini.tpl | sudo tee /opt/iklimco/swag/dns-conf/godaddy.ini > /dev/null sudo chmod 600 /opt/iklimco/swag/dns-conf/godaddy.ini echo "✅ godaddy.ini written" sudo mkdir -p /opt/iklimco/swag/proxy-confs /opt/iklimco/swag/site-confs export RESTRICTED_IP_1="78.187.87.109" export RESTRICTED_IP_2="95.70.151.248" for tpl in swag/proxy-confs/*.conf.tpl; do out="/opt/iklimco/swag/proxy-confs/$(basename "${tpl%.tpl}")" envsubst < "$tpl" | sudo tee "$out" > /dev/null echo "✅ $out" done sudo cp swag/site-confs/default.conf /opt/iklimco/swag/site-confs/default.conf echo "✅ SWAG directories ready" working-directory: /workspace/iklim.co ``` > `.env` is sourced first so `API_SUBDOMAIN=api.iklim.co` (prod values) are used. > Ensure these vars are in `prod/secrets/iklim.co/.env.prod` on storagebox. ## Step 3 — Add `Bootstrap SWAG Certificate` step Insert **after** `Deploy Swarm Stack`: ```yaml - name: Bootstrap SWAG Certificate run: | echo "Waiting for SWAG container to start..." SWAG_CTR="" for i in $(seq 1 24); do SWAG_CTR=$(docker ps -q -f name=iklimco_swag 2>/dev/null | head -1) [ -n "$SWAG_CTR" ] && break sleep 10 done if [ -z "$SWAG_CTR" ]; then echo "❌ SWAG container did not start" exit 1 fi CERT_PATH="/config/etc/letsencrypt/live/iklim.co/fullchain.pem" echo "Waiting for cert (up to 10 min)..." for i in $(seq 1 20); do if docker exec "$SWAG_CTR" test -f "$CERT_PATH" 2>/dev/null; then echo "✅ Cert obtained" break fi echo " attempt $i/20 — waiting 30s..." sleep 30 done if ! docker exec "$SWAG_CTR" test -f "$CERT_PATH" 2>/dev/null; then echo "❌ SWAG did not obtain cert. Logs:" docker service logs iklimco_swag --tail 50 exit 1 fi sudo mkdir -p /opt/iklimco/ssl docker exec "$SWAG_CTR" cat "$CERT_PATH" | \ sudo tee /opt/iklimco/ssl/STAR.iklim.co.full.crt > /dev/null docker exec "$SWAG_CTR" cat "/config/etc/letsencrypt/live/iklim.co/privkey.pem" | \ sudo tee /opt/iklimco/ssl/STAR.iklim.co_key.txt > /dev/null echo "✅ Cert bootstrapped to /opt/iklimco/ssl/" working-directory: /workspace/iklim.co ``` ## Step 4 — Ensure subdomain env vars are in prod `.env` Add to `prod/secrets/iklim.co/.env.prod` on storagebox: ```bash API_SUBDOMAIN=api.iklim.co APIGW_SUBDOMAIN=apigw.iklim.co RABBITMQ_SUBDOMAIN=rabbitmq.iklim.co GRAFANA_SUBDOMAIN=grafana.iklim.co ``` ## Step 5 — Final step order for prod pipeline 1. Checkout Branch 2. Prepare Folders 3. Set up SSH Key 4. Install Required Tools 5. Fetch Service Secret Files 6. Initialize Servers ← cert scp lines removed 7. Upload Updated Secrets to Storagebox 8. Provision Vault AppRole IDs and Docker Secrets 9. Upload Updated Env to Storagebox 10. Prepare Init Files ← cert copy lines removed 11. Initialize Docker Swarm 12. Stop Docker Compose Services 13. Docker Login to Harbor 14. **Prepare SWAG Directories** ← NEW 15. Deploy Swarm Stack 16. **Bootstrap SWAG Certificate** ← NEW 17. Review Environment