Files
michaelschiemer/docs/deployment/local-secrets-unification-plan.md
Michael Schiemer 02e4dc9338 feat(local-secrets): introduce unified local secrets management and documentation
- Add example secret files for `app_key`, `db_user_password`, and `redis_password`.
- Introduce `local.vault.yml.example` for Ansible Vault encryption of local secrets.
- Create migration and setup scripts for transitioning from `.env.local` to secrets files.
- Update `docker-compose.local.yml` to adopt Docker Secrets and `_FILE` pattern for local configurations.
- Add deployment playbooks and enhanced logging configurations for local development.
2025-11-04 11:06:21 +01:00

13 KiB

Plan: Vereinheitlichung der lokalen Entwicklungsumgebung mit Staging/Production

Datum: 2025-11-04
Ziel: Lokale Entwicklungsumgebung auf Docker Secrets und Redis-Passwort umstellen, um Konsistenz mit Staging/Production zu erreichen

Aktuelle Situation

Lokal (docker-compose.local.yml)

  • ? Redis: Kein Passwort (nur redis.conf)
  • ? Docker Secrets: Nicht verwendet
  • ? *_FILE Pattern: Nicht verwendet
  • ? Secrets: Direkt in .env.local (plain text)

Staging/Production

  • ? Redis: Mit Passwort via Docker Secrets
  • ? Docker Secrets: Aktiviert
  • ? *_FILE Pattern: F?r alle Secrets
  • ? Framework: DockerSecretsResolver unterst?tzt automatisch *_FILE Pattern

Vorteile der Vereinheitlichung

1. Konsistenz

  • ? Gleiche Konfiguration in allen Umgebungen
  • ? Weniger ?berraschungen bei Deployment
  • ? Einfachere Fehlersuche (gleiche Konfiguration = gleiche Probleme)

2. Framework-Support

  • ? Framework unterst?tzt bereits DockerSecretsResolver
  • ? Automatisches Laden von *_FILE Pattern
  • ? Kein Code-Change n?tig - nur Konfiguration

3. Sicherheit

  • ? Bessere Praxis auch in Entwicklung
  • ? Secrets nicht in .env.local (kann versehentlich committed werden)
  • ? Dateisystem-Permissions f?r Secrets

4. Entwickler-Erfahrung

  • ? Testen mit Production-?hnlicher Konfiguration
  • ? Fr?hes Erkennen von Secrets-Problemen
  • ? Einheitliches Setup f?r alle Entwickler

Nachteile / ?berlegungen

1. Komplexit?t

  • ?? Mehr Setup-Schritte f?r neue Entwickler
  • ?? Zus?tzliche Secrets-Dateien m?ssen erstellt werden
  • ?? Lokale Secrets-Verwaltung n?tig

2. Migration

  • ?? Bestehende .env.local muss angepasst werden
  • ?? Secrets-Verzeichnis muss erstellt werden
  • ?? Dokumentation muss aktualisiert werden

Implementierungsplan

Phase 1: Secrets-Verzeichnis und Struktur

1.1 Secrets-Verzeichnis erstellen

mkdir -p secrets
chmod 700 secrets

1.2 .gitignore aktualisieren

