This commit introduces comprehensive guidelines for managing development and production environments, addressing the user's strategic questions regarding workflow, webhook handling, and secure email sending. - **Teil 4: Entwicklungs- vs. Produktions-Workflow:** Documents the 'separated worlds' approach for development on Synology and production on the Wackler VM, detailing configuration separation, webhook handling, and safe email testing. - **Teil 5: Alternative - Single-Host-Setup:** Provides a robust strategy for running both development and production environments on a single VM, emphasizing directory structure, port conflict resolution, and guaranteed database isolation via Docker volumes. These additions clarify the operational guidelines for maintaining system stability and data integrity post-migration.
15 KiB
Anforderungsdokument (Version 3): Docker-Migration nach Ubuntu VM (docker1)
Zweck: Verbindliche Netzwerk-Anforderungen und schrittweiser Migrationsplan für den Umzug des GTM-Engine Stacks (ca. 20 Container). Basierend auf den Stabilisierungs-Erkenntnissen vom 07.03.2026.
Teil 1: Externe Port-Freigaben (Firewall)
Diese Ports müssen auf der Firewall für den eingehenden Verkehr zur VM 10.10.81.2 geöffnet werden.
| Host-Port | Ziel-Dienst | Zugriff | Zweck |
|---|---|---|---|
| 8090 | gateway_proxy |
Intranet | Zentraler Zugang. Alle Web-Apps (Dashboard, CE, Lead). |
| 3000 | gitea |
Intranet | Gitea Web UI. |
| 2222 | gitea |
Intranet | Gitea Git via SSH. |
| 8003 | connector-so |
Public | SuperOffice Webhook-Empfänger (SSL erforderlich!). |
| 5678 | n8n |
Public | Automation Workhooks. |
| 8094 | gtm-architect |
Intranet | GTM Architect Direct. |
| 8092 | b2b-marketing |
Intranet | B2B Marketing Assistant Direct. |
| 8001 | transcription |
Intranet | Transcription Tool Direct (via 8090). |
Port-Mapping (docker-compose.yml)
Die folgende Tabelle listet alle Host-Ports auf, die durch die docker-compose.yml gebunden werden. Diese sind die Ports, die auf docker1 lauschen werden.
| Host-Port | Ziel-Dienst | Zweck / Notiz |
|---|---|---|
| 8090 | nginx (Gateway) |
Zentraler Zugang (Intranet) |
| 8000 | company-explorer |
API (intern) |
| 8003 | connector-superoffice |
Webhook (Public) |
| 8501 | lead-engine |
UI (intern) |
| 8004 | lead-engine |
API (intern) |
| 8092 | b2b-marketing-assistant |
UI/API (Intranet) |
| 8093 | content-engine |
UI/API (Intranet) |
| 8094 | gtm-architect |
UI/API (Intranet) |
| 8096 | heatmap-frontend |
UI (Intranet) |
| 8002 | heatmap-backend |
API (intern) |
| 8097 | competitor-analysis |
UI/API (Intranet) |
| 8098 | market-intelligence |
UI/API (Intranet) |
| 8001 | transcription-tool |
UI/API (Intranet) |
Teil 2: Netzwerk-Architektur (Intern)
- DNS Resolver: In Nginx konfiguriert (
resolver 127.0.0.11). - WebSockets: Das Gateway unterstützt
Upgrade-Header (kritisch für Streamlit/Lead-Engine). - Echo-Prävention: Der Connector (
worker.py) identifiziert sich dynamisch. Keine manuellen ID-Einträge in.envnötig, solangeSO_CLIENT_IDpasst. - Routing:
/ce/->company-explorer:8000/lead/->lead-engine:8501(UI)/feedback/->lead-engine:8004(API)/gtm/->gtm-architect:3005(API/Frontend)/b2b/->b2b-marketing-assistant:3002(API/Frontend)/content/->content-engine:3000(API/Frontend)/market/->market-intelligence:3001(API/Frontend)/competitor/->competitor-analysis:3000(API/Frontend)/heatmap/->heatmap-frontend:80(Static/Proxy)/tr/->transcription-tool:8001(API/Frontend) -> Achtung: Benötigt explizitenrewritein Nginx!
⚠️ Kritische Lehren (Update 08.03.2026)
Der Umzug muss zwingend diese Punkte beachten, um den "Totalausfall" zu vermeiden:
1. Datenbank-Schema & Volumes
Regel: Datenbanken werden NIEMALS mehr direkt auf einen Host-Pfad gemountet.
Grund: Permission-Errors und SQLite-Locks auf Netzwerk-Dateisystemen.
Vorgehen: Nutzung von benannten Volumes (explorer_db_data, connector_db_data, lead_engine_data, gtm_architect_data, b2b_marketing_data, content_engine_data, market_intel_data, competitor_analysis_data, transcription_uploads).
2. Lead Engine: Kalender-Logik (v1.4)
- Raster: Das System bietet Termine nur im 15-Minuten-Takt (:00, :15, :30, :45) an.
- Abstand: Zwischen zwei Terminvorschlägen liegen mind. 3 Stunden Pause.
- AppOnly Workaround: Termin wird im Kalender von
info@robo-planet.deerstellt und der Mitarbeiter (e.melcer@) als Teilnehmer hinzugefügt.
3. GTM Architect & B2B Assistant: Standalone-Betrieb
- Architektur: Beide Apps nutzen das "Self-Contained Image" Muster. Code, Frontend-Builds (
dist/) undnode_modulessind fest im Image verbaut. - GTM Port: 3005 intern.
- B2B Port: 3002 intern.
- DB-Abhängigkeit: Der B2B Assistant benötigt zwingend die Datei
market_db_manager.py(wird beim Build aus dem Root kopiert).
4. Transcription Tool: FFmpeg & Routing
- FFmpeg: Muss im Image vorhanden sein (Build dauert ca. 15 Min auf Synology).
- Pfade: Das Tool benötigt eine
tsconfig.jsonimfrontend/Ordner für den TypeScript-Build. - Nginx: Der Pfad
/tr/muss explizit umgeschrieben werden:rewrite ^/tr/(.*) /$1 break;.
📂 Docker Volume Migration (Der "Plug & Play" Weg)
Um die Daten (Companies, Leads, Projekte, Audio-Files) ohne Verluste umzuziehen, müssen die benannten Volumes gesichert werden.
Auf der Synology (Quelle):
# Backup aller kritischen Volumes in ein Archiv
docker run --rm -v explorer_db_data:/data -v $(pwd):/backup alpine tar czf /backup/explorer_data.tar.gz -C /data .
docker run --rm -v lead_engine_data:/data -v $(pwd):/backup alpine tar czf /backup/lead_data.tar.gz -C /data .
docker run --rm -v gtm_architect_data:/data -v $(pwd):/backup alpine tar czf /backup/gtm_data.tar.gz -C /data .
docker run --rm -v b2b_marketing_data:/data -v $(pwd):/backup alpine tar czf /backup/b2b_data.tar.gz -C /data .
docker run --rm -v content_engine_data:/data -v $(pwd):/backup alpine tar czf /backup/content_data.tar.gz -C /data .
docker run --rm -v market_intel_data:/data -v $(pwd):/backup alpine tar czf /backup/market_data.tar.gz -C /data .
docker run --rm -v competitor_analysis_data:/data -v $(pwd):/backup alpine tar czf /backup/competitor_data.tar.gz -C /data .
docker run --rm -v transcription_uploads:/data -v $(pwd):/backup alpine tar czf /backup/tr_uploads.tar.gz -C /data .
Auf der Ubuntu VM (Ziel):
- Volumes anlegen:
docker volume create explorer_db_data(etc.) - Daten wiederherstellen:
docker run --rm -v explorer_db_data:/data -v $(pwd):/backup alpine sh -c "cd /data && tar xzf /backup/explorer_data.tar.gz"
Verbindlicher Migrationsplan
Phase 1: Vorbereitung
git pushauf Synology (aktuellster Stand inkl. GTM-Integration)..envDatei sichern (Vollständigkeit prüfen!).- Volumes sichern (siehe oben:
tar.gzErstellung).
Phase 2: Deployment auf docker1
- Repo klonen:
git clone ... /opt/gtm-engine .envkopieren.- Volumes restoren (BEVOR
docker compose upausgeführt wird). - Starten:
docker compose up -d --build - Schema-Check:
docker exec -it company-explorer python /app/fix_missing_columns.py
Phase 3: Verifizierung
- Check Kalender-Lesen:
docker exec lead-engine python /app/trading_twins/test_calendar_logic.py - Check GTM Architect:
https://10.10.81.2:8090/gtm/
Anhang A: Post-Deployment Port Check
Führen Sie dieses Skript auf einem Client-Rechner aus (nicht auf docker1 selbst), um die Erreichbarkeit der freigegebenen Ports zu testen. Ersetzen Sie TARGET_IP durch 10.10.81.2.
#!/bin/bash
TARGET_IP="10.10.81.2"
PORTS_INTRANET=(8090 3000 2222 8092 8093 8094 8096 8097 8098 8001)
PORTS_PUBLIC=(8003 5678)
echo "--- Testing Intranet Ports on $TARGET_IP ---"
for port in "${PORTS_INTRANET[@]}"; do
if nc -z -w 2 $TARGET_IP $port; then
echo "✅ Port $port is OPEN"
else
echo "❌ Port $port is CLOSED"
fi
done
echo -e "\n--- Testing Public Ports on $TARGET_IP (von extern prüfen!) ---"
for port in "${PORTS_PUBLIC[@]}"; do
echo " - Bitte prüfen Sie Port $port manuell von außerhalb des Netzwerks."
done
Teil 4: Entwicklungs- vs. Produktions-Workflow
Dieses Kapitel definiert die verbindlichen Regeln für die Weiterentwicklung der GTM-Engine nach der Migration, um maximale Stabilität und Sicherheit des Produktivsystems zu gewährleisten.
1. Grundprinzipien: Getrennte Welten
-
Regel 1: Keine Entwicklung in der Produktion. Auf der Wackler-VM (
docker1) wird niemals Code direkt bearbeitet, experimentiert oder getestet. Sie ist ausschließlich für den Betrieb der stabilen Softwareversion vorgesehen. -
Regel 2: Getrennte Konfiguration. Jede Umgebung hat ihre eigene Konfigurationsdatei.
-
Produktion (Wackler):
.env– Enthält alle echten API-Schlüssel und Endpunkte. -
Entwicklung (Synology):
.env.dev(oder eine Kopie der.env) – Verwendet Test-Schlüssel, Sandbox-Endpunkte und Dummy-Werte.
-
-
Regel 3: Die Produktionsdatenbank ist heilig. Die produktiven Docker-Volumes (
explorer_db_dataetc.) werden niemals für Entwicklungszwecke angetastet. Lokale Entwicklung findet gegen eine separate, lokale Test-Datenbank statt.
2. Umgang mit Live-Daten & Aktionen
a) SuperOffice Webhook
-
Problem: Es darf nur einen aktiven Webhook geben, um Dateninkonsistenzen zu vermeiden.
-
Lösung:
-
Produktion: Der Webhook (
https://<neue-wackler-domain>/connector/webhook) wird bei SuperOffice registriert. In der.envist dasWEBHOOK_SECRET_TOKENgesetzt. -
Entwicklung: In der
.env.devwird dasWEBHOOK_SECRET_TOKENauskommentiert (#WEBHOOK_SECRET_TOKEN=...). Der Connector ist somit "taub" für externe Anrufe. -
Testen in der Entwicklung: Um realistische Tests durchzuführen, wird eine Umgebungsvariable
LOG_WEBHOOKS=trueim produktiv-Connector gesetzt. Dieser schreibt dann den Body jedes eingehenden Webhooks in die Docker-Logs. Diese JSON-Payloads können kopiert werden, um mit einem Skript (curl) gezielte, manuelle Tests gegen die lokale Entwicklungsumgebung zu fahren.
-
b) E-Mail-Versand (Lead Engine & Co.)
-
Problem: Das Entwicklungssystem darf unter keinen Umständen E-Mails an echte Kunden oder Kontakte senden.
-
Lösung: Der "Safety Override"
-
Produktion: Die echten MS Graph API Credentials (
INFO_...) sind in der.envgesetzt. -
Entwicklung: Die MS Graph Credentials in der
.env.devsind auskommentiert oder mit Dummy-Werten belegt. -
Sicherer Test-Modus: Eine neue Umgebungsvariable
DEV_MODE_EMAIL_RECIPIENTwird implementiert.-
Wenn diese Variable in der
.env.devgesetzt ist (z.B.DEV_MODE_EMAIL_RECIPIENT=ihre.test@adresse.de), leitet der Code alle ausgehenden E-Mails an diese eine Adresse um. -
Test-Prozess: Für einen E-Mail-Test werden in der
.env.devtemporär die echten MS Graph Credentials eingetragen,DEV_MODE_EMAIL_RECIPIENTgesetzt, der Test durchgeführt und danach werden die Credentials sofort wieder entfernt/auskommentiert.
-
-
3. Deployment-Prozess: Von der Entwicklung zur Produktion
Der Prozess, um neuen, getesteten Code sicher auf das Produktivsystem zu bringen, ist wie folgt:
-
Entwicklung (Synology):
-
Ein neues Feature wird entwickelt und lokal gegen die Test-Datenbank getestet.
-
Änderungen werden committet und in das lokale Gitea auf der Synology gepusht (
git push).
-
-
Deployment (Wackler VM):
-
Verbindung zur Wackler-VM via SSH.
-
Ins Projektverzeichnis navigieren (
/opt/gtm-engine). -
Den neuesten stabilen Code vom Entwicklungs-Gitea holen:
git pull synology main. -
Die Docker-Container mit dem neuen Code neu bauen und starten:
docker compose up -d --build.
-
-
Netzwerkanforderung für Deployment:
- Für den
git pull-Befehl muss die Wackler-VM (10.10.81.2) auf den Gitea-Port (TCP 3000) der Synology-Diskstation zugreifen können. Dies muss einmalig im Netzwerk konfiguriert werden.
- Für den
Teil 5: Alternative - Single-Host-Setup (Dev & Prod auf einer VM)
Dieses Szenario beschreibt den wahrscheinlicheren Fall, dass die gesamte Arbeit (Entwicklung und Produktion) auf der von der IT bereitgestellten VM (docker1) stattfinden muss. Der Ansatz wandelt sich von "physischer Trennung" zu "logischer Trennung mit starker Isolation".
1. Grundkonzept: Schalldichte Räume
Auf der VM werden zwei komplett isolierte Umgebungen parallel betrieben. Docker ist für dieses Szenario optimiert und gewährleistet die Trennung von Code, Konfiguration, Ports und vor allem Daten.
- Produktionsumgebung (
prod): Läuft stabil mit dem geprüften Code und greift auf die produktiven Daten zu. - Entwicklungsumgebung (
dev): Dient zum Entwickeln und Testen. Hat eine eigene Konfiguration und eine komplett separate Test-Datenbank.
2. Implementierung
a) Verzeichnisstruktur
Eine saubere Ordnerstruktur ist die Basis für die Trennung.
/opt/gtm-engine/
├── dev/
│ ├── docker-compose.yml
│ ├── .env
│ └── (kompletter Code des Projekts...)
│
└── prod/
├── docker-compose.yml
├── .env
└── (kompletter Code des Projekts...)
b) Auflösung von Port-Konflikten
Zwei Stacks können nicht dieselben Ports nutzen. Die dev-Umgebung nutzt daher verschobene Ports.
| Dienst | Produktions-Port (in prod/docker-compose.yml) |
Entwicklungs-Port (in dev/docker-compose.yml) |
|---|---|---|
| Gateway | 8090:80 |
9090:80 |
| Webhook | 8003:8003 |
9003:8003 |
| GTM | 8094:3005 |
9094:3005 |
So ist das Produktivsystem unter http://10.10.81.2:8090 und das Entwicklungssystem unter http://10.10.81.2:9090 erreichbar.
c) Garantierte Datenbank-Isolation
Dies ist der wichtigste Punkt: Docker stellt sicher, dass die Datenbanken niemals vermischt werden können. Docker Compose erstellt benannte Volumes mit dem Verzeichnisnamen als Präfix.
docker compose upim Ordnerprod/erzeugt das Volumeprod_explorer_db_data.docker compose upim Ordnerdev/erzeugt das Volumedev_explorer_db_data.
Diese beiden Volumes sind vollständig voneinander isolierte Container auf der Festplatte. Ein Zugriff von dev auf prod-Daten ist technisch unmöglich. Ihre Anforderung, dass die Produktionsdatenbank sicher ist, wird hiermit zu 100% erfüllt.
3. Vereinfachter Workflow auf einer Maschine
Das neue Gitea (auf Port 3000) wird zur zentralen "Source of Truth".
-
Entwicklung:
- Sie arbeiten im Verzeichnis
/opt/gtm-engine/dev/. - Sie ändern den Code und testen ihn, indem Sie den
dev-Stack starten:cd /opt/gtm-engine/dev/ && docker compose up -d --build - Sie verifizieren die Änderungen im Browser unter
http://10.10.81.2:9090. - Wenn alles passt, committen Sie und pushen zum Gitea auf derselben Maschine:
git push.
- Sie arbeiten im Verzeichnis
-
Deployment (Release in die Produktion):
- Wechseln Sie in das Produktionsverzeichnis:
cd /opt/gtm-engine/prod/. - Holen Sie den neuen, im
dev-Zweig getesteten Code aus Gitea:git pull. - Aktualisieren Sie den Produktions-Stack:
docker compose up -d --build.
- Wechseln Sie in das Produktionsverzeichnis:
Dieser Prozess ist sicher, schnell und wiederholbar, da er nur aus Standard-Git- und Docker-Befehlen besteht.