Hallo zusammen,
ich möchte ein kleines Setup teilen, mit dem sich kivitendo containerisiert und mit einer serverlosen Postgres-Datenbank (Neon) betreiben lässt – statt der klassischen lokalen Postgres-Instanz.
Warum?
Neon ist ein gehosteter, serverloser Postgres-Dienst: die Datenbank skaliert automatisch, wird bei Inaktivität auf null heruntergefahren (Scale-to-Zero) und man muss sich um kein eigenes DB-Hosting kümmern. Für kivitendo bedeutet das: der Anwendungscontainer bleibt zustandslos, die Daten liegen sicher und verwaltet extern.
Wie ist es aufgebaut?
Das Deployment wird über eine einzige .env-Datei gesteuert. Ein Schalter entscheidet über das DB-Backend:
cp .env.neon-postgres.example .env # Zugangsdaten eintragen
docker compose up -d --build
| DB_BACKEND | Datenbank | lokaler db-Container |
| postgres | Lokaler PostgreSQL-Container | wird gestartet |
| neon-postgres | Neon Serverless Postgres | wird nicht gestartet |
Bei neon-postgres läuft nur der App-Container, die DB liegt komplett bei Neon.
Ein paar Stolpersteine, die gelöst sind
Damit das reibungslos funktioniert, waren einige kivitendo-spezifische Anpassungen nötig, die im Image automatisch angewendet werden:
- TLS + SNI: Neon verlangt SSL und – weil die libpq unter Debian
Bullseye noch kein SNI kann – die Endpoint-ID im DSN. Das wird für
*.neon.tech-Hosts automatisch injiziert (sslmode=require;options=endpoint=…), lokal bleibt es inaktiv.
- Superuser-Gate: kivitendo prüft beim Anlegen eines Mandanten auf
einen echten Postgres-Superuser. Neon vergibt kein usesuper, wohl
aber CREATEDB – das reicht völlig für kivitendo. Die Prüfung wurde
entsprechend auf usesuper OR usecreatedb gelockert.
template0 statt template1: Neon hält immer eine Session auf template1 offen, wodurch
CREATE DATABASE ... TEMPLATE template1 fehlschlägt. Die DB-Erstellung
nutzt daher template0.
- Scale-to-Zero / Cold Starts: Neon suspendiert
die Compute nach ~5 Min Leerlauf. Verbindungen bekommen ein
connect_timeout mit Retry, tote Handles werden erkannt und neu
aufgebaut – der erste Request nach einer Pause weckt die DB in ~5–7 s
auf, ohne Fehler. Zusätzlich sind die mod_fcgid-Timeouts hochgesetzt,
damit lange Migrationsläufe (~200 dbupgrade-Schritte beim
Mandanten-Anlegen) nicht abbrechen.
Auch lauffähig in Kubernetes
Das Image ist bewusst 12-Factor-freundlich: jede Einstellung aus der kivitendo.conf lässt sich per Umgebungsvariable überschreiben – ideal für ConfigMaps und Secrets:
KIVI_<SECTION>__<KEY> = wert
Beispiele:
KIVI_AUTHENTICATION__ADMIN_PASSWORD=s3cret
KIVI_AUTHENTICATION_DATABASE__HOST=postgres.default.svc.cluster.local
KIVI_MAIL_DELIVERY__HOST=smtp.example.com
KIVI_SYSTEM__DEFAULT_LANGUAGE=de
Nur die gesetzten Keys werden geändert, alle übrigen Defaults und Kommentare der kivitendo.conf bleiben erhalten. Damit läuft derselbe Container unverändert lokal per docker compose, gegen Neon in der Cloud oder in einem Kubernetes-Cluster – die Konfiguration kommt komplett aus der Umgebung.
https://github.com/davidwuest/kivitendo-docker-v2
Über Rückmeldungen und Erfahrungen mit ähnlichen Setups freue ich mich!
Viele Grüße