vcard4reseller/deploy/terraform/cloud-init-caddy.yaml.tftpl
Thomas Peterson 79e996ab03 Deployment: Caddy-Edge (TLS + On-Demand für Custom-Domains) + Hetzner DNS
- Caddy ersetzt den Hetzner-LB: terminiert TLS (Portal-Domain automatisch) und
  load-balanced per reverse_proxy über die App-Nodes. Für Custom-Domains (§11)
  On-Demand-TLS, autorisiert über GET /internal/tls-allowed.
- TlsCheckController + DomainRepository::findVerifiedByHostname: erlaubt Zertifikate
  nur für Portal-Domain oder verifizierte Domains (Schutz vor Cert-Flooding).
- Terraform: hcloud_load_balancer entfernt, Caddy-Server + Firewall (80/443) +
  cloud-init-caddy (Caddyfile templated mit Upstreams/Domain/ACME).
- Optional Hetzner DNS via API (manage_dns): A-Record Portal + Wildcard → Caddy.
- nginx.prod: /internal zu Symfony geroutet; APP_PORTAL_DOMAIN-Env.

Validiert: Caddyfile (caddy validate), Terraform (validate), /internal/tls-allowed (200/403/400).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:13:29 +02:00

41 lines
1.1 KiB
Plaintext

#cloud-config
package_update: true
write_files:
- path: /opt/caddy/Caddyfile
permissions: '0644'
content: |
{
email ${acme_email}
on_demand_tls {
# Caddy fragt die App, ob es für die Domain ein Zertifikat ausstellen darf
ask http://${ask_upstream}/internal/tls-allowed
}
}
# Portal (Haupt-Domain): automatisches TLS, Load-Balancing über die App-Nodes
${domain}, www.${domain} {
reverse_proxy ${app_upstreams} {
lb_policy round_robin
}
}
# Custom-Domains der Firmenkunden: On-Demand-TLS (nur erlaubte Hosts)
https:// {
tls {
on_demand
}
reverse_proxy ${app_upstreams} {
lb_policy round_robin
}
}
runcmd:
- command -v docker >/dev/null 2>&1 || curl -fsSL https://get.docker.com | sh
- mkdir -p /opt/caddy/data /opt/caddy/config
- |
docker run -d --name caddy --restart unless-stopped \
-p 80:80 -p 443:443 -p 443:443/udp \
-v /opt/caddy/Caddyfile:/etc/caddy/Caddyfile:ro \
-v /opt/caddy/data:/data \
-v /opt/caddy/config:/config \
caddy:2