# Watermaps auf Hetzner Cloud Diese OpenTofu-Konfiguration erstellt einen einzelnen Ubuntu-24.04-Server mit fester IPv4-Adresse, vorgeschalteter Hetzner-Firewall und einem persistenten ext4-Volume für Routingdaten, Geofabrik-Rohdaten und die PostGIS-Datenbank mit Häfen, Schleusen, Brücken und Kontaktdaten. Kartenkacheln, DNS-Einträge und konkrete Anwendungsversionen sind bewusst nicht Teil dieses Infrastrukturmoduls. Die Anwendung wird anschließend als commitgenaues Container-Image aus der Gitea Registry deployt. ## Konfiguration Die lokale Datei `terraform.tfvars` wird aus der versionierten Vorlage angelegt und durch die lokale `.gitignore` ausgeschlossen: ```sh cp terraform.tfvars.example terraform.tfvars ``` Vor dem ersten Plan müssen dort mindestens folgende Werte ersetzt werden: - `hcloud_token`: Read/Write-API-Token des richtigen Hetzner-Cloud-Projekts - `ssh_public_key`: vollständiger Inhalt des öffentlichen SSH-Schlüssels - `admin_cidrs`: öffentliche Administrator-IP mit `/32` beziehungsweise ein bewusst gewähltes Netz `terraform.tfvars.example` bleibt als geheimnisfreie Vorlage versioniert. Da `terraform.tfvars` den Token im Klartext enthält, sollte sie nur für den lokalen Benutzer lesbar sein: ```sh chmod 600 terraform.tfvars ``` Auch `terraform.tfstate` bleibt lokal und wird nicht nach Git oder auf den Anwendungsserver übertragen. Nach dem ersten Apply sollte die State-Datei verschlüsselt gesichert werden, weil OpenTofu sie für spätere Änderungen an denselben Ressourcen benötigt. ## Infrastruktur erzeugen ```sh cd infra/opentofu tofu init tofu fmt -check tofu validate tofu plan -out=watermaps.tfplan tofu apply watermaps.tfplan ``` Die feste IPv4-Adresse und den erforderlichen manuellen DNS-Eintrag zeigt OpenTofu anschließend an: ```sh tofu output server_ipv4 tofu output dns_a_record tofu output ssh_command ``` Der A-Record `watermaps.incoso.eu` kann direkt nach dem Apply auf `server_ipv4` gesetzt werden. Das eigentliche SSL-Livegehen erfolgt erst durch das separate Deployment-Skript, nachdem DNS propagiert ist und die Routingdaten bereitstehen. ## Auf dem Server Cloud-init installiert Docker einschließlich Compose v2, `curl`, `jq` und `rsync`. Der Benutzer `deploy` erhält Zugriff per SSH und auf Docker. Es wird kein Git-Repository auf den Server geklont. Das persistente Volume wird nach dem Anhängen unter `/srv/watermaps-data` gemountet und enthält die vom Produktions-Stack verwendeten Verzeichnisse `geofabrik`, `local` und `certbot`. Ein systemd-Drop-in lässt Docker bei jedem Start auf den erfolgreichen Volume-Mount warten, bevor bestehende Container neu gestartet werden. Der Status des ersten Starts lässt sich so prüfen: ```sh ssh deploy@"$(tofu output -raw server_ipv4)" \ "cloud-init status --wait && systemctl status watermaps-volume-setup --no-pager" ```