# Secrets (lokal)
secrets/*.txt
!secrets/*.example

1.3 Beispiel-Secrets erstellen

# secrets/redis_password.txt.example
# Beispiel: local-dev-redis-password-2024

# secrets/db_user_password.txt.example
# Beispiel: local-dev-db-password-2024

# secrets/app_key.txt.example
# Beispiel: base64:local-dev-app-key-generated

Phase 2: Docker Compose Konfiguration

2.1 docker-compose.local.yml aktualisieren

Redis Service:

redis:
  secrets:
    - redis_password
  command: >
    sh -c "redis-server
    --requirepass $$(cat /run/secrets/redis_password)
    --maxmemory 256mb
    --maxmemory-policy allkeys-lru
    --save 900 1
    --save 300 10
    --save 60 10000
    --appendonly yes
    --appendfsync everysec"
  healthcheck:
    test: ["CMD", "sh", "-c", "redis-cli --no-auth-warning -a $$(cat /run/secrets/redis_password) ping"]

PHP Service:

php:
  environment:
    - REDIS_PASSWORD_FILE=/run/secrets/redis_password
    - DB_PASSWORD_FILE=/run/secrets/db_user_password
    - APP_KEY_FILE=/run/secrets/app_key
  secrets:
    - redis_password
    - db_user_password
    - app_key

Queue-Worker Service:

queue-worker:
  environment:
    - REDIS_PASSWORD_FILE=/run/secrets/redis_password
    - DB_PASSWORD_FILE=/run/secrets/db_user_password
  secrets:
    - redis_password
    - db_user_password

2.2 docker-compose.base.yml Secrets erweitern

Secrets-Sektion:

secrets:
  db_user_password:
    file: ./secrets/db_user_password.txt
    external: false
  redis_password:
    file: ./secrets/redis_password.txt
    external: false
  app_key:
    file: ./secrets/app_key.txt
    external: false

Hinweis: external: false bedeutet, dass die Dateien lokal sein m?ssen (nicht external wie in Production).

Phase 3: Redis-Konfiguration

3.1 redis.conf anpassen

Option A: redis.conf entfernt (nur Command-Line-Args) Option B: redis.conf mit requirepass (aus Secret geladen)

Empfehlung: Option A - Command-Line-Args sind flexibler und konsistenter mit Staging/Production.

3.2 redis.conf entfernen oder anpassen

# docker/redis/redis.conf
# Hinweis: Passwort wird via Command-Line-Args gesetzt (aus Docker Secret)
# requirepass wird nicht hier gesetzt, sondern via --requirepass Argument

Phase 4: Migration bestehender .env.local

4.1 Secrets aus .env.local extrahieren

# Script: scripts/migrate-env-to-secrets.sh
#!/bin/bash

SECRETS_DIR="./secrets"
mkdir -p "$SECRETS_DIR"

# Redis Password
if grep -q "REDIS_PASSWORD=" .env.local; then
    grep "REDIS_PASSWORD=" .env.local | cut -d'=' -f2 > "$SECRETS_DIR/redis_password.txt"
    chmod 600 "$SECRETS_DIR/redis_password.txt"
    echo "? Created secrets/redis_password.txt"
    # Entferne aus .env.local (kommentiere aus oder entferne)
    sed -i '/^REDIS_PASSWORD=/d' .env.local
fi

# DB Password
if grep -q "DB_PASSWORD=" .env.local; then
    grep "DB_PASSWORD=" .env.local | cut -d'=' -f2 > "$SECRETS_DIR/db_user_password.txt"
    chmod 600 "$SECRETS_DIR/db_user_password.txt"
    echo "? Created secrets/db_user_password.txt"
    sed -i '/^DB_PASSWORD=/d' .env.local
fi

# APP_KEY
if grep -q "APP_KEY=" .env.local; then
    grep "APP_KEY=" .env.local | cut -d'=' -f2 > "$SECRETS_DIR/app_key.txt"
    chmod 600 "$SECRETS_DIR/app_key.txt"
    echo "? Created secrets/app_key.txt"
    sed -i '/^APP_KEY=/d' .env.local
fi

echo "? Migration completed. Please review .env.local and remove migrated secrets."

4.2 .env.local bereinigen

  • Entferne: REDIS_PASSWORD=, DB_PASSWORD=, APP_KEY=
  • Behalte: Alle anderen Konfigurationen (DB_HOST, DB_PORT, etc.)

Phase 5: Dokumentation

5.1 ENV_SETUP.md aktualisieren

  • Lokales Setup mit Secrets dokumentieren
  • Migration-Anleitung hinzuf?gen
  • Beispiel-Secrets erw?hnen

5.2 README.md aktualisieren

  • Setup-Schritte f?r neue Entwickler
  • Secrets-Verzeichnis erstellen
  • Beispiel-Secrets kopieren

5.3 .env.example aktualisieren

  • Kommentare zu *_FILE Pattern hinzuf?gen
  • Hinweis auf Secrets-Verzeichnis

Detaillierte ?nderungen

Datei: docker-compose.local.yml

services:
  php:
    environment:
      # Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
      - DB_PASSWORD_FILE=/run/secrets/db_user_password
      - REDIS_PASSWORD_FILE=/run/secrets/redis_password
      - APP_KEY_FILE=/run/secrets/app_key
    secrets:
      - db_user_password
      - redis_password
      - app_key

  redis:
    secrets:
      - redis_password
    command: >
      sh -c "redis-server
      --requirepass $$(cat /run/secrets/redis_password)
      --maxmemory 256mb
      --maxmemory-policy allkeys-lru
      --save 900 1
      --save 300 10
      --save 60 10000
      --appendonly yes
      --appendfsync everysec"
    healthcheck:
      test: ["CMD", "sh", "-c", "redis-cli --no-auth-warning -a $$(cat /run/secrets/redis_password) ping"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

  queue-worker:
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_user_password
      - REDIS_PASSWORD_FILE=/run/secrets/redis_password
    secrets:
      - db_user_password
      - redis_password

secrets:
  db_user_password:
    file: ./secrets/db_user_password.txt
    external: false
  redis_password:
    file: ./secrets/redis_password.txt
    external: false
  app_key:
    file: ./secrets/app_key.txt
    external: false

Datei: docker-compose.base.yml

Secrets-Sektion bereits vorhanden (Zeilen 192-224), muss nur genutzt werden.

Datei: docker/redis/redis.conf

Anpassen oder entfernen:

# docker/redis/redis.conf
# Hinweis: Passwort wird via Docker Secrets geladen
# requirepass wird nicht hier gesetzt, sondern via Command-Line-Args
# In docker-compose.local.yml wird --requirepass verwendet

Migration f?r bestehende Entwickler

Schritt-f?r-Schritt Anleitung

# 1. Secrets-Verzeichnis erstellen
mkdir -p secrets
chmod 700 secrets

# 2. Secrets aus .env.local extrahieren
# Redis Password
REDIS_PASS=$(grep "^REDIS_PASSWORD=" .env.local | cut -d'=' -f2)
if [ -n "$REDIS_PASS" ]; then
    echo "$REDIS_PASS" > secrets/redis_password.txt
    chmod 600 secrets/redis_password.txt
    echo "? Created secrets/redis_password.txt"
fi

# DB Password
DB_PASS=$(grep "^DB_PASSWORD=" .env.local | cut -d'=' -f2)
if [ -n "$DB_PASS" ]; then
    echo "$DB_PASS" > secrets/db_user_password.txt
    chmod 600 secrets/db_user_password.txt
    echo "? Created secrets/db_user_password.txt"
fi

# APP_KEY
APP_KEY=$(grep "^APP_KEY=" .env.local | cut -d'=' -f2)
if [ -n "$APP_KEY" ]; then
    echo "$APP_KEY" > secrets/app_key.txt
    chmod 600 secrets/app_key.txt
    echo "? Created secrets/app_key.txt"
fi

# 3. Entferne Secrets aus .env.local (oder kommentiere aus)
sed -i '/^REDIS_PASSWORD=/d' .env.local
sed -i '/^DB_PASSWORD=/d' .env.local
sed -i '/^APP_KEY=/d' .env.local

# 4. Pr?fe Secrets
ls -la secrets/
# Sollte zeigen: redis_password.txt, db_user_password.txt, app_key.txt

# 5. Teste Konfiguration
docker compose -f docker-compose.base.yml -f docker-compose.local.yml config

# 6. Starte Container
docker compose -f docker-compose.base.yml -f docker-compose.local.yml up -d

# 7. Teste Redis-Verbindung
docker compose exec redis redis-cli --no-auth-warning -a $(cat secrets/redis_password.txt) ping
# Erwartet: PONG

Setup f?r neue Entwickler

Initial Setup Script

#!/bin/bash
# scripts/setup-local-secrets.sh

echo "?? Setting up local development secrets..."

SECRETS_DIR="./secrets"
mkdir -p "$SECRETS_DIR"
chmod 700 "$SECRETS_DIR"

# Generate Redis Password
if [ ! -f "$SECRETS_DIR/redis_password.txt" ]; then
    REDIS_PASS=$(openssl rand -base64 32)
    echo "$REDIS_PASS" > "$SECRETS_DIR/redis_password.txt"
    chmod 600 "$SECRETS_DIR/redis_password.txt"
    echo "? Generated secrets/redis_password.txt"
fi

# Generate DB Password
if [ ! -f "$SECRETS_DIR/db_user_password.txt" ]; then
    DB_PASS=$(openssl rand -base64 32)
    echo "$DB_PASS" > "$SECRETS_DIR/db_user_password.txt"
    chmod 600 "$SECRETS_DIR/db_user_password.txt"
    echo "? Generated secrets/db_user_password.txt"
    echo "??  Update DB_PASSWORD in .env.local if needed"
fi

# Generate APP_KEY (if not exists)
if [ ! -f "$SECRETS_DIR/app_key.txt" ]; then
    APP_KEY=$(php -r "echo 'base64:' . base64_encode(random_bytes(32));")
    echo "$APP_KEY" > "$SECRETS_DIR/app_key.txt"
    chmod 600 "$SECRETS_DIR/app_key.txt"
    echo "? Generated secrets/app_key.txt"
fi

echo "? Local secrets setup completed!"
echo ""
echo "?? Next steps:"
echo "1. Review secrets/*.txt files"
echo "2. Update .env.local if needed (DB_USERNAME, DB_HOST, etc.)"
echo "3. Start containers: docker compose -f docker-compose.base.yml -f docker-compose.local.yml up -d"

Vorteile dieser L?sung

1. Konsistenz

  • ? Gleiche Konfiguration in Local, Staging, Production
  • ? Framework nutzt DockerSecretsResolver ?berall
  • ? Keine Environment-spezifischen Code-Pfade

2. Sicherheit

  • ? Secrets nicht in .env.local (kann versehentlich committed werden)
  • ? Dateisystem-Permissions (600) f?r Secrets
  • ? .gitignore verhindert versehentliches Committen

3. Wartbarkeit

  • ? Einheitliche Konfiguration
  • ? Framework unterst?tzt *_FILE Pattern automatisch
  • ? Klare Trennung: Secrets vs. Konfiguration

4. Entwickler-Erfahrung

  • ? Testen mit Production-?hnlicher Konfiguration
  • ? Fr?hes Erkennen von Secrets-Problemen
  • ? Setup-Script f?r neue Entwickler

Nachteile / ?berlegungen

1. Komplexit?t

  • ?? Mehr Setup-Schritte f?r neue Entwickler
  • ?? Zus?tzliche Secrets-Dateien m?ssen verwaltet werden
  • ?? Lokale Secrets-Verwaltung n?tig

L?sung: Setup-Script automatisiert die Erstellung

2. Migration

  • ?? Bestehende .env.local muss angepasst werden
  • ?? Secrets-Verzeichnis muss erstellt werden
  • ?? Dokumentation muss aktualisiert werden

L?sung: Migration-Script unterst?tzt den ?bergang

3. Redis-Passwort lokal

  • ?? Mehr Konfiguration f?r lokale Entwicklung
  • ?? Passwort muss bekannt sein f?r Redis-CLI-Zugriff

L?sung:

  • Passwort in secrets/redis_password.txt (leicht zug?nglich lokal)
  • Helper-Script: scripts/redis-cli.sh f?r einfachen Zugriff

Alternative Ans?tze

Option A: Secrets optional machen (nicht empfohlen)

  • Redis-Passwort nur wenn Secret vorhanden
  • Komplexer, weniger konsistent

Option B: Nur Production/Staging mit Secrets (aktuell)

  • Lokal bleibt ohne Secrets
  • Nachteil: Inkonsistenz zwischen Umgebungen

Option C: Vereinheitlichung (empfohlen)

  • Alle Umgebungen nutzen Secrets
  • Vorteil: Maximale Konsistenz

Empfehlung

Vereinheitlichung (Option C) ist die beste L?sung, weil:

  1. ? Maximale Konsistenz zwischen allen Umgebungen
  2. ? Framework unterst?tzt bereits DockerSecretsResolver
  3. ? Bessere Sicherheit auch lokal
  4. ? Fr?hes Erkennen von Secrets-Problemen
  5. ? Setup-Script macht Migration einfach

N?chste Schritte

  1. ? Plan erstellt
  2. ? Diskussion: Ist Vereinheitlichung gew?nscht?
  3. ? Implementierung: docker-compose.local.yml anpassen
  4. ? Migration: Secrets aus .env.local extrahieren
  5. ? Dokumentation: ENV_SETUP.md und README.md aktualisieren
  6. ? Testing: Lokale Entwicklungsumgebung testen
  7. ? Setup-Script: scripts/setup-local-secrets.sh erstellen