feat: add Docker/OpenTofu deployment and DE/NL routing
This commit is contained in:
@@ -22,18 +22,37 @@ iPhone-taugliche Browser-PWA für Bootsfahrer: Karte, GPS, Kompass, Wetter/Welle
|
||||
|
||||
## Start
|
||||
|
||||
Dieses Projekt benötigt Node `>=20.19`. In dieser Arbeitskopie liegt eine lokale Node-Version unter `.tools/`; nutze sie so:
|
||||
Der reguläre lokale Betrieb läuft als einzelner Produktionscontainer. Der
|
||||
gemeinsame Fahrwasserindex für Deutschland und die Niederlande muss einmalig
|
||||
vorhanden sein:
|
||||
|
||||
```bash
|
||||
npm run setup:local-routing
|
||||
npm run docker:up
|
||||
```
|
||||
|
||||
Web und API: `http://localhost:5173`<br>
|
||||
Healthcheck: `http://localhost:5173/health`
|
||||
|
||||
Die sichtbaren Kartenkacheln kommen weiterhin von den konfigurierten externen
|
||||
Kartendiensten. Lokal gespeichert werden nur die OSM-Rohdaten und der daraus
|
||||
erzeugte Routingindex.
|
||||
|
||||
Stoppen:
|
||||
|
||||
```bash
|
||||
npm run docker:down
|
||||
```
|
||||
|
||||
Für die Entwicklung ohne Container benötigt das Projekt Node `>=20.19`:
|
||||
|
||||
```bash
|
||||
export PATH="$PWD/.tools/bin:$PATH"
|
||||
npm install
|
||||
npm run build
|
||||
npm run test
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Web: `http://localhost:5173`<br>
|
||||
API: `http://localhost:5174`
|
||||
Dev-Web: `http://localhost:5173`<br>
|
||||
Dev-API: `http://localhost:5174`
|
||||
|
||||
Für GPS-Tests auf dem iPhone muss die App über HTTPS laufen. Starte dafür:
|
||||
|
||||
@@ -43,13 +62,75 @@ npm run dev:https
|
||||
|
||||
Web HTTPS: `https://localhost:5173` bzw. die von Vite ausgegebene `https://192.168...:5173`-Adresse im gleichen WLAN. Beim lokalen Dev-Zertifikat muss Safari die Zertifikatswarnung einmal akzeptieren; falls iOS Geolocation danach weiterhin blockiert, nutze ein vertrauenswürdiges lokales Zertifikat oder einen HTTPS-Tunnel.
|
||||
|
||||
## Hetzner-Deployment mit OpenTofu
|
||||
|
||||
Die produktive Infrastruktur besteht aus einem Hetzner-Server, einer festen
|
||||
IPv4, Firewall und einem persistenten Volume. Der Docker-Stack enthält nur die
|
||||
App, Nginx/Certbot und den Wartungscontainer für Deutschland- und
|
||||
Niederlande-Routendaten; Kartenkacheln werden nicht selbst gehostet.
|
||||
|
||||
Die beiden lokalen, von Git ignorierten Konfigurationsdateien sind bereits
|
||||
angelegt:
|
||||
|
||||
- `infra/opentofu/terraform.tfvars`: hier den Hetzner-Cloud-Read/Write-Token
|
||||
eintragen und `admin_cidrs` bei Bedarf auf die aktuelle öffentliche IP
|
||||
aktualisieren.
|
||||
- `deploy/.env.production`: hier eine echte E-Mail-Adresse für Let's Encrypt
|
||||
als `WATERMAPS_ACME_EMAIL` eintragen.
|
||||
|
||||
Danach wird die Infrastruktur erzeugt:
|
||||
|
||||
```bash
|
||||
cd infra/opentofu
|
||||
tofu init
|
||||
tofu plan -out=watermaps.tfplan
|
||||
tofu apply watermaps.tfplan
|
||||
tofu output server_ipv4
|
||||
cd ../..
|
||||
```
|
||||
|
||||
Sobald `server_ipv4` ausgegeben wurde, kann der manuelle DNS-A-Record
|
||||
`watermaps.incoso.eu` auf diese IPv4 gesetzt werden. Das erste Deployment darf
|
||||
bereits vor der DNS-Propagation laufen:
|
||||
|
||||
```bash
|
||||
./deploy/scripts/upload-and-deploy.sh \
|
||||
--identity ~/.ssh/watermaps_hetzner_ed25519
|
||||
```
|
||||
|
||||
Dabei werden die vollständigen Geofabrik-Extrakte für Deutschland und die
|
||||
Niederlande auf dem persistenten Server-Volume geladen und der lokale
|
||||
Routingindex erstellt. Vor dem SSL-Livegang liefert Port 80 außer
|
||||
ACME-Challenges nur 404.
|
||||
|
||||
Erst wenn der DNS-A-Record propagiert ist, wird HTTPS mit dem finalen manuellen
|
||||
Befehl aktiviert:
|
||||
|
||||
```bash
|
||||
./deploy/scripts/remote-go-live.sh \
|
||||
--identity ~/.ssh/watermaps_hetzner_ed25519
|
||||
```
|
||||
|
||||
Das Skript prüft DNS, beide Länder im Routingindex sowie Testrouten, fordert
|
||||
das Zertifikat an und schaltet anschließend dauerhaft auf HTTPS um.
|
||||
Ausführliche Hinweise stehen in
|
||||
[`infra/opentofu/README.md`](infra/opentofu/README.md) und
|
||||
[`deploy/README.md`](deploy/README.md).
|
||||
|
||||
## Datenstatus
|
||||
|
||||
Die freie Datenstrategie ist bewusst als Fahr- und Planungshilfe umgesetzt. Die App zeigt Attribution und den Status `Nicht amtlich`, weil freie Karten-/Modelldaten keine amtlich zugelassene Seekarte ersetzen.
|
||||
|
||||
## Routingstatus
|
||||
|
||||
`POST /api/routes` nutzt zuerst lokale PostGIS-Fahrwasserdaten aus `marine_fairway_edges`. Wenn in der Datenbank kein passender Graph liegt, versucht die API live extrahierte OSM/OpenSeaMap-Fahrwasserdaten für die Bounding Box zwischen Start, Wegpunkten und Ziel. Lokale und Live-Fragmente werden topologisch zusammengeführt. Berücksichtigt werden unter anderem `navigation_line`, `recommended_track`, `fairway`, navigierbare Kanäle und explizit für Boote oder Schiffe freigegebene Flüsse. Gesperrte, private, stillgelegte oder im Bau befindliche Wege werden ausgeschlossen.
|
||||
`POST /api/routes` kann Fahrwasserdaten aus PostGIS, dem lokalen
|
||||
Geofabrik-Dateiindex und – wenn explizit aktiviert – live aus Overpass
|
||||
zusammenführen. Die Produktionskonfiguration verwendet ausschließlich den
|
||||
lokalen Deutschland-/Niederlande-Index; sie benötigt weder PostGIS noch eine
|
||||
laufende Overpass-Verbindung. Berücksichtigt werden unter anderem
|
||||
`navigation_line`, `recommended_track`, `fairway`, navigierbare Kanäle und
|
||||
explizit für Boote oder Schiffe freigegebene Flüsse. Gesperrte, private,
|
||||
stillgelegte oder im Bau befindliche Wege werden ausgeschlossen.
|
||||
|
||||
Wenn freie Laufzeitdaten fehlen, stehen zwei klar als nicht amtlich markierte Fallback-Korridore bereit:
|
||||
|
||||
@@ -112,7 +193,7 @@ Die Küsten-PBFs lassen sich reproduzierbar von Geofabrik laden und ohne lokal i
|
||||
|
||||
```bash
|
||||
./scripts/download-geofabrik.sh
|
||||
docker compose up -d postgres redis martin
|
||||
docker compose --profile postgis up -d postgres redis martin
|
||||
DATABASE_URL=postgres://seacompass:seacompass@localhost:55432/seacompass \
|
||||
./scripts/import-geofabrik-docker.sh \
|
||||
data/geofabrik/germany-latest.osm.pbf \
|
||||
@@ -206,11 +287,37 @@ Der lokale PostGIS-Container nutzt standardmäßig Host-Port `55432`, damit er n
|
||||
## Lokale Infrastruktur
|
||||
|
||||
```bash
|
||||
docker compose up -d postgres redis martin
|
||||
docker compose --profile postgis up -d postgres redis martin
|
||||
```
|
||||
|
||||
Danach `.env` aus `.env.example` ableiten und für echte PostGIS-Features `WATERMAPS_DEMO_DATA=false` setzen. Die frühere Variable `SEA_COMPASS_DEMO_DATA` wird übergangsweise weiterhin akzeptiert.
|
||||
|
||||
### Dateibasiertes Deutschland-/Niederlande-Routing
|
||||
|
||||
Wenn Docker/PostGIS nicht verfügbar ist, kann die API den vollständigen
|
||||
Geofabrik-Extrakt beider Länder als kompakte lokale Fahrwasserdatei verwenden:
|
||||
|
||||
```bash
|
||||
npm run setup:local-routing
|
||||
```
|
||||
|
||||
Der Aufbau liest beide PBFs in Streaming-Durchläufen, führt überlappende
|
||||
OSM-Wege zusammen und erzeugt
|
||||
`data/local/germany-netherlands-fairways.json`. Für einen ausschließlich
|
||||
lokalen Betrieb:
|
||||
|
||||
```dotenv
|
||||
DATABASE_URL=
|
||||
REDIS_URL=
|
||||
WATERMAPS_LOCAL_FAIRWAYS_PATH=data/local/germany-netherlands-fairways.json
|
||||
WATERMAPS_LIVE_FAIRWAYS=false
|
||||
```
|
||||
|
||||
Damit benötigen Routen innerhalb des heruntergeladenen Datenstands weder
|
||||
PostGIS noch eine laufende Overpass-Verbindung. Nach einem neuen
|
||||
Geofabrik-Snapshot prüft `npm run setup:local-routing` die Prüfsummen und baut
|
||||
den Index bei Bedarf atomar neu.
|
||||
|
||||
## APIs
|
||||
|
||||
- `GET /api/config`
|
||||
|
||||
Reference in New Issue
Block a user