# 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=<strong-database-password>

# Cache & Queue
CACHE_DRIVER=redis
QUEUE_DRIVER=redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=<strong-redis-password>

# Vault
VAULT_ENCRYPTION_KEY=<from-generate-vault-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<password> 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=<strong-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 / <strong-password>
# 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 <previous-commit>

# 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<password> 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', '<password>');"
```

---

## 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!
