Add production compose stack and stop idle load in containers

The development stack was running permanently on a server: polling file
watchers, a healthcheck that rendered a full page every five seconds and no
memory limit grew next dev to 10 GB and pushed the host into swap.

- add compose.prod.yaml running compiled output in separate api/web services
- make the Dockerfile multi-stage with dev and prod targets, prune
  devDependencies and run the runtime image as node instead of root
- bake API_INTERNAL_URL at build time; next start ignores it at runtime
  because rewrite destinations are resolved into routes-manifest.json
- drop CHOKIDAR_USEPOLLING and WATCHPACK_POLLING
- probe /health instead of /, which redirects to /projects and made every
  healthcheck render the project list
- give every service a memory limit and forbid swap in production
- rename the development compose project to leistungsbilanz-dev so its
  down command cannot target the production stack
- bind development ports to localhost
- close the http server and the SQLite handle on SIGTERM/SIGINT
- match probe user agents in the navigation log filter; Node's fetch sends
  one, so the previous check never matched
- exit docker-start.sh when either supervised process dies
- remove drizzle.config.js, a compiled copy drizzle-kit never reads, and the
  pre-Next index.html/styles.css leftovers

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Grovy311 2026-08-15 00:26:56 +02:00
parent a17e2e3f4b
commit 01fa527b9c
14 changed files with 424 additions and 118 deletions

23
README.md Normal file → Executable file
View file

@ -4,8 +4,9 @@ Leistungsbilanz ist eine Webanwendung für die elektrische Ausführungsplanung.
Mittelpunkt steht ein tabellenähnlicher Stromkreislisten-Editor, der Stromkreise,
Gerätezeilen und wiederverwendbare Projektgeräte fachlich getrennt behandelt.
Das Projekt befindet sich in aktiver Entwicklung. Der lokale Entwicklungsbetrieb
mit SQLite und Docker Compose ist unterstützt. Ein Produktionsdeployment,
Das Projekt befindet sich in aktiver Entwicklung. Unterstützt sind der lokale
Entwicklungsbetrieb (`compose.yaml`) und ein Einzelbenutzer-Deployment im
vertrauenswürdigen Netz (`compose.prod.yaml`). Authentifizierung,
Mehrbenutzerbetrieb und der Revit-/IFCGUID-Datenaustausch sind noch nicht
implementiert.
@ -62,9 +63,21 @@ docker compose logs --follow
docker compose down
```
Der Compose-Stack startet Entwicklungsserver mit Quellcode-Mounts. Er ist kein
Produktionsdeployment. Details stehen in
[Deployment und Betrieb](docs/deployment.md).
`compose.yaml` startet Entwicklungsserver mit Quellcode-Mounts, veröffentlicht
seine Ports nur auf `127.0.0.1` und ist **kein Produktionsdeployment**. Es
gehört nicht in den Dauerbetrieb: `next dev` und `tsx watch` erzeugen auch ohne
Benutzer dauerhaft Last und wachsen im Speicher.
## Deployment
```bash
docker compose -f compose.prod.yaml up --build --detach
```
Startet die kompilierte API und `next start` in getrennten Containern, mit
Speicherlimits und ohne Dateibeobachter. Das Frontend hört auf Port 3090, die
API ist nur intern erreichbar. Vorbereitung eines bestehenden Datenvolumes und
weitere Details stehen in [Deployment und Betrieb](docs/deployment.md).
## Direkte lokale Entwicklung