Datenbank Runtime
IntegraMon unterstuetzt aktuell zwei echte Betriebsmodi:
- SQLite
- PostgreSQL einschliesslich Neon-artiger gehosteter PostgreSQL-Varianten
Unterstuetzte Backends
Der Umschalter kommt ueber DB_BACKEND:
sqlitepostgresqlpostgrespostgres_neonpostgresql_neonneon
Was ist der reale Default
Es gibt eine wichtige Implementierungsnuance:
- Django faellt auf
sqlitezurueck, wenn keinDB_BACKENDvorhanden ist deploy/scripts/boot.pynutzt in seinen eigenen Fallback-JSON-Defaultspostgresql
Darum haengt der praktische Default davon ab, wie der Container gestartet wurde:
- kein Bootstrap-JSON und keine bestehende
.env: Django verhaelt sich wie SQLite - Bootstrap-JSON aus den Docker-Samples: meist PostgreSQL
SQLite versus PostgreSQL
SQLite ist akzeptabel, wenn
- ein kleines Team das System nutzt
- Schreibkonkurrenz gering ist
- das Message-Volumen moderat ist
- ein einfaches All-in-One-Deployment gewuenscht ist
- dateibasierte Backups ausreichen
PostgreSQL ist empfohlen, wenn
- mehrere User parallel arbeiten
- Message-Ingestion kontinuierlich laeuft
- mehrere Celery-Worker gleichzeitig schreiben
- Archive, Alerts und Metriken regelmaessig laufen
- eine berechenbare Betriebswiederherstellung gebraucht wird
Einfluss auf Concurrency
SQLite ist eine Single-File-Datenbank. Fuer kleine Lasten funktioniert das gut, hat aber natuerliche Write-Lock-Grenzen.
Im aktuellen Code ist das relevant, weil mehrere Prozesse gleichzeitig schreiben koennen:
- Django-Web-Requests
- mehrere Celery-Worker
- der Custom-Controller-Loop
- Archive-Cleanup und Metric-Snapshot-Jobs
SQLITE_TIMEOUT steht standardmaessig auf 20, reduziert also sofortige Lock-Fehler, aendert aber nicht das grundlegende Single-Writer-Modell.
Sobald Background-Work relevant wird, ist PostgreSQL der deutlich sicherere Produktionsweg.
Interner PostgreSQL-Modus
Wenn alle folgenden Bedingungen zutreffen:
DB_BACKEND=postgresqlDB_LOCAL=true- Supervisor laeuft
dann startet der Container einen internen PostgreSQL-17-Cluster ueber:
sv_postgres.shsv_pg_init.shpg_init.sh
Die Helferskripte:
- erzeugen den Cluster bei Bedarf
- hoeren auf Port
5432 - setzen oder aendern das Passwort des DB-Users
- legen die Zieldatenbank an, falls sie fehlt
- fuehren danach Django-Migrationen aus
Das ist fuer kompakte Umgebungen praktisch, bedeutet aber auch: Ohne gemountete Persistenz haengt die Datenbank direkt am Lifecycle des Application-Containers.
Externer PostgreSQL-Modus
Bei DB_LOCAL=false wird der interne Daemon uebersprungen. Django nutzt PostgreSQL aber weiterhin, wenn DB_BACKEND das vorgibt. Deshalb muessen dann zusaetzlich vorhanden sein:
DB_HOSTDB_PORTDB_NAMEDB_USERDB_PASSWORD
Fuer gehostete PostgreSQL- oder Neon-Setups setzt man typischerweise auch:
DB_SSLMODE=require- optional
DB_CHANNEL_BINDING=require
Migrationen
Migrationen laufen automatisch beim Startup:
- SQLite-Pfad:
sv_migrate.shfuehrtmanage.py migrateaus - PostgreSQL lokal:
app_migrate.sh - PostgreSQL remote:
db_wait_and_migrate.sh
Die Runtime wartet auf /tmp/migrate.done, bevor Gunicorn, Celery-Worker, Controller-Loop und Nginx als ready gelten.
Betriebsfolge:
- Schema-Drift wird bei jedem Restart korrigiert
- fehlgeschlagene Migrationen koennen trotzdem einen halb gestarteten Container hinterlassen, daher sind die Migrationslogs wichtig
Connection Pooling
Im aktuellen Settings-Modul gibt es kein eingebautes Django-Pooling wie CONN_MAX_AGE oder psycopg_pool.
Vorhanden ist heute:
- direkte Django-Verbindungen
PGCONNECT_TIMEOUTueberDB_CONNECT_TIMEOUTfuer Readiness-Checks
Wenn Pooling noetig ist, sollte es auf Infrastrukturebene eingefuehrt werden:
- Managed Pooler wie bei Neon
- PgBouncer
- separates Connection-Management auf DB-Seite
Storage-Growth-Verhalten
Die groessten Tabellen sind in der Praxis voraussichtlich:
cpiMessageLogcpiMessageLogRunscpiCustomHeaderPropertiescpiPayloadcpiMessageAttachment- Archive-Tracking und Metric-Snapshot-Tabellen ueber die Zeit
Growth-Treiber sind:
- Polling-Frequenz
- Anzahl heruntergeladener Payloads
- Deep-Artifact-Sync
- Archive-Retention
- Metric-Snapshot-Retention
Cleanup und Vacuum-Verhalten
Archive-Jobs fuehren bewusst backend-spezifisches Cleanup aus:
- SQLite:
wal_checkpoint(TRUNCATE)plusVACUUM - PostgreSQL:
VACUUM FULL ANALYZE
Das verbessert den reclaimten Platz nach Archiv-Deletion, bedeutet aber auch:
- SQLite-Archive koennen write-intensive Phasen staerker blockieren
- PostgreSQL
VACUUM FULList betriebsseitig deutlich schwerer als ein leichter Vacuum-Lauf
Backup-Hinweise
SQLite
Empfohlen:
- App stoppen oder zumindest Write-Peaks vermeiden
- die SQLite-Datei unter
DATA_DIRsichern - bei Bedarf auch
/app/data-Archive und Logs mitsichern
PostgreSQL
Empfohlen:
- uebliche PostgreSQL-Backups wie
pg_dumpoder Storage-Snapshots - bei externem PostgreSQL die Provider-Backup-Mechanismen nutzen
- Application-seitige Archivverzeichnisse separat sichern, wenn sie fuer Recovery relevant sind
Produktions-Empfehlung
PostgreSQL fuer:
- geteilte Umgebungen
- relevanten Background-Job-Durchsatz
- alles Kundennahe
SQLite nur fuer:
- lokale Demos
- Single-Admin-Piloten
- leichte Testumgebungen