Files
michaelschiemer/docs/guides/configuration.md
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

7.9 KiB

Configuration Best Practices

Leitlinien für effektives Configuration Management im Custom PHP Framework.

Problem: .env Bloat

Symptom: Zunehmende Anzahl von Environment-Variablen in .env.example

Negative Auswirkungen:

  • Schwer zu überschauen, welche Variablen wirklich wichtig sind
  • Viele Parameter, die Entwickler nie ändern werden
  • Unklare Defaults für optionale Parameter
  • Erhöhter Wartungsaufwand

Lösung: Sensible Defaults + Minimal Configuration

Prinzip 1: "Convention over Configuration"

Regel: Nur Werte, die Entwickler WIRKLICH ändern müssen oder wollen, gehören in .env

Gute .env Kandidaten:

  • Credentials (DB_PASSWORD, API_KEYS)
  • Umgebungs-spezifische Werte (APP_ENV, APP_URL)
  • Infrastruktur-Konfiguration (DB_HOST, REDIS_HOST)
  • Feature Toggles für Production (APP_DEBUG)

Schlechte .env Kandidaten:

  • Performance Tuning Parameter (CACHE_TTL=60)
  • Interne Framework-Defaults (CACHE_SIZE=100)
  • Rarely Changed Feature Flags (FEATURE_ENABLED=true)
  • Debug-only Flags (VERBOSE_LOGGING=false)

Prinzip 2: Sensible Defaults im Code

Vor der Refaktorierung (4 .env Variablen):

FILESYSTEM_VALIDATOR_CACHE=true          # Rarely disabled
FILESYSTEM_VALIDATOR_CACHE_TTL=60       # Never changed
FILESYSTEM_VALIDATOR_CACHE_SIZE=100     # Never changed
FILESYSTEM_STORAGE_CACHE=true           # Rarely disabled

Nach der Refaktorierung (1 .env Variable):

# Filesystem Performance (caching enabled by default)
# Set to true only for debugging performance issues
# FILESYSTEM_DISABLE_CACHE=false

Im Code (FilesystemInitializer.php):

// Sensible defaults hardcoded
$disableCache = filter_var($_ENV['FILESYSTEM_DISABLE_CACHE'] ?? 'false', FILTER_VALIDATE_BOOLEAN);

if ($disableCache) {
    return $validator;
}

return new CachedFileValidator(
    validator: $validator,
    cacheTtl: 60,        // Sensible default: 1 minute
    maxCacheSize: 100    // Sensible default: 100 entries
);

Vorteile:

  • 75% weniger .env Variablen (4 → 1)
  • Klarere Intention: "disable only for debugging"
  • Production-optimized by default
  • Einfacher für neue Entwickler

Prinzip 3: Opt-Out statt Opt-In für Performance

Schlechtes Pattern (Opt-In):

FEATURE_CACHE=false  # Muss explizit aktiviert werden

→ Entwickler vergessen es zu aktivieren → Performance-Probleme

Gutes Pattern (Opt-Out):

# FEATURE_DISABLE_CACHE=false  # Caching standardmäßig aktiv

→ Production-optimiert by default → Explizit deaktivieren nur für Debugging

Prinzip 4: Gruppierung und Kommentare

Schlechtes Beispiel:

CACHE_ENABLED=true
CACHE_TTL=60
CACHE_SIZE=100
DB_CACHE=true
FILE_CACHE=true
API_CACHE=true

Gutes Beispiel:

# Cache System (optimized by default)
# Disable only for debugging: DISABLE_ALL_CACHES=true
# DISABLE_ALL_CACHES=false

# Database-specific cache tuning (advanced)
# DB_CACHE_TTL=3600

Refactoring-Strategie

Schritt 1: Identifiziere "Never Changed" Parameter

Prüfe in der Codebase:

# Suche nach $_ENV usage
grep -r "ENV\['" src/

# Identifiziere Parameter, die nie geändert werden
# Kandidaten für Hardcoding

Schritt 2: Extrahiere Sensible Defaults

Vor:

$ttl = (int) ($_ENV['CACHE_TTL'] ?? 60);
$size = (int) ($_ENV['CACHE_SIZE'] ?? 100);

Nach:

// Sensible defaults based on production experience
const DEFAULT_CACHE_TTL = 60;    // 1 minute
const DEFAULT_CACHE_SIZE = 100;  // 100 entries

$ttl = self::DEFAULT_CACHE_TTL;
$size = self::DEFAULT_CACHE_SIZE;

Vor (3 separate flags):

FILESYSTEM_VALIDATOR_CACHE=true
FILESYSTEM_STORAGE_CACHE=true
FILESYSTEM_CACHE_CLEARSTATCACHE=true

Nach (1 master flag):

# FILESYSTEM_DISABLE_CACHE=false

Im Code:

