Docker Setup
IntegraMon wird als Multi-Process-Container gebaut. Ein Image enthaelt:
- Nginx
- Gunicorn mit der Django-ASGI-App
- Redis bei
REDIS_LOCAL=true - PostgreSQL bei
DB_LOCAL=trueundDB_BACKEND=postgresql - mehrere Celery-Worker
- den Custom-Controller
cpi/worker.py - die PDF-Export-Toolchain mit Chromium und Mermaid CLI
Supervisor startet und koordiniert diese Prozesse.
Runtime-Boot-Sequenz
Beim Containerstart ist die Abfolge:
deploy/scripts/boot.pywandelt JSON-Konfiguration in/app/backend/src/.envdeploy/start.shsourced diese.envmount.pymountet optional Koofr, SMB oder SSHFSDATA_DIRundLOG_DIRwerden aufgeloest- Nginx-Konfiguration wird aus Templates gerendert, sofern kein
NGINX_CONF_OVERRIDEgesetzt ist - Supervisor startet PostgreSQL, Redis, Migration, Web, Celery, Controller und Nginx
Darum ist die Docker-Konfiguration nicht nur eine Menge docker run -e ...-Variablen. Die Boot-Schicht schreibt und normalisiert die effektive Runtime-Umgebung zuerst um.
Wie Konfiguration in den Container gelangt
Es gibt zwei unterstuetzte Bootstrap-Kanaele:
CONFIG_JSON_B64- eine gemountete Datei unter
/run/secrets/app-config.json
Beide erwarten JSON mit Upper-Case-Keys wie:
{
"DB_BACKEND": "postgresql",
"DB_HOST": "127.0.0.1",
"DB_PORT": 5432,
"DB_NAME": "monitorx",
"DB_USER": "postgres",
"DB_PASSWORD": "secret",
"CELERY_BROKER_URL": "redis://localhost:6379/0",
"REDIS_CACHE_URL": "redis://localhost:6379/2",
"DATA_DIR": "/app/data"
}
Warum CONFIG_JSON_B64 existiert
Base64-JSON ist nuetzlich, weil es:
- ein strukturiertes Payload statt vieler
-e KEY=value-Flags liefert - gut auf Plattformen mit reiner ENV-Injektion funktioniert
- Quoting-Probleme bei JSON im Shell-Kontext vermeidet
- dieselben Keys transportiert, die spaeter als
.env-Eintraege landen
Im Container macht boot.py dann:
- Whitespace entfernen
- base64 dekodieren
- JSON parsen
- normalisierte
KEY=value-Zeilen in/app/backend/src/.envschreiben
Ist CONFIG_JSON_B64 ungueltig, stoppt der Boot sofort.
Tatsaechliche Prioritaet in Docker
Die effektive Reihenfolge im laufenden Container ist:
CONFIG_JSON_B64/run/secrets/app-config.json- bestehende
/app/backend/src/.env boot.py-Fallback-Defaults- Django-Setting-Fallbacks
- Laufzeitdaten aus der Datenbank wie Worker-Tuning, Metrik-Intervalle, Tenant-Konfiguration, Templates und Cleanup-Settings
Das ist wichtig, weil Einstellungen ueber mehrere Ebenen verteilt sind:
- Infrastruktur-Settings wie DB oder Redis kommen aus ENV
- Application-Defaults greifen trotzdem, wenn ein Key fehlt
- Tenant-Verhalten kommt oft aus
cConfigExt - Plattform-Tuning kommt oft aus
cMetricSettingsundcWorkerTuningSettings
Beispiel: lokaler All-in-One-Container
docker run -d \
--name integramon-local \
-p 80:80 \
-v "$(pwd)/data:/app/data" \
-v "$(pwd)/deploy/env/postgreslocal.docker.json:/run/secrets/app-config.json:ro" \
--restart unless-stopped \
integramon:latest
Dieses Muster nutzt:
- internes PostgreSQL
- internes Redis
- persistente Application-Daten unter
/app/data - generierte Nginx-Konfiguration aus dem HTTP-Template
Beispiel: externes PostgreSQL und Redis
docker run -d \
--name integramon-prod \
-p 80:80 \
-e APP_BASE_PATH="/integramon" \
-e FRONTEND_BASE_URL="https://example.com/integramon" \
-e ENABLE_SSL="false" \
-e CONFIG_JSON_B64="$CONFIG_JSON_B64" \
-v "$(pwd)/data:/app/data" \
--restart unless-stopped \
integramon:latest
In diesem Modell sollte das JSON-Payload setzen:
DB_LOCAL=falseREDIS_LOCAL=false- externe
DB_HOST,DB_USER,DB_PASSWORD - externe
CELERY_BROKER_URL,CELERY_RESULT_BACKEND,REDIS_CACHE_URLund idealerweiseCHANNELS_REDIS_URL
Beispiel: Compose-Muster
Die vorhandene docker-compose.yml im Repo zeigt derzeit eher ein Entwicklungssetup mit:
postgresredisapp
Fuer Produktion sollte Compose zusaetzlich Persistenz und explizite Runtime-Config einbinden:
services:
app:
image: integramon:latest
restart: unless-stopped
ports:
- "80:80"
environment:
APP_BASE_PATH: /integramon
FRONTEND_BASE_URL: https://example.com/integramon
CONFIG_JSON_B64: ${CONFIG_JSON_B64}
volumes:
- ./data:/app/data
Volumes und Persistenz
Empfohlene persistente Mounts:
/app/data- optional Zertifikatsdateien fuer
SSL_CERTundSSL_KEY - optional ein Custom-Nginx-Config fuer
NGINX_CONF_OVERRIDE - optional
/run/secrets/app-config.json
Was in /app/data landet, haengt vom Modus ab:
- SQLite-DB-Datei bei
DB_BACKEND=sqlite - Tenant-Archive
- Tenant-Job-Logs
- Laufzeit-Verzeichnisse aus
cConfigExt
Was nicht automatisch persistent ist, wenn du es nicht separat mountest:
/var/log/nginx- interne PostgreSQL-Clusterdateien
- interner Redis-Zustand, weil interner Redis ohne RDB und AOF laeuft
Fuer Produktion bedeutet das:
- internen Redis nicht als dauerhaften Queue-Speicher behandeln
- externes PostgreSQL bevorzugen oder PostgreSQL-Daten mounten, wenn die Datenbank im Container bleiben soll
Interne versus externe Services
DB_LOCAL und REDIS_LOCAL entscheiden nur, ob Supervisor die internen Daemons startet.
Sie schreiben die Django-Verbindungseinstellungen nicht automatisch um.
Beispiele:
REDIS_LOCAL=falseohne externe Redis-URLs laesst Django weiterhin auf lokale Redis-Defaults zeigen und faellt ausDB_LOCAL=falsemitDB_BACKEND=postgresqlbraucht trotzdem gueltige externe Postgres-Credentials
Reverse Proxy und Subpath-Verhalten
APP_BASE_PATH wird an drei Stellen genutzt:
- Nginx-Location-Blocks
- runtime-generierte
/var/www/html/app-config.js - umgeschriebenes
<base href>inindex.html
Deshalb kann dasselbe Frontend-Build sowohl unter / als auch unter einem Subpath wie /integramon laufen.
HTTPS-Verhalten
Wenn ENABLE_SSL=true, rendert start.sh das HTTPS-Nginx-Template und erwartet:
SERVER_NAMESSL_CERTSSL_KEY
Sind diese Pfade falsch oder fehlen sie, startet Nginx nicht.
Fuer Deployments hinter einem vorgeschalteten Reverse Proxy oder Load Balancer ist es meist einfacher, ENABLE_SSL=false zu lassen und TLS upstream zu terminieren.
Logging und Restart-Verhalten
Supervisor schreibt Prozesslogs in LOG_DIR, typischerweise:
postgres.logredis.logmigrate.loggunicorn.logcelery-*.logworker.lognginx.log
Der Container-CMD ist bash /start.sh, daher fuehrt jeder Container-Restart die gesamte Bootstrap-Sequenz erneut aus.
Empfohlene Docker-Restart-Policy:
unless-stoppedfuer langlebige Umgebungen
PDF-Generierung in Docker
Das Image installiert bereits alles, was manage.py export_docs_pdfs benoetigt:
- Chromium
- Mermaid CLI
- Cairo- und Pango-Libraries
- den kompletten Doku-Baum
Der Docker-Build fuehrt sogar aus:
python /app/backend/src/manage.py export_docs_pdfs --output-dir /app/generated-docs
Das bedeutet: Neue Markdown-Seiten unter docs/integramon/docs und docs/integramon/sysdocs muessen mit derselben Export-Pipeline kompatibel bleiben. Normales Markdown, Standard-Tabellen und Mermaid-Bloecke sind dafuer sichere Patterns.