- Update Ansible playbooks and roles for application deployment - Add new Gitea/Traefik troubleshooting playbooks - Update Docker Compose configurations (base, local, staging, production) - Enhance EncryptedEnvLoader with improved error handling - Add deployment scripts (autossh setup, migration, secret testing) - Update CI/CD workflows and documentation - Add Semaphore stack configuration
8.4 KiB
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
# 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:
- System Environment Variables (Docker ENV)
.env.base(gemeinsame Basis).env.local(lokale Overrides).env.secrets(verschlüsselte Secrets, optional)
Wichtig: env_file in Docker Compose ist nicht nötig!
- Framework lädt automatisch
.env.base→.env.localviaEncryptedEnvLoader - Docker Compose
env_fileist 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.baseoder.env.localnicht existieren, wird.envgeladen (Fallback) - Migration: Bestehende
.envFiles 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
# 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:
- Template
.env.production.j2rendern - Vault-verschlüsselte Secrets einsetzen
- File nach
/home/deploy/michaelschiemer/shared/.env.productiondeployen - Docker Compose mounted diesen File in Container
🔒 Security & Secret Management
Docker Secrets (Production & Staging)
Production und Staging verwenden Docker Secrets:
-
Ansible Vault → Docker Secrets Dateien
- Ansible Playbook erstellt Secret-Dateien in
secrets/Verzeichnis - Dateien haben sichere Permissions (0600)
- Ansible Playbook erstellt Secret-Dateien in
-
Docker Compose Secrets
- Secrets werden in
docker-compose.base.ymldefiniert - Environment-Variablen nutzen
*_FILEPattern (z.B.DB_PASSWORD_FILE=/run/secrets/db_user_password) - Framework lädt automatisch via
DockerSecretsResolver
- Secrets werden in
-
Framework Support
DockerSecretsResolverunterstützt automatisch*_FILEPattern- Kein manuelles Secret-Loading mehr nötig (wird automatisch vom Framework behandelt)
Development
# .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
*_FILEPattern - ✅ .env.production auf Server wird NICHT ins Repository committed
- ✅ Template
application.env.j2verwendet*_FILEPattern
📝 Adding New Environment Variables
Development
# 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)
# 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:
# 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/*.txtDateien) - ✅ Framework lädt automatisch via
*_FILEPattern (DockerSecretsResolver) - ✅ Keine Duplikate
Staging
- ✅ Docker Compose Environment Variables
- ✅ Docker Secrets aktiviert (wie Production)
- ✅ Optional:
.env.stagingfür Staging-spezifische Overrides
🔍 Verification
# 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:
# 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).