$disableCache = filter_var($_ENV['FILESYSTEM_DISABLE_CACHE'] ?? 'false', FILTER_VALIDATE_BOOLEAN);

// Affects all filesystem caching
$useValidatorCache = !$disableCache;
$useStorageCache = !$disableCache;
$optimizeClearstatcache = !$disableCache;

Schritt 4: Dokumentiere Advanced Tuning

Für Experten, die wirklich tunen wollen:

// Advanced tuning (usually not needed)
$ttl = (int) ($_ENV['FILESYSTEM_VALIDATOR_CACHE_TTL'] ?? 60);
$size = (int) ($_ENV['FILESYSTEM_VALIDATOR_CACHE_SIZE'] ?? 100);

In Dokumentation (nicht in .env.example):

## Advanced Configuration

For expert performance tuning, these environment variables can be used:

- `FILESYSTEM_VALIDATOR_CACHE_TTL`: Cache TTL in seconds (default: 60)
- `FILESYSTEM_VALIDATOR_CACHE_SIZE`: Max cache entries (default: 100)

⚠️ **Warning**: Only change these if you have measured performance issues.

Entscheidungsbaum

Braucht diese Variable in .env?
│
├─ Ist es eine Credential? → ✅ JA
├─ Ist es umgebungs-spezifisch (dev/prod)? → ✅ JA
├─ Muss es für Production geändert werden? → ✅ JA
├─ Wird es von Entwicklern oft geändert? → ✅ JA
│
└─ Ansonsten:
   ├─ Ist es ein Performance Tuning Parameter? → ❌ NEIN (Sensible Default im Code)
   ├─ Ist es ein internes Detail? → ❌ NEIN (Hardcode im Code)
   ├─ Ist es ein Debug Flag? → ⚠️ MAYBE (Opt-Out Pattern erwägen)
   └─ Ist es ein Feature Toggle? → ⚠️ MAYBE (Convention over Configuration)

.env Organisation

Empfohlene Struktur

# ============================================================
# CORE APPLICATION
# ============================================================
APP_ENV=development
APP_DEBUG=true
APP_URL=https://localhost

# ============================================================
# DATABASE
# ============================================================
DB_HOST=db
DB_PORT=5432
DB_DATABASE=michaelschiemer
DB_USERNAME=postgres
DB_PASSWORD=your_secure_password

# ============================================================
# EXTERNAL SERVICES
# ============================================================
SPOTIFY_CLIENT_ID=your_client_id
SPOTIFY_CLIENT_SECRET=your_client_secret

# ============================================================
# PERFORMANCE & DEBUGGING (optimized by default)
# ============================================================
# Uncomment only for debugging:
# FILESYSTEM_DISABLE_CACHE=false
# DISABLE_QUERY_LOG=false
# VERBOSE_ERROR_PAGES=false

Beispiele aus dem Framework

Gutes Beispiel: Filesystem Performance

Vorher (4 Variablen):

FILESYSTEM_VALIDATOR_CACHE=true
FILESYSTEM_VALIDATOR_CACHE_TTL=60
FILESYSTEM_VALIDATOR_CACHE_SIZE=100
FILESYSTEM_STORAGE_CACHE=true

Nachher (1 Variable):

# FILESYSTEM_DISABLE_CACHE=false

Einsparung: 75% weniger Variablen, gleiche Funktionalität

Anti-Pattern: Zu granulare Konfiguration

# DON'T DO THIS
ENABLE_USER_CACHE=true
USER_CACHE_TTL=60
USER_CACHE_SIZE=100
ENABLE_POST_CACHE=true
POST_CACHE_TTL=120
POST_CACHE_SIZE=200
ENABLE_COMMENT_CACHE=true
COMMENT_CACHE_TTL=30
COMMENT_CACHE_SIZE=50

Besser:

# Cache System (enabled by default with sensible defaults)
# DISABLE_ALL_CACHES=false

Im Code (wenn wirklich Tuning nötig):

// Expert tuning available via environment, but not advertised
$userCacheTtl = (int) ($_ENV['USER_CACHE_TTL'] ?? 60);
$postCacheTtl = (int) ($_ENV['POST_CACHE_TTL'] ?? 120);

Zusammenfassung

Goldene Regel: Jede .env Variable muss rechtfertigen, warum sie NICHT ein Sensible Default im Code sein kann.

Checklist für neue .env Variablen:

  • Ist es eine Credential oder Secret? → .env
  • Ist es umgebungs-spezifisch? → .env
  • Ändern Entwickler es regelmäßig? → .env
  • Ist es ein Performance Parameter? → Sensible Default im Code
  • Ist es ein Debug Flag? → Opt-Out Pattern (commented out in .env.example)
  • Ist es ein internes Detail? → Hardcode im Code, nicht konfigurierbar

Ergebnis: Übersichtliche .env.example, production-optimized by default, trotzdem flexibel für Experten.