Files
windwiderstand/.gitea/workflows/deploy.yml
T
Peter Meier d03afe780e
Deploy / verify (push) Failing after 44s
Deploy / deploy (push) Has been skipped
feat(contact): add Cloudflare Turnstile captcha
Client renders explicit Turnstile widget (flexible, light theme) when
PUBLIC_TURNSTILE_SITE_KEY is set. Token sent with form payload, server
verifies via siteverify endpoint before forwarding to CMS. Skipped
entirely when no site key configured (dev fallback). New i18n keys:
contact_captcha_pending, contact_server_error_captcha. Deploy workflow
forwards PUBLIC_TURNSTILE_SITE_KEY + TURNSTILE_SECRET.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:37:09 +02:00

110 lines
4.0 KiB
YAML

# Deploy windwiderstand SvelteKit auf Contabo bei Push auf main.
#
# Setup auf dem Server (einmalig):
# mkdir -p /opt/windwiderstand
# DNS: windwiderstand.de + www.windwiderstand.de A → 167.86.74.105
#
# Gitea Secrets (Repo → Settings → Secrets):
# SSH_DEPLOY_KEY ~/.ssh/contabo_rsa (privat)
# REGISTRY_USER Gitea-Username
# REGISTRY_TOKEN Gitea Access Token (Scope: package)
# PUBLIC_CMS_URL https://cms.pm86.de
# PUBLIC_SITE_URL https://windwiderstand.de
# PUBLIC_SITE_NAME Windwiderstand
# ORIGIN https://windwiderstand.de
# REVALIDATE_TOKEN openssl rand -hex 32
# PUBLIC_UMAMI_WEBSITE_ID (optional, sonst leer)
name: Deploy
on:
push:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: Install deps
run: npm ci
- name: Generate icons subset
run: npm run generate:icons
- name: SvelteKit sync
run: npx svelte-kit sync
- name: Typecheck (svelte-check)
run: npx svelte-check --threshold error
- name: Typecheck (tsc)
run: npx tsc --noEmit
deploy:
needs: verify
runs-on: ubuntu-latest
env:
DEPLOY_HOST: root@167.86.74.105
DEPLOY_DIR: /opt/windwiderstand
IMAGE: git.pm86.de/admin/windwiderstand:latest
steps:
- uses: actions/checkout@v4
- name: Build and push image
run: |
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.pm86.de -u ${{ secrets.REGISTRY_USER }} --password-stdin
docker build -t $IMAGE .
docker push $IMAGE
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_DEPLOY_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
cat > ~/.ssh/config <<EOF
Host vserver
HostName 167.86.74.105
User root
IdentityFile ~/.ssh/deploy_key
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
EOF
- name: Sync compose.yml
run: |
ssh vserver "mkdir -p $DEPLOY_DIR"
scp ./docker-compose.prod.yml vserver:$DEPLOY_DIR/docker-compose.yml
- name: Write .env from secrets
run: |
ssh vserver "cat > $DEPLOY_DIR/.env" <<ENVEOF
PORT=3001
NODE_ENV=production
PUBLIC_CMS_URL=${{ secrets.PUBLIC_CMS_URL }}
PUBLIC_SITE_URL=${{ secrets.PUBLIC_SITE_URL }}
PUBLIC_SITE_NAME=${{ secrets.PUBLIC_SITE_NAME }}
ORIGIN=${{ secrets.ORIGIN }}
REVALIDATE_TOKEN=${{ secrets.REVALIDATE_TOKEN }}
IMAGE_CACHE_DIR=/data/image-cache
PUBLIC_UMAMI_SCRIPT_URL=https://cloud.umami.is/script.js
PUBLIC_UMAMI_WEBSITE_ID=${{ secrets.PUBLIC_UMAMI_WEBSITE_ID }}
PUBLIC_TURNSTILE_SITE_KEY=${{ secrets.PUBLIC_TURNSTILE_SITE_KEY }}
TURNSTILE_SECRET=${{ secrets.TURNSTILE_SECRET }}
ENVEOF
- name: Pull and restart container
run: |
ssh vserver "echo '${{ secrets.REGISTRY_TOKEN }}' | docker login git.pm86.de -u ${{ secrets.REGISTRY_USER }} --password-stdin"
ssh vserver "docker pull $IMAGE"
ssh vserver "cd $DEPLOY_DIR && docker compose up -d --force-recreate && docker image prune -f"
- name: Caddy site block + reload
run: |
ssh vserver 'grep -qE "^windwiderstand\.de[[:space:],{]" /opt/caddy/extra-config/Caddyfile || printf "\nwindwiderstand.de {\n reverse_proxy windwiderstand:3001\n}\n\nwww.windwiderstand.de {\n redir https://windwiderstand.de{uri} permanent\n}\n" >> /opt/caddy/extra-config/Caddyfile'
ssh vserver "docker exec caddy caddy reload --config /extra-config/Caddyfile"
- name: Cleanup
if: always()
run: rm -f ~/.ssh/deploy_key