# Environment Configuration Guide ## 📁 .env File Structure (Base + Override Pattern) Die neue Struktur verwendet ein **Base + Override Pattern** (analog zu docker-compose): ``` ├── .env.example # Template für neue Entwickler (vollständige Dokumentation) ├── .env.base # Gemeinsame Variablen für alle Environments (versioniert) ├── .env.local # Lokale Development-Overrides (gitignored) ├── .env.staging # Staging-spezifische Overrides (optional, gitignored) └── .env.production # Production (generiert durch Ansible, nicht im Repo) ``` ## 🏗️ Development Setup ### Initial Setup ```bash # 1. .env.base ist bereits im Repository (gemeinsame Variablen) # 2. Erstelle .env.local für lokale Overrides cp .env.example .env.local # 3. Passe .env.local an deine lokale Entwicklung an # - DB Credentials (lokal) # - API Keys (lokal) # - Debug-Flags ``` ### Framework lädt automatisch: `.env.base` → `.env.local` (Overrides) **Priorität:** 1. System Environment Variables (Docker ENV) 2. `.env.base` (gemeinsame Basis) 3. `.env.local` (lokale Overrides) 4. `.env.secrets` (verschlüsselte Secrets, optional) **Wichtig:** `env_file` in Docker Compose ist nicht nötig! - Framework lädt automatisch `.env.base` → `.env.local` via `EncryptedEnvLoader` - Docker Compose `env_file` ist optional und wird nur für Container-interne Variablen benötigt - PHP-Anwendung lädt ENV-Variablen direkt aus den Dateien **Backward Compatibility:** - Falls `.env.base` oder `.env.local` nicht existieren, wird `.env` geladen (Fallback) - Migration: Bestehende `.env` Files funktionieren weiterhin ## 🚀 Production Deployment ### Production .env Management **WICHTIG**: Production `.env` wird **NICHT** aus dem Repository deployed! ### Single Source of Truth ``` Server: /home/deploy/michaelschiemer/shared/.env.production ``` Dieser File wird von **Ansible** automatisch erstellt aus: ``` deployment/infrastructure/templates/.env.production.j2 ``` ### Production Deployment Process ```bash # Ansible Playbook erstellt automatisch die Production .env cd deployment/infrastructure ansible-playbook -i inventories/production/hosts.yml \ playbooks/deploy-rsync-based.yml \ --vault-password-file .vault_pass ``` **Ansible macht dabei**: 1. Template `.env.production.j2` rendern 2. Vault-verschlüsselte Secrets einsetzen 3. File nach `/home/deploy/michaelschiemer/shared/.env.production` deployen 4. Docker Compose mounted diesen File in Container ## 🔒 Security & Secret Management ### Docker Secrets (Production & Staging) **Production und Staging verwenden Docker Secrets:** 1. **Ansible Vault → Docker Secrets Dateien** - Ansible Playbook erstellt Secret-Dateien in `secrets/` Verzeichnis - Dateien haben sichere Permissions (0600) 2. **Docker Compose Secrets** - Secrets werden in `docker-compose.base.yml` definiert - Environment-Variablen nutzen `*_FILE` Pattern (z.B. `DB_PASSWORD_FILE=/run/secrets/db_user_password`) - Framework lädt automatisch via `DockerSecretsResolver` 3. **Framework Support** - `DockerSecretsResolver` unterstützt automatisch `*_FILE` Pattern - Kein manuelles Secret-Loading mehr nötig (wird automatisch vom Framework behandelt) ### Development ```bash # .env.local niemals committen git status # Should show: .env.local (untracked) ✅ # .env.base ist versioniert (keine Secrets!) # Falls versehentlich staged: git reset HEAD .env.local ``` ### Production - ✅ Secrets in Ansible Vault - ✅ Ansible erstellt Docker Secrets Dateien (`secrets/*.txt`) - ✅ Docker Compose Secrets aktiviert - ✅ Framework lädt automatisch via `*_FILE` Pattern - ✅ .env.production auf Server wird NICHT ins Repository committed - ✅ Template `application.env.j2` verwendet `*_FILE` Pattern ## 📝 Adding New Environment Variables ### Development ```bash # 1. Add to .env.base if shared across environments echo "NEW_API_KEY=" >> .env.base # 2. Add to .env.local for local development echo "NEW_API_KEY=abc123..." >> .env.local # 3. Update .env.example for documentation echo "NEW_API_KEY=your_api_key_here" >> .env.example ``` **Hinweis:** Wenn die Variable nur für lokale Entwicklung ist, nur in `.env.local` hinzufügen. ### Production (mit Docker Secrets) ```bash # 1. Add to Ansible Template (use *_FILE pattern for secrets) # File: deployment/ansible/templates/application.env.j2 echo "# Use Docker Secrets via *_FILE pattern" >> application.env.j2 echo "NEW_API_KEY_FILE=/run/secrets/new_api_key" >> application.env.j2 # 2. Add to docker-compose.base.yml secrets section # File: docker-compose.base.yml # secrets: # new_api_key: # file: ./secrets/new_api_key.txt # 3. Add secret to Ansible Vault ansible-vault edit deployment/ansible/secrets/production.vault.yml # Add: vault_new_api_key: "production_value" # 4. Update setup-production-secrets.yml to create secret file # File: deployment/ansible/playbooks/setup-production-secrets.yml # Add to loop: # - name: new_api_key # value: "{{ vault_new_api_key }}" # 5. Deploy cd deployment/ansible ansible-playbook -i inventory/production.yml \ playbooks/setup-production-secrets.yml \ --vault-password-file .vault_pass ``` ### Production (ohne Docker Secrets, fallback) Falls Docker Secrets nicht verwendet werden sollen: ```bash # 1. Add to Ansible Template # File: deployment/ansible/templates/application.env.j2 echo "NEW_API_KEY={{ vault_new_api_key }}" >> application.env.j2 # 2. Add secret to Ansible Vault ansible-vault edit deployment/ansible/secrets/production.vault.yml # Add: vault_new_api_key: "production_value" # 3. Deploy cd deployment/ansible ansible-playbook -i inventory/production.yml \ playbooks/deploy-update.yml ``` ## 🗑️ Removed Files (Consolidation 27.10.2024) Diese Files wurden gelöscht, da sie redundant/nicht verwendet wurden: ``` ❌ .env.production (Root - redundant) ❌ .env.production.example (Root - nicht verwendet) ❌ .env.backup.20250912_133135 (Altes Backup) ❌ .env.analytics.example (In .env.example integriert) ❌ .env.secrets.example (In .env.example integriert) ❌ deployment/applications/environments/ (Gesamtes Directory gelöscht) ``` ## ✅ Current State ### Local Development - ✅ Base File: `.env.base` (versioniert, gemeinsame Variablen) - ✅ Override File: `.env.local` (gitignored, lokale Anpassungen) - ✅ Template: `.env.example` (Dokumentation) - ✅ Framework lädt automatisch: `.env.base` → `.env.local` (Overrides) ### Production - ✅ Single Source: `/home/deploy/michaelschiemer/shared/.env.production` (auf Server) - ✅ Verwaltet durch: Ansible Template `application.env.j2` - ✅ Secrets: Docker Secrets (`secrets/*.txt` Dateien) - ✅ Framework lädt automatisch via `*_FILE` Pattern (`DockerSecretsResolver`) - ✅ Keine Duplikate ### Staging - ✅ Docker Compose Environment Variables - ✅ Docker Secrets aktiviert (wie Production) - ✅ Optional: `.env.staging` für Staging-spezifische Overrides ## 🔍 Verification ```bash # Check local .env files ls -la .env* # Should show: .env.base (versioniert), .env.local (gitignored), .env.example # Check Ansible template exists ls -la deployment/ansible/templates/application.env.j2 # Should exist # Check Docker Secrets files exist (on server) ls -la {{ app_stack_path }}/secrets/ # Should show: db_user_password.txt, redis_password.txt, app_key.txt, etc. # Check NO old files remain find . -name ".env.production" -o -name ".env.*.example" | grep -v .env.example | grep -v .env.base # Should be empty ``` ## 📞 Support Bei Fragen zum .env Setup: - Development: Siehe `.env.base` (gemeinsame Variablen) und `.env.example` (Dokumentation) - Production: Siehe `deployment/ansible/templates/application.env.j2` - Secrets: Docker Secrets aktiviert, verwaltet durch Ansible Vault - Migration: Framework unterstützt Fallback auf `.env` (alte Struktur) ## 🔄 Migration von alter Struktur **Von `.env` zu `.env.base` + `.env.local`:** ```bash # 1. Erstelle .env.base (gemeinsame Variablen extrahieren) # (wird automatisch vom Framework erkannt) # 2. Erstelle .env.local (nur lokale Overrides) cp .env .env.local # 3. Entferne gemeinsame Variablen aus .env.local # (nur lokale Anpassungen behalten) # 4. Alte .env kann später entfernt werden # (nach erfolgreicher Migration) ``` **Hinweis:** Framework lädt automatisch `.env.base` + `.env.local`. Falls diese nicht existieren, wird `.env` als Fallback geladen (Backward Compatibility).