[30388f42] Documentation Update: Refined RELOCATION.md with 1:1 instructions for Monday's migration based on today's lessons learned (DB schema, Echo Shield, Streamlit Proxy).

This commit is contained in:
2026-03-07 14:10:59 +00:00
parent d1b77fd2f6
commit 2ccd5eb89c

View File

@@ -1,102 +1,82 @@
### **Anforderungsdokument (Version 2): Docker-Migration von Synology nach Ubuntu VM (`docker1`)**
### **Anforderungsdokument (Version 3): Docker-Migration nach Ubuntu VM (`docker1`)**
**Zweck:** Dieses Dokument listet alle notwendigen Port-Freigaben und Netzwerk-Anforderungen für den Umzug des internen Docker-Anwendungsstacks auf die neue VM `docker1` (IP: `10.10.81.2`). Diese Version basiert auf der Analyse aller aktiven Docker-Container vom Quellsystem.
**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)**
Die folgenden Ports müssen auf der Firewall für den eingehenden Verkehr zur VM `10.10.81.2` geöffnet werden.
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 (Container) | Zweck / Beschreibung | Kritikalität |
| Host-Port | Ziel-Dienst | Zugriff | Zweck |
| :--- | :--- | :--- | :--- |
| **3000** | `gitea` | **Gitea Web UI.** Zugriff auf die Weboberfläche des Git-Servers. | **Hoch** |
| **2222** | `gitea` | **Gitea Git via SSH.** Ermöglicht `git clone`, `push`, `pull` über SSH. (Auf dem Altsystem Port `32768`, wird hier auf einen Standard-Port gelegt). | **Hoch** |
| **8090** | `gateway_proxy` (Nginx) | **Zentraler App-Hub.** Reverse-Proxy, der den Zugriff auf alle Web-Anwendungen (Dashboard, B2B, Market-Intel etc.) steuert und mit Passwort schützt. | **Hoch** |
| **8003** | `connector-superoffice` | **SuperOffice Webhook-Empfänger.** Muss aus dem Internet (von SuperOffice-Servern) erreichbar sein. | **Hoch** |
| **8501** | `lead-engine` | **Lead Engine UI.** Web-Interface der Lead Engine (Streamlit). | **Mittel** |
| **8004** | `lead-engine` (API) | **Lead Engine API.** Für externe Integrationen wie Kalender/Buchungs-Links. | **Mittel** |
| **8002** | `heatmap-tool-backend` | **Heatmap Tool Backend.** API für das Heatmap-Visualisierungs-Tool. | **Niedrig** |
| **5173** | `heatmap-tool-frontend` | **Heatmap Tool Frontend.** Direktzugriff auf die UI des Heatmap-Tools (typ. für Entwicklung). | **Niedrig** |
**Empfehlung:** Der gesamte externe Zugriff sollte idealerweise über einen vorgeschalteten, von der IT verwalteten Reverse-Proxy mit SSL-Terminierung (HTTPS) laufen, um die Sicherheit zu erhöhen.
| **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. |
| **8004** | `lead-engine` | **Public** | Lead Engine API (für Buchungs-Links). |
---
#### **Teil 2: Interne Port-Nutzung (Host-System)**
#### **Teil 2: Netzwerk-Architektur (Intern)**
Die folgenden Ports werden von den Docker-Containern auf dem Host-System (`docker1`) belegt. Sie müssen **nicht extern** freigegeben werden, aber sie dürfen auf dem Host nicht von anderen Diensten belegt sein.
| Host-Port | Ziel-Dienst (Container) | Zweck |
| :--- | :--- | :--- |
| `8000` | `company-explorer` | Haupt-API für Unternehmensdaten, wird vom App-Hub (`gateway_proxy`) genutzt. |
| `8001` | `transcription-app` | API und UI für das Transkriptions-Tool, wird vom App-Hub genutzt. |
* **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 `.env` nötig, solange `SO_CLIENT_ID` passt.
---
#### **Teil 3: Externe Service-Abhängigkeiten (Ausgehender Verkehr)**
# ⚠️ Kritische Lehren (Post-Mortem 07.03.2026)
Die VM muss in der Lage sein, ausgehende Verbindungen zu den folgenden externen Diensten aufzubauen.
Der Umzug am Montag muss zwingend diese Punkte beachten, um den "Totalausfall" von heute zu vermeiden:
| Dienst | Zweck | Protokoll/Port |
| :--- | :--- | :--- |
| **SuperOffice API** | CRM-Synchronisation | HTTPS / 443 |
| **Google APIs** | SerpAPI, Gemini AI | HTTPS / 443 |
| **Notion API** | Wissensdatenbank-Sync | HTTPS / 443 |
| **DuckDNS** | Dynamisches DNS | HTTPS / 443 |
| **GitHub / Docker Hub / etc.** | Herunterladen von Docker-Images, Software-Paketen | HTTPS / 443 |
| **Öffentliche DNS-Server** | Namensauflösung (z.B. 8.8.8.8) | DNS / 53 (UDP/TCP) |
### 1. Datenbank-Schema-Falle
**Problem:** Alte `.db`-Dateien (Backups) haben oft nicht alle Spalten, die der aktuelle Code erwartet.
**Lösung:** Nach dem Starten der Container auf der neuen VM **muss** das Migrations-Skript ausgeführt werden:
```bash
docker exec -it company-explorer python /app/fix_missing_columns.py
```
*Dies repariert Tabellen für Companies, Industries und Contacts (inkl. Unsubscribe-Tokens).*
### 2. Docker Volumes vs. Bind Mounts
**Regel:** Datenbanken werden **NIEMALS** mehr direkt auf einen Host-Pfad gemountet.
**Grund:** Permission-Errors und SQLite-Locks ("Database is locked") auf Netzwerk-Dateisystemen (Synology/NFS).
**Vorgehen:** Nutzung von benannten Volumes (`explorer_db_data`, `connector_db_data`, `lead_engine_data`).
### 3. Daten-Injektion (Der "Rescue"-Befehl)
Um bestehende Daten in die neuen Volumes zu bekommen, nutzt man diesen Befehl:
```bash
# Beispiel für den Company Explorer
docker cp ./my_local_backup.db company-explorer:/data/companies_v3_fixed_2.db
```
### 4. Streamlit Proxy-Konfiguration
**Problem:** Streamlit (Lead Engine) verliert die Verbindung unter Sub-Pfaden (`/lead/`).
**Lösung:**
* Dockerfile: `--server.baseUrlPath=/lead` ist Pflicht.
* Nginx: `proxy_http_version 1.1` und `Upgrade`-Header müssen gesetzt sein.
---
#### **Teil 4: Netzwerk-Architektur & Kommunikation (Intern)**
### **Verbindlicher Migrationsplan (Montag)**
* **Inter-Container-Kommunikation:** Alle Container sind über ein internes Docker-Bridge-Netzwerk verbunden. Sie können sich gegenseitig über ihre Dienstnamen erreichen (z.B. `connector-superoffice` kann `company-explorer` über `http://company-explorer:8000` erreichen).
* **Keine speziellen Netzwerkregeln:** Es sind keine komplexen internen Firewall-Regeln zwischen den Containern erforderlich. Die Kommunikation innerhalb des Docker-Netzwerks sollte uneingeschränkt möglich sein.
---
# ⚠️ Post-Mortem & Kritische Lehren (März 2026)
**Hintergrund:**
Am 07.03.2026 führte ein Versuch, das Legacy-System auf der Synology für die Migration "aufzuräumen", zu massiver Instabilität und temporärem Datenverlust.
**Identifizierte Fehlerquellen ("Root Causes"):**
1. **Destruktive Bereinigung:** `git clean -fdx` löschte untracked Datenbanken.
2. **Dateisystem-Inkompatibilität:** Bind Mounts auf Synology führten zu Berechtigungsfehlern ("Database Locked").
3. **Fehlende Isolation:** Änderungen wurden am "lebenden Objekt" vorgenommen.
**Erfolgreiche Stabilisierung (Status Quo):**
* **Docker Volumes:** Alle Datenbanken laufen jetzt auf benannten Docker-Volumes (`connector_db_data`, `explorer_db_data`). Bind Mounts sind Geschichte.
* **Healthchecks:** Nginx wartet nun korrekt auf die Gesundheit der Backend-Services.
* **Environment:** Alle Secrets kommen aus der `.env`, keine Key-Files mehr im Repo.
* **Daten:** Die `companies_v3_fixed_2.db` konnte via Synology Drive Versioning wiederhergestellt und per `docker cp` injiziert werden.
**Neue Richtlinien für die Migration ("Never Again Rules"):**
1. **Immutable Infrastructure:** Wir ändern **NICHTS** mehr an der Konfiguration auf der Synology. Der dortige Stand ist eingefroren.
2. **Code-Only Transfer:** Die neue Umgebung auf `docker1` wird ausschließlich durch `git clone` aufgebaut.
3. **Docker Volumes Only:** Datenbanken werden **niemals** mehr direkt auf das Host-Dateisystem gemountet.
4. **Environment Isolation:** Secrets existieren ausschließlich in der `.env` Datei.
---
### **Revidierter Migrationsplan (Clean Slate)**
**Phase 1: Code & Config Freeze (Abgeschlossen)**
- [x] `docker-compose.yml` reparieren (Named Volumes, Healthchecks, Env Vars).
- [x] Dockerfiles reparieren (PostCSS/Tailwind Build-Fehler behoben).
- [x] `.env.example` erstellt.
- [x] Nginx Konfiguration stabilisiert.
**Phase 1: Vorbereitung**
1. [ ] **`git push`** auf Synology (aktuellster Stand d1b77fd2).
2. [ ] **`.env` Datei sichern** (enthält alle heute stabilisierten Keys!).
**Phase 2: Deployment auf `docker1`**
1. Repository klonen: `git clone <repo-url> /opt/gtm-engine`
2. Environment einrichten: `cp .env.example .env` und echte Werte eintragen.
3. Starten: `docker compose up -d --build`
4. **Datenimport (Optional):** Falls nötig, Datenbanken via `docker cp` in die Volumes kopieren.
1. [ ] Repo klonen: `git clone ... /opt/gtm-engine`
2. [ ] `.env` anlegen und befüllen.
3. [ ] Starten: `docker compose up -d --build`
4. [ ] **Schema-Check:** `docker exec -it company-explorer python /app/fix_missing_columns.py` ausführen.
**Phase 3: Datenrettung (Falls nötig)**
1. [ ] Datenbank-Dumps vom Wochenende via `docker cp` in die Volumes schieben.
2. [ ] Webhook-Status prüfen: `docker exec -it connector-superoffice python /app/register_webhook.py`.
---
### **Aktuelle Offene Todos (Priorisiert)**
1. **UI Styling:** Das Frontend des Company Explorers hat keine Stylesheets (PostCSS temporär deaktiviert, um Build zu ermöglichen). Muss auf der neuen VM sauber gelöst werden.
2. **Datenverifizierung:** Prüfen, ob die wiederhergestellte Datenbank vollständig ist.
3. **Migration:** Den Umzug auf `docker1` nach dem neuen Plan durchführen.
1. **Lead Engine:** Microsoft Graph Credentials in `.env` ergänzen (401 Fehler beheben).
2. **n8n:** Workflow-Export von Synology und Import auf neuer Instanz.
3. **Styling:** Frontend-CSS im Company Explorer verifizieren (Build läuft wieder, aber UI-Check nötig).