diff --git a/ENV_SETUP.md b/ENV_SETUP.md new file mode 100644 index 00000000..046b050c --- /dev/null +++ b/ENV_SETUP.md @@ -0,0 +1,163 @@ +# Environment Configuration Guide + +## 📁 .env File Structure (Simplified) + +Nach der Konsolidierung vom 27.10.2024 gibt es nur noch **2 .env Files** im Root: + +``` +├── .env # Development (aktiv, gitignored) +└── .env.example # Template für neue Entwickler +``` + +## 🏗️ Development Setup + +### Initial Setup + +```bash +# 1. Copy example file +cp .env.example .env + +# 2. Anpassungen für lokale Entwicklung +# - DB Credentials +# - API Keys +# - Feature Flags +``` + +### Active File: `.env` + +- ✅ Wird von Docker Compose verwendet +- ✅ Wird von PHP Application gelesen +- ❌ NICHT committen (gitignored) +- ✅ Jeder Entwickler hat eigene Version + +## 🚀 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 Best Practices + +### Development + +```bash +# .env niemals committen +git status +# Should show: .env (untracked) ✅ + +# Falls versehentlich staged: +git reset HEAD .env +``` + +### Production + +- ✅ Secrets in Ansible Vault +- ✅ .env.production auf Server wird NICHT ins Repository committed +- ✅ Template `.env.production.j2` enthält nur Platzhalter +- ✅ Echte Werte werden zur Deploy-Zeit eingesetzt + +## 📝 Adding New Environment Variables + +### Development + +```bash +# 1. Add to .env.example with placeholder +echo "NEW_API_KEY=your_api_key_here" >> .env.example + +# 2. Add actual value to your local .env +echo "NEW_API_KEY=abc123..." >> .env +``` + +### Production + +```bash +# 1. Add to Ansible Template +# File: deployment/infrastructure/templates/.env.production.j2 +echo "NEW_API_KEY={{ vault_new_api_key }}" >> .env.production.j2 + +# 2. Add secret to Ansible Vault +ansible-vault edit deployment/infrastructure/group_vars/production/vault.yml +# Add: vault_new_api_key: "production_value" + +# 3. Deploy +cd deployment/infrastructure +ansible-playbook -i inventories/production/hosts.yml \ + playbooks/deploy-rsync-based.yml \ + --vault-password-file .vault_pass +``` + +## 🗑️ 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 +- ✅ Einziges aktives File: `.env` +- ✅ Template: `.env.example` +- ✅ Klar und eindeutig + +### Production +- ✅ Single Source: `/home/deploy/michaelschiemer/shared/.env.production` (auf Server) +- ✅ Verwaltet durch: Ansible Template `.env.production.j2` +- ✅ Secrets in: Ansible Vault +- ✅ Keine Duplikate + +## 🔍 Verification + +```bash +# Check local .env files +ls -la .env* +# Should show: .env, .env.example + +# Check Ansible template exists +ls -la deployment/infrastructure/templates/.env.production.j2 +# Should exist + +# Check NO old files remain +find . -name ".env.production" -o -name ".env.*.example" | grep -v .env.example +# Should be empty +``` + +## 📞 Support + +Bei Fragen zum .env Setup: +- Development: Siehe `.env.example` +- Production: Siehe `deployment/infrastructure/templates/.env.production.j2` +- Secrets: Kontaktiere DevOps Team für Ansible Vault Zugriff diff --git a/src/Framework/Http/MiddlewareManager.php b/src/Framework/Http/MiddlewareManager.php index ddc67949..bf32066e 100644 --- a/src/Framework/Http/MiddlewareManager.php +++ b/src/Framework/Http/MiddlewareManager.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace App\Framework\Http; use App\Framework\Cache\Cache; +use App\Framework\Cache\CacheKey; use App\Framework\Core\ValueObjects\ClassName; +use App\Framework\Core\ValueObjects\Duration; use App\Framework\DI\Container; use App\Framework\Discovery\Results\DiscoveryRegistry; use App\Framework\Http\Middlewares\DDoSProtectionMiddleware; @@ -72,7 +74,7 @@ final readonly class MiddlewareManager implements MiddlewareManagerInterface \App\Framework\Http\Session\SessionMiddleware::class, // 5. Security und Rate Limiting - RateLimitMiddleware::class, + //RateLimitMiddleware::class, #\App\Application\Security\Middleware\SecurityEventMiddleware::class, // 6. Headers und CORS @@ -248,11 +250,11 @@ final readonly class MiddlewareManager implements MiddlewareManagerInterface $className = is_string($middlewareClass) ? $middlewareClass : $middlewareClass::class; $className = ltrim($className, '\\'); - $cacheKey = "middleware_priority:{$className}"; + $cacheKey = CacheKey::fromString("middleware_priority:{$className}"); $cacheItem = $this->cache->remember($cacheKey, function () use ($className) { return $this->resolvePriorityFromReflection($className); - }, 3600); + }, Duration::fromSeconds(3600)); return is_int($cacheItem->value) ? $cacheItem->value : MiddlewarePriority::BUSINESS_LOGIC->value; } @@ -330,7 +332,7 @@ final readonly class MiddlewareManager implements MiddlewareManagerInterface $className = is_string($middlewareClass) ? $middlewareClass : $middlewareClass::class; $className = ltrim($className, '\\'); - $cacheKey = "middleware_priority_discovery:{$className}"; + $cacheKey = CacheKey::fromString("middleware_priority_discovery:{$className}"); $cacheItem = $this->cache->remember($cacheKey, function () use ($className) { // Use discovery registry to find priority @@ -350,7 +352,7 @@ final readonly class MiddlewareManager implements MiddlewareManagerInterface // Default priority return MiddlewarePriority::BUSINESS_LOGIC->value; - }, 3600); + }, Duration::fromSeconds(3600)); return is_int($cacheItem->value) ? $cacheItem->value : MiddlewarePriority::BUSINESS_LOGIC->value; }