# Deployment-Guide: Risk Intelligence Platform ## πŸ“‹ Inhaltsverzeichnis 1. [Übersicht](#ΓΌbersicht) 2. [Voraussetzungen](#voraussetzungen) 3. [Docker Deployment](#docker-deployment) 4. [Kubernetes Deployment](#kubernetes-deployment) 5. [Production Checklist](#production-checklist) 6. [Environment Configuration](#environment-configuration) 7. [Database Migration](#database-migration) 8. [Monitoring & Logging](#monitoring--logging) 9. [Backup & Recovery](#backup--recovery) 10. [Rollback-Strategie](#rollback-strategie) 11. [Troubleshooting](#troubleshooting) --- ## Übersicht Die Risk Intelligence Platform kann auf verschiedene Arten deployed werden: - **Docker** - Standalone Container oder Docker Compose - **Kubernetes** - Production-ready mit CronJobs fΓΌr Scheduled Tasks - **Traditional** - Apache/Nginx + PHP-FPM auf Linux-Server ### Deployment-Architektur ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Production Environment β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Nginx β”‚ β”‚ PHP-FPM β”‚ β”‚ Supervisor β”‚ β”‚ β”‚ β”‚ (Port 80) β”‚ β”‚ (Laravel) β”‚ β”‚ (Queue) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ PostgreSQL Database β”‚ β”‚ β”‚ β”‚ (Public + Backend Schema) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Kubernetes CronJob (Laravel Scheduler) β”‚ β”‚ β”‚ β”‚ - SyncBackendDataPool (every 6h) β”‚ β”‚ β”‚ β”‚ - TransformDataPool (every 6h at :30) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## Voraussetzungen ### System Requirements | Komponente | Minimum | Empfohlen | |------------|---------|-----------| | **CPU** | 2 Cores | 4 Cores | | **RAM** | 2 GB | 4 GB | | **Disk** | 20 GB | 50 GB SSD | | **OS** | Linux (Ubuntu 22.04+) | Alpine Linux 3.22 | ### Software Requirements | Software | Version | Zweck | |----------|---------|-------| | **PHP** | 8.2+ | Runtime | | **Composer** | 2.0+ | Dependencies | | **Node.js** | 18+ | Asset Building | | **PostgreSQL** | 14+ | Database | | **Nginx** | 1.24+ | Web Server | | **Supervisor** | 4.0+ | Process Management | | **Docker** | 24.0+ | Containerization (optional) | | **Kubernetes** | 1.28+ | Orchestration (optional) | --- ## Docker Deployment ### Multi-Stage Dockerfile Die Applikation nutzt einen **Multi-Stage Build** fΓΌr optimale Image-Grâße. ```dockerfile # Stage 1: Composer Dependencies FROM composer:2 AS vendor WORKDIR /app COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader # Stage 2: Runtime FROM alpine:3.22 # Install PHP 8.2, Nginx, Supervisor, PostgreSQL Client RUN apk add --no-cache \ nginx supervisor php82 php82-fpm \ php82-pgsql php82-pdo_pgsql \ nodejs npm # Copy vendor from build stage COPY --from=vendor /app/vendor ./vendor COPY . ./ # Build frontend assets RUN npm ci && npm run build # Optimize Laravel RUN php artisan config:cache && \ php artisan route:cache && \ php artisan view:cache EXPOSE 80 CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"] ``` ### Build & Run ```bash # Build Image docker build -t risk-platform:latest . # Run Container docker run -d \ --name risk-platform \ -p 8080:80 \ -v $(pwd)/.env:/var/www/html/.env \ -v $(pwd)/storage:/var/www/html/storage \ risk-platform:latest ``` ### Docker Compose ```yaml # docker-compose.yml version: "3.9" services: app: build: context: . dockerfile: Dockerfile container_name: risk-platform restart: unless-stopped ports: - "8080:80" volumes: - .env:/var/www/html/.env - ./storage:/var/www/html/storage depends_on: - postgres networks: - risk-net postgres: image: postgres:16-alpine container_name: risk-postgres restart: unless-stopped environment: POSTGRES_DB: risk_platform_db POSTGRES_USER: risk_user POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - postgres-data:/var/lib/postgresql/data ports: - "5432:5432" networks: - risk-net scheduler: build: context: . dockerfile: Dockerfile container_name: risk-scheduler restart: unless-stopped command: ["php", "artisan", "schedule:work"] volumes: - .env:/var/www/html/.env depends_on: - postgres networks: - risk-net volumes: postgres-data: networks: risk-net: driver: bridge ``` **Starten:** ```bash docker-compose up -d ``` --- ## Kubernetes Deployment ### Namespace erstellen ```yaml # namespace.yaml apiVersion: v1 kind: Namespace metadata: name: risk-platform ``` ```bash kubectl apply -f namespace.yaml ``` ### ConfigMap fΓΌr Environment ```yaml # configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: risk-platform-config namespace: risk-platform data: env: | APP_NAME="Risk Intelligence Platform" APP_ENV=production APP_KEY=base64:xxx APP_DEBUG=false APP_URL=https://risk.example.com DB_CONNECTION2=pgsql DB_HOST2=postgres-service DB_PORT2=5432 DB_DATABASE2=risk_platform_db DB_USERNAME2=risk_user DB_PASSWORD2=xxx CACHE_STORE=redis SESSION_DRIVER=redis QUEUE_CONNECTION=redis REDIS_HOST=redis-service REDIS_PORT=6379 ``` ```bash kubectl apply -f configmap.yaml ``` ### Deployment ```yaml # deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: risk-platform namespace: risk-platform labels: app: risk-platform spec: replicas: 2 selector: matchLabels: app: risk-platform template: metadata: labels: app: risk-platform spec: containers: - name: app image: registry.example.com/risk-platform:latest imagePullPolicy: Always ports: - containerPort: 80 name: http env: - name: APP_ENV value: "production" volumeMounts: - name: config mountPath: /var/www/html/.env subPath: env - name: storage mountPath: /var/www/html/storage resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "1Gi" cpu: "500m" livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 10 periodSeconds: 5 volumes: - name: config configMap: name: risk-platform-config - name: storage persistentVolumeClaim: claimName: risk-platform-storage ``` ```bash kubectl apply -f deployment.yaml ``` ### Service ```yaml # service.yaml apiVersion: v1 kind: Service metadata: name: risk-platform-service namespace: risk-platform spec: selector: app: risk-platform ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP ``` ### Ingress (Optional) ```yaml # ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: risk-platform-ingress namespace: risk-platform annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: ingressClassName: nginx tls: - hosts: - risk.example.com secretName: risk-platform-tls rules: - host: risk.example.com http: paths: - path: / pathType: Prefix backend: service: name: risk-platform-service port: number: 80 ``` ### CronJob fΓΌr Laravel Scheduler ```yaml # cronjob.yaml apiVersion: batch/v1 kind: CronJob metadata: name: sync-backend-data-pool namespace: risk-platform spec: schedule: "0 */6 * * *" # Every 6 hours successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3 concurrencyPolicy: Forbid jobTemplate: spec: template: metadata: labels: app: sync-backend-data-pool spec: restartPolicy: OnFailure containers: - name: sync image: registry.example.com/risk-platform:latest command: ["php", "artisan", "schedule:run"] volumeMounts: - name: config mountPath: /var/www/html/.env subPath: env volumes: - name: config configMap: name: risk-platform-config ``` ```bash kubectl apply -f cronjob.yaml ``` ### Alle Ressourcen deployen ```bash # Complete Deployment kubectl apply -f namespace.yaml kubectl apply -f configmap.yaml kubectl apply -f deployment.yaml kubectl apply -f service.yaml kubectl apply -f ingress.yaml kubectl apply -f cronjob.yaml # Status prΓΌfen kubectl get all -n risk-platform # Logs anschauen kubectl logs -f deployment/risk-platform -n risk-platform ``` --- ## Production Checklist ### Pre-Deployment - [ ] **Environment Configuration** - [ ] `.env` auf `production` gesetzt - [ ] `APP_DEBUG=false` - [ ] `APP_KEY` generiert - [ ] Sichere PasswΓΆrter fΓΌr DB - [ ] **Database** - [ ] PostgreSQL lΓ€uft - [ ] Schemas erstellt (public, backend) - [ ] User-Rechte vergeben - [ ] Backup-Strategie definiert - [ ] **Dependencies** - [ ] `composer install --no-dev --optimize-autoloader` - [ ] `npm ci && npm run build` - [ ] **Laravel Optimization** - [ ] `php artisan config:cache` - [ ] `php artisan route:cache` - [ ] `php artisan view:cache` - [ ] `php artisan event:cache` - [ ] **Security** - [ ] HTTPS aktiviert (SSL/TLS) - [ ] Firewall konfiguriert - [ ] `.env` nicht im Git - [ ] Secrets in Vault/ConfigMap ### Post-Deployment - [ ] **Migrations** - [ ] `php artisan migrate --force` - [ ] Backup vor Migration - [ ] **Tests** - [ ] Health Check (`/`) - [ ] Login funktioniert - [ ] Database Connection - [ ] Scheduled Jobs - [ ] **Monitoring** - [ ] Logs werden geschrieben - [ ] Metrics werden gesammelt - [ ] Alerts konfiguriert - [ ] **Performance** - [ ] OPcache aktiviert - [ ] Redis fΓΌr Cache/Session - [ ] Database Indizes --- ## Environment Configuration ### Production .env ```ini # Application APP_NAME="Risk Intelligence Platform" APP_ENV=production APP_KEY=base64:xxx # Generate with: php artisan key:generate APP_DEBUG=false APP_URL=https://risk.example.com # Locale APP_LOCALE=de APP_FALLBACK_LOCALE=en # Database (PostgreSQL) DB_CONNECTION2=pgsql DB_HOST2=postgres-host DB_PORT2=5432 DB_DATABASE2=risk_platform_db DB_USERNAME2=risk_user DB_PASSWORD2=xxx # Use strong password! # Cache & Session (Redis) CACHE_STORE=redis SESSION_DRIVER=redis SESSION_LIFETIME=120 # Queue QUEUE_CONNECTION=redis # Redis REDIS_HOST=redis-host REDIS_PASSWORD=null REDIS_PORT=6379 # Mail MAIL_MAILER=smtp MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_USERNAME=noreply@example.com MAIL_PASSWORD=xxx MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=noreply@example.com MAIL_FROM_NAME="${APP_NAME}" # Logging LOG_CHANNEL=stack LOG_LEVEL=error # Production: error, nicht debug! # Security SESSION_SECURE_COOKIE=true SESSION_SAME_SITE=strict ``` ### Secrets Management **Kubernetes Secrets:** ```bash # Create Secret kubectl create secret generic risk-platform-secrets \ --from-literal=APP_KEY=base64:xxx \ --from-literal=DB_PASSWORD=xxx \ --from-literal=REDIS_PASSWORD=xxx \ -n risk-platform # Use in Deployment env: - name: APP_KEY valueFrom: secretKeyRef: name: risk-platform-secrets key: APP_KEY ``` --- ## Database Migration ### Pre-Migration Backup ```bash # PostgreSQL Backup pg_dump -h localhost -U risk_user -d risk_platform_db > backup_$(date +%Y%m%d_%H%M%S).sql # Verify Backup psql -h localhost -U risk_user -d risk_platform_db_test < backup_xxx.sql ``` ### Run Migrations ```bash # Production Migration php artisan migrate --force # With Output php artisan migrate --force --verbose # Rollback (if needed) php artisan migrate:rollback --force ``` ### Zero-Downtime Migration ```bash # 1. Maintenance Mode php artisan down --message="Updating..." --retry=60 # 2. Pull latest code git pull origin main # 3. Update dependencies composer install --no-dev --optimize-autoloader # 4. Run migrations php artisan migrate --force # 5. Clear & cache php artisan optimize:clear php artisan config:cache php artisan route:cache php artisan view:cache # 6. Restart services sudo supervisorctl restart all # 7. Exit maintenance mode php artisan up ``` --- ## Monitoring & Logging ### Application Logs ```bash # Laravel Logs tail -f storage/logs/laravel.log # Nur Errors tail -f storage/logs/laravel.log | grep ERROR # Mit Laravel Pail php artisan pail --filter=error ``` ### Nginx Logs ```bash # Access Log tail -f /var/log/nginx/access.log # Error Log tail -f /var/log/nginx/error.log ``` ### Kubernetes Logs ```bash # Pod Logs kubectl logs -f deployment/risk-platform -n risk-platform # Alle Pods kubectl logs -f -l app=risk-platform -n risk-platform # CronJob Logs kubectl logs -f cronjob/sync-backend-data-pool -n risk-platform ``` ### Health Checks ```bash # Application Health curl https://risk.example.com/ # Database Connection php artisan tinker >>> DB::connection()->getPdo() # Queue Status php artisan queue:monitor # Scheduler Status php artisan schedule:list ``` ### Monitoring-Tools (Optional) **Laravel Telescope:** ```bash composer require laravel/telescope --dev php artisan telescope:install php artisan migrate ``` **Prometheus + Grafana:** - Metrics-Export via Laravel Package - Custom Dashboards fΓΌr Transactions, Companies - Alerts bei hoher Error-Rate --- ## Backup & Recovery ### Automated Backup Script ```bash #!/bin/bash # backup.sh DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="/backups" DB_NAME="risk_platform_db" # Database Backup pg_dump -h localhost -U risk_user $DB_NAME > $BACKUP_DIR/db_$DATE.sql # Storage Backup tar -czf $BACKUP_DIR/storage_$DATE.tar.gz storage/ # Keep only last 7 days find $BACKUP_DIR -type f -mtime +7 -delete echo "Backup completed: $DATE" ``` **Crontab:** ```bash # Daily backup at 2 AM 0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1 ``` ### Kubernetes Backup ```yaml # backup-cronjob.yaml apiVersion: batch/v1 kind: CronJob metadata: name: database-backup namespace: risk-platform spec: schedule: "0 2 * * *" # Daily at 2 AM jobTemplate: spec: template: spec: containers: - name: backup image: postgres:16-alpine command: - /bin/sh - -c - | pg_dump -h postgres-service -U risk_user risk_platform_db > /backup/db_$(date +%Y%m%d).sql volumeMounts: - name: backup-storage mountPath: /backup volumes: - name: backup-storage persistentVolumeClaim: claimName: backup-pvc restartPolicy: OnFailure ``` ### Recovery Procedure ```bash # 1. Stop Application kubectl scale deployment risk-platform --replicas=0 -n risk-platform # 2. Restore Database psql -h localhost -U risk_user -d risk_platform_db < backup_xxx.sql # 3. Verify Data psql -h localhost -U risk_user -d risk_platform_db \dt SELECT COUNT(*) FROM companies; # 4. Restart Application kubectl scale deployment risk-platform --replicas=2 -n risk-platform ``` --- ## Rollback-Strategie ### Git-based Rollback ```bash # 1. Identify previous version git log --oneline -10 # 2. Checkout previous version git checkout # 3. Rebuild & Deploy docker build -t risk-platform:rollback . docker push registry.example.com/risk-platform:rollback # 4. Update Kubernetes kubectl set image deployment/risk-platform \ app=registry.example.com/risk-platform:rollback \ -n risk-platform ``` ### Database Rollback ```bash # Rollback last migration php artisan migrate:rollback --step=1 --force # Rollback specific batch php artisan migrate:rollback --batch=3 --force # Full rollback to fresh state (CAUTION!) php artisan migrate:fresh --force ``` ### Blue-Green Deployment ```yaml # deployment-blue.yaml (current) metadata: name: risk-platform-blue labels: app: risk-platform version: blue # deployment-green.yaml (new version) metadata: name: risk-platform-green labels: app: risk-platform version: green # Switch Traffic # Change service selector from blue to green kubectl patch service risk-platform-service \ -p '{"spec":{"selector":{"version":"green"}}}' \ -n risk-platform ``` --- ## Troubleshooting ### Problem: Container startet nicht **Diagnose:** ```bash docker logs risk-platform kubectl logs deployment/risk-platform -n risk-platform ``` **HΓ€ufige Ursachen:** - `.env` fehlt oder ungΓΌltig - Database Connection fehlgeschlagen - Permissions auf `storage/` fehlen **LΓΆsung:** ```bash # Check .env docker exec -it risk-platform cat /var/www/html/.env # Fix permissions docker exec -it risk-platform chown -R nginx:nginx storage ``` --- ### Problem: "500 Internal Server Error" **Diagnose:** ```bash # Laravel Logs tail -f storage/logs/laravel.log # Nginx Error Log tail -f /var/log/nginx/error.log ``` **HΓ€ufige Ursachen:** - `APP_KEY` nicht gesetzt - Config Cache veraltet - Database Connection Error **LΓΆsung:** ```bash # Generate APP_KEY php artisan key:generate --force # Clear caches php artisan optimize:clear # Test DB connection php artisan tinker >>> DB::connection()->getPdo() ``` --- ### Problem: Scheduled Jobs laufen nicht **Diagnose:** ```bash # Check CronJob Status kubectl get cronjobs -n risk-platform # Check Job History kubectl get jobs -n risk-platform # Check Logs kubectl logs job/sync-backend-data-pool-xxx -n risk-platform ``` **LΓΆsung:** ```bash # Test Schedule manually php artisan schedule:run # Test specific Job php artisan backend:sync-data-pool --incremental ``` --- ### Problem: High Memory Usage **Diagnose:** ```bash # Container Stats docker stats risk-platform # Pod Resource Usage kubectl top pod -n risk-platform ``` **LΓΆsung:** - Reduce batch size in Jobs - Increase memory limits - Enable OPcache - Use Redis for cache/session --- ## Performance Optimization ### OPcache Configuration ```ini ; /etc/php82/conf.d/opcache.ini opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=10000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 ``` ### Redis Configuration ```yaml # redis.conf maxmemory 512mb maxmemory-policy allkeys-lru ``` ### Database Optimization ```sql -- Index on frequently queried columns CREATE INDEX idx_transactions_status ON transactions(status); CREATE INDEX idx_transactions_risk_score ON transactions(risk_score); CREATE INDEX idx_companies_kyc_risk_level ON companies(kyc_risk_level); -- Vacuum regularly VACUUM ANALYZE companies; VACUUM ANALYZE transactions; ``` --- ## Security Best Practices ### SSL/TLS ```yaml # ingress.yaml with TLS spec: tls: - hosts: - risk.example.com secretName: risk-platform-tls ``` ### Firewall Rules ```bash # Allow HTTP/HTTPS only ufw allow 80/tcp ufw allow 443/tcp ufw enable ``` ### Security Headers ```nginx # nginx.conf add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; ``` --- ## Zusammenfassung ### Deployment-Optionen | Option | KomplexitΓ€t | Skalierbarkeit | Empfohlen fΓΌr | |--------|-------------|----------------|---------------| | **Docker** | Niedrig | Mittel | Development, Small Production | | **Kubernetes** | Hoch | Hoch | Production, Enterprise | | **Traditional** | Mittel | Niedrig | Legacy Systems | ### Checkliste fΓΌr Production βœ… Environment auf `production` gesetzt βœ… `APP_DEBUG=false` βœ… HTTPS aktiviert βœ… Database-Backup automatisiert βœ… Monitoring & Logging konfiguriert βœ… Scheduled Jobs laufen βœ… Health Checks aktiv βœ… Secrets sicher gespeichert βœ… Rollback-Strategie getestet --- **Erstellt:** 2025-11-24 **Version:** 1.0 **Autor:** Risk Intelligence Platform Team