# Concrete Deployment Workflow Schritt-für-Schritt Anleitung für das Production Deployment mit und ohne Ansible. ## Deployment-Optionen Das Framework bietet **zwei Deployment-Strategien**: 1. **Manual/Script-Based** (einfach, für Single-Server) 2. **Ansible-Based** (automatisiert, für Multi-Server) Beide Strategien nutzen Docker Compose als Container-Orchestrierung. --- ## Option 1: Manual/Script-Based Deployment (Empfohlen für Start) ### Voraussetzungen - Server mit Ubuntu 22.04 LTS - SSH-Zugriff mit sudo-Rechten - Domain mit DNS konfiguriert - Git Repository Access ### Phase 1: Initiales Server Setup (Einmalig) #### 1.1 Server vorbereiten ```bash # SSH-Verbindung zum Server ssh user@your-server.com # System aktualisieren sudo apt update && sudo apt upgrade -y # Docker installieren curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER # Docker Compose installieren sudo apt install -y docker-compose-plugin # Neuanmeldung für Docker-Gruppe exit ssh user@your-server.com # Verify docker --version docker compose version ``` #### 1.2 Projektverzeichnisse erstellen ```bash # Verzeichnisstruktur anlegen sudo mkdir -p /var/www/app sudo mkdir -p /var/log/app sudo mkdir -p /opt/vault sudo mkdir -p /etc/ssl/app sudo mkdir -p /backups/database sudo mkdir -p /backups/volumes # Berechtigungen setzen sudo chown -R $USER:$USER /var/www/app sudo chown -R www-data:www-data /var/log/app sudo chown -R www-data:www-data /opt/vault sudo chmod 755 /var/www/app sudo chmod 755 /var/log/app sudo chmod 700 /opt/vault ``` #### 1.3 Repository klonen ```bash cd /var/www git clone git@github.com:yourusername/app.git cd app # Production branch git checkout production # Scripts ausführbar machen chmod +x scripts/deployment/*.sh ``` #### 1.4 SSL-Zertifikat einrichten ```bash # Nginx für Certbot installieren sudo apt install -y nginx certbot python3-certbot-nginx # Temporäre Nginx-Config für Certbot sudo tee /etc/nginx/sites-available/temp-certbot > /dev/null <<'EOF' server { listen 80; server_name yourdomain.com www.yourdomain.com; location /.well-known/acme-challenge/ { root /var/www/certbot; } } EOF sudo ln -s /etc/nginx/sites-available/temp-certbot /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx # Zertifikat holen sudo certbot certonly --webroot \ -w /var/www/certbot \ -d yourdomain.com \ -d www.yourdomain.com \ --email your-email@example.com \ --agree-tos \ --no-eff-email # Zertifikate für Container verfügbar machen sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/ssl/app/cert.pem sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/ssl/app/key.pem sudo chmod 644 /etc/ssl/app/cert.pem sudo chmod 600 /etc/ssl/app/key.pem # Auto-Renewal einrichten echo "0 3 * * * root certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/ssl/app/cert.pem && cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/ssl/app/key.pem && docker compose -f /var/www/app/docker-compose.production.yml restart nginx" | sudo tee -a /etc/crontab ``` #### 1.5 Vault Encryption Key generieren ```bash cd /var/www/app # Key generieren php scripts/deployment/generate-vault-key.php # Output kopieren (sicher speichern!): # VAULT_ENCRYPTION_KEY=base64encodedkey... # In 1Password, Bitwarden, oder AWS Secrets Manager speichern ``` #### 1.6 Environment File erstellen ```bash cd /var/www/app # Template kopieren cp .env.example .env.production # Mit echten Production-Werten füllen nano .env.production ``` **Minimal erforderliche Werte**: ```env # Application APP_ENV=production APP_DEBUG=false APP_URL=https://yourdomain.com # Database DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=app_production DB_USERNAME=app_user DB_PASSWORD= # Cache & Queue CACHE_DRIVER=redis QUEUE_DRIVER=redis REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD= # Vault VAULT_ENCRYPTION_KEY= # Admin Access ADMIN_ALLOWED_IPS=your.ip.address.here # Logging LOG_PATH=/var/log/app LOG_LEVEL=info ``` #### 1.7 Secrets in Vault speichern ```bash # Secrets-Setup Script ausführen php scripts/deployment/setup-production-secrets.php # Manuelle Secrets hinzufügen docker compose -f docker-compose.production.yml run --rm php php -r " require 'vendor/autoload.php'; \$vault = new App\Framework\Vault\EncryptedVault( \$_ENV['VAULT_ENCRYPTION_KEY'], '/opt/vault/production.vault' ); // API Keys \$vault->set( App\Framework\Vault\SecretKey::from('stripe_secret_key'), App\Framework\Vault\SecretValue::from('sk_live_...') ); // Mail Password \$vault->set( App\Framework\Vault\SecretKey::from('mail_password'), App\Framework\Vault\SecretValue::from('your-mail-password') ); echo 'Secrets stored successfully\n'; " ``` ### Phase 2: Initiales Deployment #### 2.1 Dependencies installieren ```bash cd /var/www/app # Composer Dependencies docker compose -f docker-compose.production.yml run --rm php composer install --no-dev --optimize-autoloader # NPM Dependencies und Build docker compose -f docker-compose.production.yml run --rm nodejs npm ci docker compose -f docker-compose.production.yml run --rm nodejs npm run build ``` #### 2.2 Container starten ```bash # Docker Images bauen docker compose -f docker-compose.production.yml build # Container starten docker compose -f docker-compose.production.yml up -d # Logs verfolgen docker compose -f docker-compose.production.yml logs -f ``` #### 2.3 Datenbank initialisieren ```bash # Warten bis MySQL ready ist sleep 30 # Migrations ausführen docker compose -f docker-compose.production.yml exec php php console.php db:migrate # Verify docker compose -f docker-compose.production.yml exec php php console.php db:status ``` #### 2.4 Health Checks verifizieren ```bash # Health Check (sollte 200 zurückgeben) curl -f http://localhost/health || echo "Health check failed" # Detailed Health Report curl -s http://localhost/health/detailed | jq # Alle Checks sollten "healthy" sein curl -s http://localhost/health/summary | jq '.summary' ``` #### 2.5 Nginx Reverse Proxy konfigurieren ```bash # System Nginx als Reverse Proxy sudo tee /etc/nginx/sites-available/app > /dev/null <<'EOF' upstream app_backend { server localhost:8080; } server { listen 80; server_name yourdomain.com www.yourdomain.com; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name yourdomain.com www.yourdomain.com; ssl_certificate /etc/ssl/app/cert.pem; ssl_certificate_key /etc/ssl/app/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Security Headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # Proxy to Docker container location / { proxy_pass http://app_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Increase timeouts for long-running requests proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } EOF # Enable site sudo ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo rm -f /etc/nginx/sites-enabled/temp-certbot # Test config sudo nginx -t # Reload sudo systemctl reload nginx ``` #### 2.6 Finaler Test ```bash # HTTPS Health Check curl -f https://yourdomain.com/health || echo "HTTPS health check failed" # SSL Test openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null # Metrics curl https://yourdomain.com/metrics | head -20 # Homepage curl -I https://yourdomain.com ``` ### Phase 3: Laufendes Deployment (Updates) #### 3.1 Automatisches Deployment Script nutzen ```bash cd /var/www/app # Standard Deployment ./scripts/deployment/deploy-production.sh # Mit spezifischem Branch ./scripts/deployment/deploy-production.sh --branch production-v2.1.0 # Dry-Run (keine Änderungen) ./scripts/deployment/deploy-production.sh --dry-run ``` Das Script führt automatisch aus: 1. ✅ Pre-deployment Checks 2. ✅ Backup Erstellung 3. ✅ Git Pull 4. ✅ Composer/NPM Install 5. ✅ Docker Image Build 6. ✅ Database Migrations 7. ✅ Container Restart 8. ✅ Health Checks 9. ✅ Smoke Tests #### 3.2 Zero-Downtime Deployment (Blue-Green) ```bash # Blue-Green Deployment für Zero-Downtime ./scripts/deployment/blue-green-deploy.sh # Bei Problemen: Rollback ./scripts/deployment/blue-green-rollback.sh ``` #### 3.3 Manuelles Deployment (wenn Scripts nicht verfügbar) ```bash cd /var/www/app # 1. Pre-Deployment Backup docker compose -f docker-compose.production.yml exec db \ mysqldump -u app_user -p app_production \ > /backups/database/backup_$(date +%Y%m%d_%H%M%S).sql # 2. Git Pull git fetch origin production git checkout production git pull origin production # 3. Dependencies aktualisieren docker compose -f docker-compose.production.yml run --rm php \ composer install --no-dev --optimize-autoloader # 4. Frontend Build (falls geändert) docker compose -f docker-compose.production.yml run --rm nodejs npm ci docker compose -f docker-compose.production.yml run --rm nodejs npm run build # 5. Images neu bauen docker compose -f docker-compose.production.yml build # 6. Migrations ausführen docker compose -f docker-compose.production.yml exec php php console.php db:migrate # 7. Container neu starten docker compose -f docker-compose.production.yml up -d --no-deps --build php nginx # 8. Health Check curl -f https://yourdomain.com/health/summary # 9. Logs prüfen docker compose -f docker-compose.production.yml logs -f --tail=100 php ``` ### Phase 4: Monitoring Setup #### 4.1 Prometheus (Optional) ```yaml # docker-compose.monitoring.yml erstellen version: '3.8' services: prometheus: image: prom/prometheus:latest ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' restart: unless-stopped grafana: image: grafana/grafana:latest ports: - "3000:3000" volumes: - grafana-data:/var/lib/grafana environment: - GF_SECURITY_ADMIN_PASSWORD= restart: unless-stopped volumes: prometheus-data: grafana-data: ``` ```yaml # prometheus.yml global: scrape_interval: 15s scrape_configs: - job_name: 'app' static_configs: - targets: ['app-nginx:80'] metrics_path: '/metrics' ``` ```bash # Monitoring starten docker compose -f docker-compose.monitoring.yml up -d # Grafana öffnen: http://your-server:3000 # Login: admin / # Dashboard importieren: docs/deployment/grafana-dashboard.json ``` #### 4.2 Alerting (Optional) ```bash # Simple Alert Script für kritische Health Checks tee /opt/health-check-alert.sh > /dev/null <<'EOF' #!/bin/bash HEALTH=$(curl -s http://localhost/health/summary | jq -r '.overall_healthy') if [ "$HEALTH" != "true" ]; then # Alert senden (Email, Slack, PagerDuty, etc.) curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \ -H 'Content-Type: application/json' \ -d '{"text":"🚨 Production Health Check FAILED!"}' fi EOF chmod +x /opt/health-check-alert.sh # Crontab: Jede 5 Minuten prüfen echo "*/5 * * * * /opt/health-check-alert.sh" | crontab - ``` --- ## Option 2: Ansible-Based Deployment (Multi-Server) ### Wann Ansible verwenden? ✅ **Verwende Ansible wenn**: - Mehrere Production Server (Load Balancing) - Staging + Production Environments - Infrastructure as Code gewünscht - Wiederholbare, idempotente Deployments - Team-basierte Deployments ❌ **Ansible NICHT notwendig wenn**: - Einzelner Production Server - Einfache Infrastruktur - Kleine Team-Größe - Docker Compose Scripts ausreichend ### Ansible Setup Siehe separate Dokumentation: [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md) **Kurzübersicht**: ```bash # Ansible installieren pip install ansible # Playbooks ausführen cd ansible ansible-playbook -i inventory/production site.yml # Spezifische Playbooks ansible-playbook -i inventory/production playbooks/deploy.yml ansible-playbook -i inventory/production playbooks/rollback.yml ``` --- ## Deployment-Checkliste ### Pre-Deployment - [ ] Server vorbereitet und zugänglich - [ ] Domain DNS konfiguriert - [ ] SSL-Zertifikat vorhanden - [ ] Vault Encryption Key generiert und sicher gespeichert - [ ] Environment File `.env.production` erstellt - [ ] Secrets in Vault gespeichert - [ ] Docker und Docker Compose installiert - [ ] Nginx Reverse Proxy konfiguriert ### Initial Deployment - [ ] Repository geklont - [ ] Dependencies installiert - [ ] Docker Images gebaut - [ ] Container gestartet - [ ] Datenbank migriert - [ ] Health Checks grün - [ ] HTTPS funktioniert - [ ] Monitoring konfiguriert (optional) ### Laufendes Deployment - [ ] Backup erstellt - [ ] Git Pull erfolgreich - [ ] Dependencies aktualisiert - [ ] Frontend gebaut (falls nötig) - [ ] Images neu gebaut - [ ] Migrations ausgeführt - [ ] Container neu gestartet - [ ] Health Checks grün - [ ] Smoke Tests erfolgreich - [ ] Logs geprüft ### Post-Deployment - [ ] Application erreichbar - [ ] Alle Features funktional - [ ] Performance akzeptabel - [ ] Monitoring aktiv - [ ] Logs rotieren - [ ] Backups funktionieren - [ ] Rollback-Plan getestet --- ## Rollback-Prozedur ### Quick Rollback ```bash cd /var/www/app # 1. Zu vorherigem Commit git log --oneline -10 # Vorherigen Commit finden git checkout # 2. Dependencies (falls nötig) docker compose -f docker-compose.production.yml run --rm php \ composer install --no-dev --optimize-autoloader # 3. Migrations rückgängig docker compose -f docker-compose.production.yml exec php \ php console.php db:rollback 3 # 4. Container neu starten docker compose -f docker-compose.production.yml up -d --build # 5. Health Check curl -f https://yourdomain.com/health/summary ``` ### Database Rollback ```bash # Datenbank aus Backup wiederherstellen docker compose -f docker-compose.production.yml exec -T db \ mysql -u app_user -p app_production \ < /backups/database/backup_20250115_120000.sql # Verify docker compose -f docker-compose.production.yml exec php \ php console.php db:status ``` --- ## Troubleshooting Deployment ### Container starten nicht ```bash # Logs prüfen docker compose -f docker-compose.production.yml logs # Port-Konflikte prüfen sudo netstat -tulpn | grep -E ':(80|443|3306|6379)' # Container Status docker compose -f docker-compose.production.yml ps # Neustart docker compose -f docker-compose.production.yml down docker compose -f docker-compose.production.yml up -d ``` ### Health Checks schlagen fehl ```bash # Detailed Health Report curl http://localhost/health/detailed | jq # Spezifische Checks curl http://localhost/health/category/database | jq curl http://localhost/health/category/security | jq # Container-Logs docker compose -f docker-compose.production.yml logs php docker compose -f docker-compose.production.yml logs nginx ``` ### Migrations schlagen fehl ```bash # Migration Status docker compose -f docker-compose.production.yml exec php \ php console.php db:status # Migrations rollback docker compose -f docker-compose.production.yml exec php \ php console.php db:rollback 1 # Database Connection testen docker compose -f docker-compose.production.yml exec php \ php -r "new PDO('mysql:host=db;dbname=app_production', 'app_user', '');" ``` --- ## Empfohlener Workflow für dein Projekt ### Für Initial Setup und kleine Deployments: **Verwende Script-Based Deployment**: 1. Server Setup (einmalig): Siehe Phase 1 2. Initial Deployment: Siehe Phase 2 3. Updates: `./scripts/deployment/deploy-production.sh` 4. Zero-Downtime: `./scripts/deployment/blue-green-deploy.sh` ### Für Skalierung und Multiple Environments: **Ergänze mit Ansible**: 1. Server Provisioning automatisieren 2. Multi-Server Deployments orchestrieren 3. Konsistente Configuration Management 4. Infrastructure as Code Siehe nächstes Dokument: [ANSIBLE_DEPLOYMENT.md](ANSIBLE_DEPLOYMENT.md) --- ## Nächste Schritte 1. ✅ Server vorbereiten (Phase 1) 2. ✅ Initial Deployment durchführen (Phase 2) 3. ✅ Monitoring einrichten (Phase 4) 4. 📝 Deployment dokumentieren 5. 🔄 Ansible evaluieren (optional, wenn Multi-Server) Für detaillierte Ansible-Integration siehe nächstes Dokument!