Files
michaelschiemer/docs/deployment/staging-database-connection-analysis.md
Michael Schiemer 12afbe874d refactor(container): simplify Redis pool initialization flow
- Remove redundant `$container` parameter in `RedisPoolInitializer` instantiation.
- Streamline container interactions for improved clarity and maintainability.
2025-11-04 02:43:45 +01:00

6.0 KiB

Analyse: Datenbankverbindung im staging-app Container

Datum: 2025-11-04
Problem: staging-app Container kann nicht zur Datenbank verbinden
Fehlermeldung: could not translate host name "postgres" to address: Name or service not known

Problem-Identifikation

Symptom

Der staging-app Container schl?gt fehl mit folgendem Fehler:

[2025-11-04 01:32:28] [ERROR] appConsoleHandler --- Failed to invoke initializer method __invoke for class App\Framework\Database\ConnectionInitializer: Failed to connect to database 'michaelschiemer' on 'postgres': SQLSTATE[08006] [7] could not translate host name "postgres" to address: Name or service not known

Root Cause Analysis

1. Fehlender PostgreSQL-Service im Staging-Setup

Problem: In docker-compose.staging.yml wird DB_HOST=${DB_HOST:-postgres} konfiguriert (Zeilen 32, 357, 412), aber es existiert kein PostgreSQL-Service mit dem Namen postgres im Staging-Setup.

Beweis:

  • docker-compose.staging.yml Zeile 32: DB_HOST=${DB_HOST:-postgres}
  • docker-compose.staging.yml Zeilen 456-458: Der db Service aus docker-compose.base.yml wird explizit deaktiviert:
    db:
      profiles:
        - never
    

2. Netzwerk-Isolation

Problem: Der staging-app Container ist nur im staging-internal Netzwerk (Zeile 18), aber es gibt keinen Datenbank-Service in diesem Netzwerk.

Netzwerk-Konfiguration:

  • staging-app: Netzwerk staging-internal (Zeile 18)
  • staging-redis: Netzwerk staging-internal (Zeile 302)
  • Kein PostgreSQL-Service im staging-internal Netzwerk

3. Vergleich mit Production-Setup

Production (docker-compose.production.yml):

  • Zeile 154-196: db Service ist definiert und aktiv
  • db Service ist im backend Netzwerk (aus docker-compose.base.yml)
  • PHP-Services k?nnen sich mit DB_HOST=postgres verbinden, da der Service existiert

Staging (docker-compose.staging.yml):

  • Zeilen 456-458: db Service wird deaktiviert
  • Kein PostgreSQL-Service definiert
  • Services versuchen trotzdem, sich mit postgres zu verbinden

Detaillierte Analyse der Konfiguration

Staging-Services, die DB_HOST verwenden

  1. staging-app (Zeile 13-205)

    • DB_HOST=${DB_HOST:-postgres} (Zeile 32)
    • Netzwerk: staging-internal
  2. staging-queue-worker (Zeile 346-399)

    • DB_HOST=${DB_HOST:-postgres} (Zeile 357)
    • Netzwerk: staging-internal
  3. staging-scheduler (Zeile 401-447)

    • DB_HOST=${DB_HOST:-postgres} (Zeile 412)
    • Netzwerk: staging-internal

Fehlende Komponenten

  1. PostgreSQL-Service: Nicht definiert in Staging-Konfiguration
  2. Netzwerk-Verbindung: Kein Datenbank-Service im staging-internal Netzwerk
  3. Dependencies: Keine depends_on f?r Datenbank-Service

L?sungsoptionen

Option 1: Eigener PostgreSQL-Service f?r Staging (Empfohlen)

Vorteile:

  • Vollst?ndige Isolation zwischen Staging und Production
  • Keine Abh?ngigkeit von externen Datenbanken
  • Konsistente Konfiguration mit anderen Services

Implementierung:

# In docker-compose.staging.yml hinzuf?gen:
staging-postgres:
  image: postgres:16-alpine
  container_name: staging-postgres
  restart: unless-stopped
  networks:
    - staging-internal
  environment:
    - TZ=Europe/Berlin
    - POSTGRES_DB=${DB_DATABASE:-michaelschiemer_staging}
    - POSTGRES_USER=${DB_USERNAME}
    - POSTGRES_PASSWORD_FILE=/run/secrets/db_user_password
  secrets:
    - db_user_password
  volumes:
    - staging-postgres-data:/var/lib/postgresql/data
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE:-michaelschiemer_staging}"]
    interval: 10s
    timeout: 5s
    retries: 5
    start_period: 30s

volumes:
  staging-postgres-data:
    name: staging-postgres-data

# DB_HOST in allen Services ?ndern:
- DB_HOST=staging-postgres  # statt postgres

Option 2: Externe Datenbank verwenden

Vorteile:

  • Keine zus?tzliche Container-Verwaltung
  • Kann auf bestehende Datenbank-Infrastruktur zur?ckgreifen

Nachteile:

  • Abh?ngigkeit von externer Infrastruktur
  • Netzwerk-Konfiguration komplexer (muss extern erreichbar sein)

Implementierung:

  • DB_HOST auf externe IP/Hostname setzen
  • Sicherstellen, dass staging-internal Netzwerk Zugriff hat (oder externes Netzwerk verwenden)

Option 3: Base-Service db aktivieren und umbenennen

Vorteile:

  • Nutzt bestehende Konfiguration aus docker-compose.base.yml
  • Minimaler Aufwand

Nachteile:

  • Kann Konflikte mit anderen Umgebungen geben
  • Nicht so isoliert wie Option 1

Implementierung:

# In docker-compose.staging.yml:
staging-postgres:
  extends:
    service: db
    file: docker-compose.base.yml
  container_name: staging-postgres
  networks:
    - staging-internal
  # DB_HOST auf staging-postgres ?ndern

Empfohlene L?sung

Option 1 ist die beste L?sung, weil:

  1. Vollst?ndige Isolation: Staging hat eigene Datenbank
  2. Konsistenz: Gleiche Struktur wie staging-redis
  3. Einfachheit: Alle Services im gleichen Netzwerk
  4. Wartbarkeit: Klare Struktur, leicht zu verstehen

N?chste Schritte

  1. ? Analyse abgeschlossen
  2. ? Implementierung: PostgreSQL-Service f?r Staging hinzuf?gen
  3. ? DB_HOST in allen Staging-Services auf staging-postgres ?ndern
  4. ? depends_on f?r Datenbank-Service hinzuf?gen
  5. ? Volume f?r PostgreSQL-Daten definieren
  6. ? Testing: Verbindung testen nach Implementierung

Zus?tzliche ?berlegungen

Netzwerk-Architektur

  • staging-internal: Interne Services (app, postgres, redis, queue-worker, scheduler)
  • traefik-public: Externes Netzwerk f?r Traefik (nur staging-nginx)

Sicherheit

  • Docker Secrets f?r Datenbank-Passwort verwenden (bereits konfiguriert)
  • Keine Ports nach au?en f?r PostgreSQL (nur intern)
  • Gesundheitschecks f?r Datenbank-Service

Performance

  • PostgreSQL-Volumes f?r Persistenz
  • Gesundheitschecks f?r alle Services
  • depends_on mit condition: service_healthy f?r Datenbank