# CODEX_NOTES.md – Deploy & Betrieb (Copy/Paste für Codex) ## Ziel Statische Landingpage soll automatisch bei jedem Push auf `main` nach `go.vanityontour.de` deployed werden. ## Repo-Struktur - `index.html` - `assets/css/style.css` - `assets/img/*` - `robots.txt` - `.forgejo/workflows/deploy.yml` ## Wo die Seite liegt Seit Juli 2026 auf dem **Hostinger-VPS** (72.62.158.29), nicht mehr auf dem Hetzner-Server. Ausgeliefert von einem nginx-Container aus dem Shlink-Stack: - Zielverzeichnis auf dem Host: `/docker/shlink/landingpage` - Container `shlink-landingpage` mountet es read-only - Davor Traefik mit Let's-Encrypt-Zertifikat `go.vanityontour.de` teilt sich die Domain mit Shlink. Traefik entscheidet nach Pfad, die Landingpage hat die höhere Priorität: | Pfad | Ziel | | --- | --- | | `/`, `/assets/*`, `/robots.txt`, `/favicon.*`, `/sitemap.xml`, `/CNAME` | diese Seite | | alles andere | Shlink-Kurzlink | **Wichtig:** Eine neue Datei im Repo-Root wird nur ausgeliefert, wenn ihr Pfad in der Traefik-Regel steht. Sonst landet der Aufruf bei Shlink und wird auf `/` umgeleitet. Die Regel steht in der `docker-compose.yml` des Shlink-Projekts. ## Deployment-Mechanik Forgejo Actions. Der Runner `vps-runner` läuft als Container `act_runner` auf demselben VPS: 1. Job startet in einem `node:20-alpine`-Container 2. `/docker/shlink/landingpage` wird als `/target` in den Job gemountet 3. `rsync -a --delete` vom Checkout nach `/target` 4. Smoke-Test gegen die Live-URL Kein SSH, kein Deploy-Key, keine Secrets nötig – der Runner steht bereits auf dem Zielhost. Das Mounten ist in `/docker/act_runner/config.yaml` unter `container.valid_volumes` freigegeben. ## Kein GitHub Actions mehr Der frühere Workflow `.github/workflows/deploy.yml` deployte per rsync auf den Hetzner-Server und ist entfernt. `.github/workflows/` darf hier nicht wieder angelegt werden – Forgejo Actions wertet dieses Verzeichnis ebenfalls aus und würde den Job doppelt starten. ## DNS - `go.vanityontour.de` → A-Record auf `72.62.158.29` - **Kein AAAA-Record.** Ein alter AAAA auf den Hetzner-Server hat die Let's-Encrypt-Validierung blockiert, weil IPv6 Vorrang hat. - Zertifikat kommt von Traefik, nicht mehr von CloudPanel ## Hinweise - OpenGraph Bild: ersetze `assets/img/og.jpg` (1200x630) - Links in `index.html` aktualisieren (App Store, GitHub Repo URLs, Social URLs) - Runner-Logs: `ssh hostingervps 'docker logs act_runner'`