Files
2026-07-21 13:44:23 +02:00

114 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plan: Ny Caddy-lösning med Bunny.net (Docker + dynamisk IP + cert-hantering)
## Mål
- Klona nuvarande `caddy`-repo till ett nytt repo för den nya lösningen och fortsätta arbetet där.
- Behålla fungerande reverse proxy-installation (nuvarande Caddyfile-routing).
- Köra Caddy i Docker med en **custom build** som innehåller Bunny.net-stöd.
- Låta Caddy uppdatera DNS mot Bunny.net när publik IP ändras (dynamisk IP).
- Säkerställa att Lets Encrypt-certifikat fortsatt hanteras/uppdateras av Caddy.
- Lägga till ett cron-script som reagerar på IP-byte (t.ex. efter router-omstart) och triggar cert-/TLS-verifieringsflöde.
## Inventerat nuläge (från befintligt repo)
- `compose.yml` använder `caddy:2.6.4`, portar `80/443`, volymer för `/etc/caddy`, `/data`, `/config`, samt externt Docker-nätverk `proxy`.
- Aktiv `Caddyfile` har snippets `(auth)` och `(common)` och ett antal domäner, bl.a.:
- `test.gynther.se`, `nzbget.gynther.se`, `prowlarr.gynther.se`, `radarr.gynther.se`, `sonarr.gynther.se`, `jellyfin.gynther.se`, `qbittorrent.gynther.se`, `wetty.gynther.se`, `gitea.gynther.se`, `import.gynther.se`, `recept.gynther.se`.
- `recept.gynther.se` har ordningskänsliga `handle`-regler där import- och API-rutter måste ligga före catch-all.
- Nuläget saknar Bunny.net DNS-modul, dynamisk DNS-app och cron-automation för IP-byte.
## Teknisk målarkitektur
1. **Nytt repo (arbetsrepo)**
- Klona nuvarande repo till nytt katalognamn (t.ex. `caddy-bunny`) och koppla till nytt remote-repo.
- Arbeta endast i nya repot.
2. **Custom Caddy-image i Docker**
- Bygg Caddy med `xcaddy` och moduler:
- `github.com/caddy-dns/bunny` (DNS provider för ACME DNS-01)
- `github.com/mholt/caddy-dynamicdns` (uppdaterar A/AAAA vid IP-byte)
- Köra denna image via `compose.yml` (`build:` eller pinned custom image-tag).
3. **Caddyfile med globala DNS-/ACME-inställningar**
- Införa global options-block med Bunny API-nyckel via env-variabel.
- Aktivera ACME DNS challenge med Bunny (`acme_dns bunny {env.BUNNY_API_KEY}`).
- Behålla befintliga site-block/routing oförändrade i funktion.
4. **Dynamisk DNS i Caddy**
- Konfigurera `dynamic_dns` globalt för zonen (ex. `gynther.se`) och relevanta hostnames.
- Check-interval + TTL sätts konservativt för att undvika onödiga DNS-skrivningar.
- IPv4 prioriteras; IPv6 endast om verifierat fungerande i miljön.
5. **Cron-script för IP-byte och cert/TLS-flöde**
- Script körs periodiskt (t.ex. var 5:e minut) och:
1. Läser aktuell publik IP.
2. Jämför mot senast känd IP (state-fil).
3. Vid förändring: logga händelse, trigga Caddy reload/validering, och köra HTTPS-smoke-test mot definierade domäner.
- Viktigt: Certifikat är domänbundna (inte IP-bundna). Scriptet ska därför **inte** forcera ny cert-utgivning vid varje IP-byte (risk för Lets Encrypt rate limits), utan säkerställa att DNS och TLS fungerar direkt efter ändringen.
## Implementationssteg
### Fas 1: Repo-etablering
- Skapa nytt repo från nuvarande kodbas:
- Lokal klon till ny katalog.
- Ny remote (Gitea) för nya caddy-repot.
- Verifiera att arbetskopian är ren och att endast nya repot används framåt.
### Fas 2: Containerisering med custom build
- Lägg till `Dockerfile` för Caddy custom build med båda modulerna.
- Uppdatera `compose.yml`:
- Använd custom image/build.
- Behåll portar, nätverk `proxy`, data/config-volymer.
- Lägg till env-hantering för `BUNNY_API_KEY` och kontaktmail.
### Fas 3: Caddy-konfiguration
- Uppdatera `conf/Caddyfile`:
- Lägg till globalt options-block för ACME DNS + dynamic DNS.
- Mappa zon + hostnames för dynamic DNS.
- Behåll samtliga befintliga reverse proxy-regler och ordning.
- Lägga in validering (`caddy validate` via container) som del av drift-rutin.
### Fas 4: Cron + script
- Lägg till script (t.ex. `scripts/ddns-cert-sync.sh`) med:
- lock-fil (undvika parallellkörning),
- robust felhantering och loggning,
- IP-change detection + Caddy reload + TLS-smoke-test.
- Lägg till crontab-exempel (t.ex. `cron/caddy-ddns-cert.cron`) och installationsinstruktion.
### Fas 5: Test och verifiering
- Funktionstesta i ordning:
1. Container build/start.
2. `caddy validate` + `caddy list-modules` (verifiera bunny + dynamic_dns).
3. Simulerad IP-förändring och bekräfta DNS-record update i Bunny.
4. HTTPS-test av representativa domäner.
5. Verifiera att befintliga tjänster bakom reverse proxy fungerar oförändrat.
### Fas 6: Dokumentation och överlämning
- Uppdatera `README.md` med:
- setup, env-variabler, cron-installation,
- felsökning (DNS update, ACME challenge, loggar),
- rollback-steg.
## Konfigurationsförslag (målvärden)
- `dynamic_dns.check_interval`: 5m
- DNS TTL: 300s eller 600s
- Cron: var 5:e minut
- State-fil för senaste IP: persistent volym/sökväg på host
- Loggning: tidsstämplad, roterbar via systemets logrotate/journal
## Risker och motåtgärder
- **Lets Encrypt rate limits**: undvik forcerad re-issue vid IP-byte; kör verifiering istället.
- **DNS propagation delay**: script ska vänta/retrya innan TLS-smoke-test markeras failed.
- **Felaktig zon/record mapping**: explicit lista över zone + hostnames i config, samt initial torrkörning.
- **Modulkompatibilitet/versioner**: pinna Caddy- och plugin-versioner i build för reproducerbarhet.
## Acceptanskriterier
- Nytt repo finns och används som arbetsrepo.
- Caddy kör i Docker med custom image och laddade moduler för Bunny + dynamic DNS.
- Samtliga befintliga hostnames/routingregler fungerar som idag.
- DNS A/AAAA uppdateras automatiskt när publik IP ändras.
- Cron-script upptäcker IP-byte och triggar reload + TLS-verifiering utan att orsaka onödig cert-utgivning.
- Dokumentation räcker för drift utan muntlig kunskapsöverföring.
## Beslutspunkter före implementation
- Namn/URL för nya caddy-repot i Gitea.
- Exakt vilka hostnames som ska dynamiskt uppdateras (alla i Caddyfile eller delmängd).
- Om IPv6 ska ingå från start.
- Önskad TTL (300 eller 600 sekunder).