[30388f42] Recovery & Stabilization: Restored productive core stack, implemented Docker Volumes for DB persistence, and fixed frontend build issues.

This commit is contained in:
2026-03-07 08:06:50 +00:00
parent 193b7b0e7d
commit efcaa57cf0
10 changed files with 610 additions and 225 deletions

View File

@@ -1,10 +1,5 @@
# WICHTIGER HINWEIS FÜR SPRACHMODELLE UND ENTWICKLER:
# Diese docker-compose.yml Datei ist die zentrale Orchestrierungsdatei für ALLE Docker-Services dieses Projekts.
# Es ist strengstens untersagt, Service-Definitionen, Volumes, Netzwerke oder andere Konfigurationen
# willkürlich zu löschen, auszukommentieren oder zu modifizieren, es sei denn, dies wurde
# explizit angefordert und die Auswirkungen wurden vollständig verstanden.
# Unbeabsichtigte Löschungen können zu massivem Datenverlust und Fehlfunktionen des Systems führen.
# Prüfe IMMER den gesamten Kontext der Datei und die Projektdokumentation (readme.md), bevor du Änderungen vornimmst.
version: '3.8'
@@ -17,36 +12,16 @@ services:
ports:
- "8090:80" # Synology Reverse Proxy should point to THIS port (8090)
volumes:
- ./nginx-proxy.conf:/etc/nginx/nginx.conf:ro
# Use clean config to avoid caching issues
- ./nginx-proxy-clean.conf:/etc/nginx/nginx.conf:ro
- ./.htpasswd:/etc/nginx/.htpasswd:ro
depends_on:
- company-explorer
- dashboard
- b2b-app
- market-frontend
- gtm-app
- transcription-app
- content-app
- competitor-analysis
- heatmap-frontend
# --- HEATMAP ---
heatmap-backend:
build: ./heatmap-tool/backend
container_name: heatmap-backend
restart: unless-stopped
volumes:
- ./heatmap-tool/backend:/app
- ./data:/data # Mount for database
heatmap-frontend:
build: ./heatmap-tool/frontend
container_name: heatmap-frontend
restart: unless-stopped
volumes:
- ./heatmap-tool/frontend:/app
depends_on:
- heatmap-backend
dashboard:
condition: service_started
company-explorer:
condition: service_healthy
connector-superoffice:
condition: service_healthy
# --- DASHBOARD ---
dashboard:
@@ -69,184 +44,242 @@ services:
API_USER: "admin"
API_PASSWORD: "gemini"
PYTHONUNBUFFERED: "1"
# Correct path for DB inside the mounted volume
DATABASE_URL: "sqlite:////data/companies_v3_fixed_2.db"
# Keys passed from .env
GEMINI_API_KEY: "${GEMINI_API_KEY}"
SERP_API_KEY: "${SERP_API}"
NOTION_TOKEN: "${NOTION_API_KEY}"
volumes:
- ./company-explorer:/app
- ./data:/data # Mount for database
- ./Log_from_docker:/app/logs_debug # Logging Mount
transcription-app:
build:
context: ./transcription-tool
dockerfile: Dockerfile
container_name: transcription-app
restart: unless-stopped
volumes:
- ./transcription-tool/backend:/app/backend
- ./transcription-tool/frontend/dist:/app/frontend/dist # Mount Frontend Build for Live Updates
- ./data:/data # Mount for database
- ./uploads_audio:/app/uploads_audio
environment:
PYTHONUNBUFFERED: "1"
DATABASE_URL: "sqlite:////data/transcripts.db" # Updated path for /data mount
ports:
- "8001:8001"
b2b-app:
build:
context: .
dockerfile: dockerfiles/Dockerfile.b2b
container_name: b2b-assistant
restart: unless-stopped
volumes:
- ./b2b-marketing-assistant/b2b_marketing_orchestrator.py:/app/b2b_marketing_orchestrator.py
- ./market_db_manager.py:/app/market_db_manager.py
- ./b2b-marketing-assistant/server.cjs:/app/server.cjs
- ./data:/data # Mount for database
- ./Log_from_docker:/app/Log_from_docker
environment:
PYTHONUNBUFFERED: "1"
DB_PATH: "/data/b2b_projects.db" # Updated path for /data mount
# Port 3002 is internal only
market-backend:
build:
context: .
dockerfile: dockerfiles/Dockerfile.market
container_name: market-backend
restart: unless-stopped
volumes:
- ./general-market-intelligence/market_intel_orchestrator.py:/app/general-market-intelligence/market_intel_orchestrator.py
- ./market_db_manager.py:/app/market_db_manager.py
- ./config.py:/app/config.py
- ./helpers.py:/app/helpers.py # Helper is in root, should be mounted as file
- ./general-market-intelligence/server.cjs:/app/general-market-intelligence/server.cjs
- ./data:/data # Mount for database
- ./Log:/app/Log
environment:
PYTHONUNBUFFERED: "1"
DB_PATH: "/data/market_intelligence.db" # Updated path for /data mount
# Port 3001 is internal only
market-frontend:
build:
context: ./general-market-intelligence
dockerfile: Dockerfile
container_name: market-frontend
restart: unless-stopped
depends_on:
- market-backend
# Port 80 is internal only
gtm-app:
build:
context: .
dockerfile: gtm-architect/Dockerfile
container_name: gtm-app
restart: unless-stopped
volumes:
- ./gtm-architect:/app/gtm-architect
- ./gtm-architect/server.cjs:/app/server.cjs
- ./gtm-architect/gtm_architect_orchestrator.py:/app/gtm_architect_orchestrator.py
- ./helpers.py:/app/helpers.py # Helper is in root, should be mounted as file
- ./config.py:/app/config.py
- ./gtm_db_manager.py:/app/gtm_db_manager.py
- ./data:/data # Mount for database
- ./Log_from_docker:/app/Log_from_docker
environment:
PYTHONUNBUFFERED: "1"
DB_PATH: "/data/gtm_projects.db" # Updated path for /data mount
# Port 3005 is internal only
content-app:
build:
context: .
dockerfile: content-engine/Dockerfile
container_name: content-app
restart: unless-stopped
volumes:
- ./content-engine:/app/content-engine
- ./content-engine/server.cjs:/app/server.cjs
- ./content-engine/content_orchestrator.py:/app/content-engine/content_orchestrator.py
- ./content-engine/content_db_manager.py:/app/content-engine/content_db_manager.py
- ./data:/data # Mount for database
- ./helpers.py:/app/helpers.py # Helper is in root, should be mounted as file
- ./config.py:/app/config.py
- ./data/gtm_projects.db:/data/gtm_projects.db # GTM DB also mounted here
- ./Log_from_docker:/app/Log_from_docker
environment:
PYTHONUNBUFFERED: "1"
DB_PATH: "/data/content_engine.db" # Updated path for /data mount
GTM_DB_PATH: "/data/gtm_projects.db" # Updated path for /data mount
competitor-analysis:
build:
context: ./competitor-analysis-app
dockerfile: Dockerfile
container_name: competitor-analysis
restart: unless-stopped
dns:
- 8.8.8.8
- 8.8.4.4
volumes:
- ./competitor-analysis-app/competitor_analysis_orchestrator.py:/app/competitor-analysis-app/competitor_analysis_orchestrator.py # Explicit path
- ./data:/data # Mount for database (if needed by orchestrator)
- ./Log_from_docker:/app/Log_from_docker
environment:
PYTHONUNBUFFERED: "1"
# GEMINI_API_KEY_FILE: "/app/gemini_api_key.txt" # Removed, API keys from .env
# Port 8000 is internal only
# Mount named volume to a DIRECTORY, not a file
- explorer_db_data:/data
- ./Log_from_docker:/app/logs_debug
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/docs"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
connector-superoffice:
build:
context: .
dockerfile: connector-superoffice/Dockerfile # Build context is now root
context: ./connector-superoffice
dockerfile: Dockerfile
container_name: connector-superoffice
restart: unless-stopped
ports:
- "8003:8000" # Expose internal 8000 to host 8003 (8002 was taken)
- "8003:8000" # Expose internal 8000 to host 8003
volumes:
- ./connector-superoffice:/app/connector-superoffice # Mount subfolder to its own path in /app
- ./data:/data # Data mount
- ./config.py:/app/config.py # Root config needs to be mounted
- ./helpers.py:/app/helpers.py # Root helper needs to be mounted
- ./connector-superoffice:/app
# Mount named volume to a DIRECTORY matching the Python code's expectation
- connector_db_data:/data
environment:
PYTHONUNBUFFERED: "1"
API_USER: "admin"
API_PASSWORD: "gemini"
DB_PATH: "/data/connector_queue.db" # Updated path for /data mount
# Correct path for DB inside the mounted volume
DB_PATH: "/app/data/connector_queue.db"
COMPANY_EXPLORER_URL: "http://company-explorer:8000"
# Pass through SO credentials from host .env
# Keys passed from .env
GEMINI_API_KEY: "${GEMINI_API_KEY}"
SO_CLIENT_ID: "${SO_CLIENT_ID}"
SO_CLIENT_SECRET: "${SO_CLIENT_SECRET}"
SO_REFRESH_TOKEN: "${SO_REFRESH_TOKEN}"
SO_ENVIRONMENT: "${SO_ENVIRONMENT}"
SO_CONTEXT_IDENTIFIER: "${SO_CONTEXT_IDENTIFIER}"
# Webhook Security
WEBHOOK_TOKEN: "${WEBHOOK_TOKEN}"
# Mappings
VERTICAL_MAP_JSON: "${VERTICAL_MAP_JSON}"
PERSONA_MAP_JSON: "${PERSONA_MAP_JSON}"
# User Defined Fields (UDFs)
UDF_SUBJECT: "${UDF_SUBJECT}"
UDF_INTRO: "${UDF_INTRO}"
UDF_SOCIAL_PROOF: "${UDF_SOCIAL_PROOF}"
UDF_OPENER: "${UDF_OPENER}"
UDF_OPENER_SECONDARY: "${UDF_OPENER_SECONDARY}"
UDF_VERTICAL: "${UDF_VERTICAL}"
UDF_CAMPAIGN: "${UDF_CAMPAIGN}"
UDF_UNSUBSCRIBE_LINK: "${UDF_UNSUBSCRIBE_LINK}"
UDF_SUMMARY: "${UDF_SUMMARY}"
UDF_LAST_UPDATE: "${UDF_LAST_UPDATE}"
UDF_LAST_OUTREACH: "${UDF_LAST_OUTREACH}"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
# --- INFRASTRUCTURE SERVICES ---
duckdns:
image: lscr.io/linuxserver/duckdns:latest
container_name: duckdns
environment:
PUID: "1000" # User ID (anpassen falls nötig)
PGID: "1000" # Group ID (anpassen falls nötig)
TZ: "Europe/Berlin"
SUBDOMAINS: "floke,floke-ai,floke-gitea,floke-ha,floke-n8n"
TOKEN: "${DUCKDNS_TOKEN}" # From .env
restart: unless-stopped
# --- DISABLED SERVICES (Commented out but preserved) ---
# heatmap-backend:
# build: ./heatmap-tool/backend
# container_name: heatmap-backend
# restart: unless-stopped
# volumes:
# - ./heatmap-tool/backend:/app
dns-monitor:
image: alpine
container_name: dns-monitor
dns:
- 8.8.8.8
- 1.1.1.1
environment:
SUBDOMAINS: "floke,floke-ai,floke-gitea,floke-ha,floke-n8n"
TZ: "Europe/Berlin"
volumes:
- ./dns-monitor:/app
command: "/app/monitor.sh"
restart: unless-stopped
# heatmap-frontend:
# build: ./heatmap-tool/frontend
# container_name: heatmap-frontend
# restart: unless-stopped
# volumes:
# - ./heatmap-tool/frontend:/app
# depends_on:
# - heatmap-backend
# transcription-app:
# build:
# context: ./transcription-tool
# dockerfile: Dockerfile
# container_name: transcription-app
# restart: unless-stopped
# volumes:
# - ./transcription-tool/backend:/app/backend
# - ./transcription-tool/frontend/dist:/app/frontend/dist
# - ./transcripts.db:/app/transcripts.db
# - ./uploads_audio:/app/uploads_audio
# environment:
# PYTHONUNBUFFERED: "1"
# DATABASE_URL: "sqlite:////app/transcripts.db"
# GEMINI_API_KEY: "${GEMINI_API_KEY}"
# ports:
# - "8001:8001"
# b2b-app:
# build:
# context: ./b2b-marketing-assistant
# dockerfile: Dockerfile
# container_name: b2b-assistant
# restart: unless-stopped
# volumes:
# - ./b2b_marketing_orchestrator.py:/app/b2b_marketing_orchestrator.py
# - ./market_db_manager.py:/app/market_db_manager.py
# - ./b2b-marketing-assistant/server.cjs:/app/server.cjs
# - ./b2b_projects.db:/app/b2b_projects.db
# - ./Log_from_docker:/app/Log_from_docker
# environment:
# PYTHONUNBUFFERED: "1"
# DB_PATH: "/app/b2b_projects.db"
# GEMINI_API_KEY: "${GEMINI_API_KEY}"
# market-backend:
# build:
# context: ./general-market-intelligence
# dockerfile: Dockerfile
# container_name: market-backend
# restart: unless-stopped
# volumes:
# - ./market_intel_orchestrator.py:/app/market_intel_orchestrator.py
# - ./market_db_manager.py:/app/market_db_manager.py
# - ./config.py:/app/config.py
# - ./helpers.py:/app/helpers.py
# - ./general-market-intelligence/server.cjs:/app/general-market-intelligence/server.cjs
# - ./market_intelligence.db:/app/market_intelligence.db
# - ./Log:/app/Log
# environment:
# PYTHONUNBUFFERED: "1"
# DB_PATH: "/app/market_intelligence.db"
# GEMINI_API_KEY: "${GEMINI_API_KEY}"
# SERPAPI_KEY: "${SERPAPI_KEY}"
# market-frontend:
# build:
# context: ./general-market-intelligence
# dockerfile: Dockerfile
# container_name: market-frontend
# restart: unless-stopped
# depends_on:
# - market-backend
# gtm-app:
# build:
# context: ./gtm-architect
# dockerfile: Dockerfile
# container_name: gtm-app
# restart: unless-stopped
# volumes:
# - ./gtm-architect:/app/gtm-architect
# - ./gtm-architect/server.cjs:/app/server.cjs
# - ./gtm_architect_orchestrator.py:/app/gtm_architect_orchestrator.py
# - ./helpers.py:/app/helpers.py
# - ./config.py:/app/config.py
# - ./gtm_db_manager.py:/app/gtm_db_manager.py
# - ./gtm_projects.db:/app/gtm_projects.db
# - ./Log_from_docker:/app/Log_from_docker
# environment:
# PYTHONUNBUFFERED: "1"
# DB_PATH: "/app/gtm_projects.db"
# GEMINI_API_KEY: "${GEMINI_API_KEY}"
# SERPAPI_KEY: "${SERPAPI_KEY}"
# content-app:
# build:
# context: ./content-engine
# dockerfile: Dockerfile
# container_name: content-app
# restart: unless-stopped
# volumes:
# - ./content-engine:/app/content-engine
# - ./content-engine/server.cjs:/app/server.cjs
# - ./content-engine/content_orchestrator.py:/app/content_orchestrator.py
# - ./content-engine/content_db_manager.py:/app/content_db_manager.py
# - ./content_engine.db:/app/content_engine.db
# - ./helpers.py:/app/helpers.py
# - ./config.py:/app/config.py
# - ./gtm_projects.db:/app/gtm_projects.db
# - ./Log_from_docker:/app/Log_from_docker
# environment:
# PYTHONUNBUFFERED: "1"
# DB_PATH: "/app/content_engine.db"
# GTM_DB_PATH: "/app/gtm_projects.db"
# GEMINI_API_KEY: "${GEMINI_API_KEY}"
# SERPAPI_KEY: "${SERPAPI_KEY}"
# competitor-analysis:
# build:
# context: ./competitor-analysis-app
# dockerfile: Dockerfile
# container_name: competitor-analysis
# restart: unless-stopped
# dns:
# - 8.8.8.8
# - 8.8.4.4
# volumes:
# - ./competitor-analysis-app/competitor_analysis_orchestrator.py:/app/competitor_analysis_orchestrator.py
# - ./Log_from_docker:/app/Log_from_docker
# environment:
# PYTHONUNBUFFERED: "1"
# GEMINI_API_KEY: "${GEMINI_API_KEY}"
# duckdns:
# image: lscr.io/linuxserver/duckdns:latest
# container_name: duckdns
# environment:
# PUID: "1000" # User ID (anpassen falls nötig)
# PGID: "1000" # Group ID (anpassen falls nötig)
# TZ: "Europe/Berlin"
# SUBDOMAINS: "floke,floke-ai,floke-gitea,floke-ha,floke-n8n"
# TOKEN: "2e073b27-971e-4847-988c-73ad23e648d4" # Actual token is in .env or config
# restart: unless-stopped
# dns-monitor:
# image: alpine
# container_name: dns-monitor
# dns:
# - 8.8.8.8
# - 1.1.1.1
# environment:
# SUBDOMAINS: "floke,floke-ai,floke-gitea,floke-ha,floke-n8n"
# TZ: "Europe/Berlin"
# volumes:
# - ./dns-monitor:/app
# command: "/app/monitor.sh"
# restart: unless-stopped
volumes:
moltbot_data: {} # Volume for moltbot data, even if service is commented out.
# moltbot_data: {}
connector_db_data: {}
explorer_db_data: {}