Skip to content

Datenbank Runtime

IntegraMon unterstuetzt aktuell zwei echte Betriebsmodi:

  • SQLite
  • PostgreSQL einschliesslich Neon-artiger gehosteter PostgreSQL-Varianten

Unterstuetzte Backends

Der Umschalter kommt ueber DB_BACKEND:

  • sqlite
  • postgresql
  • postgres
  • postgres_neon
  • postgresql_neon
  • neon

Was ist der reale Default

Es gibt eine wichtige Implementierungsnuance:

  • Django faellt auf sqlite zurueck, wenn kein DB_BACKEND vorhanden ist
  • deploy/scripts/boot.py nutzt in seinen eigenen Fallback-JSON-Defaults postgresql

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=postgresql
  • DB_LOCAL=true
  • Supervisor laeuft

dann startet der Container einen internen PostgreSQL-17-Cluster ueber:

  • sv_postgres.sh
  • sv_pg_init.sh
  • pg_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_HOST
  • DB_PORT
  • DB_NAME
  • DB_USER
  • DB_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.sh fuehrt manage.py migrate aus
  • 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_TIMEOUT ueber DB_CONNECT_TIMEOUT fuer 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:

  • cpiMessageLog
  • cpiMessageLogRuns
  • cpiCustomHeaderProperties
  • cpiPayload
  • cpiMessageAttachment
  • 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) plus VACUUM
  • 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 FULL ist betriebsseitig deutlich schwerer als ein leichter Vacuum-Lauf

Backup-Hinweise

SQLite

Empfohlen:

  • App stoppen oder zumindest Write-Peaks vermeiden
  • die SQLite-Datei unter DATA_DIR sichern
  • bei Bedarf auch /app/data-Archive und Logs mitsichern

PostgreSQL

Empfohlen:

  • uebliche PostgreSQL-Backups wie pg_dump oder 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