# Deployment auf externem Server

## Voraussetzungen auf dem Server
- Docker und Docker Compose installiert
- Git installiert
- Port 80 und/oder 443 für Web-Traffic geöffnet
- Optional: Reverse Proxy (nginx/Apache) für SSL-Termination

## 1. Repository auf Server klonen
```bash
git clone <your-repository-url> /opt/rezepte
cd /opt/rezepte
```

## 2. Produktions-Umgebung konfigurieren

### Environment-Datei erstellen
```bash
cp .env.example .env.production
```

### .env.production anpassen:
```env
# Database
DATABASE_URL="mysql://rezepte_user:secure_password_here@mysql:3306/rezepte"

# Security
JWT_SECRET="your-super-secure-jwt-secret-min-32-chars"

# CORS - Ihre Domain(s) eintragen
CORS_ORIGIN="https://yourdomain.com"

# Environment
NODE_ENV=production

# Uploads
UPLOAD_DIR=/app/uploads
MAX_UPLOAD_SIZE=10mb

# Server
PORT=3001
```

## 3. Docker Compose für Produktion anpassen

### docker-compose.production.yml erstellen:
```yaml
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: rezepte-mysql-prod
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: rezepte
      MYSQL_USER: rezepte_user
      MYSQL_PASSWORD: secure_password_here
      MYSQL_ROOT_PASSWORD: super_secure_root_password
    volumes:
      - mysql_data:/var/lib/mysql
      - ./Rezepte.sql:/docker-entrypoint-initdb.d/01-rezepte.sql:ro
      - ./ingredients.sql:/docker-entrypoint-initdb.d/02-ingredients.sql:ro
      - ./Zubereitung.sql:/docker-entrypoint-initdb.d/03-zubereitung.sql:ro
      - ./rezepte_bilder.sql:/docker-entrypoint-initdb.d/04-bilder.sql:ro
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 20s
      retries: 10
    networks:
      - rezepte-network

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: rezepte-backend-prod
    restart: unless-stopped
    environment:
      - NODE_ENV=production
      - DATABASE_URL=mysql://rezepte_user:secure_password_here@mysql:3306/rezepte
      - JWT_SECRET=your-super-secure-jwt-secret-min-32-chars
      - CORS_ORIGIN=https://yourdomain.com
      - PORT=3001
    volumes:
      - uploads_data:/app/uploads
      - ./upload:/app/legacy-uploads:ro
    depends_on:
      mysql:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - rezepte-network

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      args:
        - VITE_API_BASE_URL=https://yourdomain.com/api
    container_name: rezepte-frontend-prod
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"  # Wenn SSL direkt im Container
    volumes:
      - ./ssl:/etc/nginx/ssl:ro  # SSL-Zertifikate
    depends_on:
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - rezepte-network

volumes:
  mysql_data:
    driver: local
  uploads_data:
    driver: local

networks:
  rezepte-network:
    driver: bridge
```

## 4. SSL/HTTPS einrichten

### Option A: Let's Encrypt mit Certbot
```bash
# Certbot installieren
sudo apt update
sudo apt install certbot

# SSL-Zertifikat erstellen
sudo certbot certonly --standalone -d yourdomain.com

# Zertifikate kopieren
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem ./ssl/
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem ./ssl/
```

### Option B: Reverse Proxy (empfohlen)
```nginx
# /etc/nginx/sites-available/rezepte
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }

    location /api/ {
        proxy_pass http://localhost:3001;
        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;
    }

    location /uploads/ {
        proxy_pass http://localhost:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

## 5. Deployment-Skripte

### deploy.sh erstellen:
```bash
#!/bin/bash
set -e

echo "🚀 Deploying Rezepte..."

# Git pull latest changes
git pull origin main

# Build and start containers
docker-compose -f docker-compose.production.yml down
docker-compose -f docker-compose.production.yml up --build -d

# Health check
echo "⏳ Waiting for services to start..."
sleep 30

# Check if all services are healthy
if docker-compose -f docker-compose.production.yml ps | grep -q "Up (healthy)"; then
    echo "✅ Deployment successful!"
    echo "🌐 Application available at: https://yourdomain.com"
else
    echo "❌ Deployment failed! Check logs:"
    docker-compose -f docker-compose.production.yml logs
    exit 1
fi
```

### backup.sh erstellen:
```bash
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/backups/rezepte"

mkdir -p $BACKUP_DIR

# Database backup
docker exec rezepte-mysql-prod mysqldump -u root -psuper_secure_root_password rezepte > $BACKUP_DIR/database_$DATE.sql

# Uploads backup
docker cp rezepte-backend-prod:/app/uploads $BACKUP_DIR/uploads_$DATE

# Keep only last 7 backups
find $BACKUP_DIR -name "database_*.sql" -mtime +7 -delete
find $BACKUP_DIR -name "uploads_*" -mtime +7 -exec rm -rf {} +

echo "✅ Backup completed: $BACKUP_DIR"
```

## 6. Monitoring und Logs

### Logs anzeigen:
```bash
# Alle Services
docker-compose -f docker-compose.production.yml logs -f

# Nur Backend
docker-compose -f docker-compose.production.yml logs -f backend

# Nur Frontend
docker-compose -f docker-compose.production.yml logs -f frontend
```

### Service-Status prüfen:
```bash
docker-compose -f docker-compose.production.yml ps
```

## 7. Automatische Updates (Optional)

### Crontab für automatische Backups:
```bash
# Täglich um 2 Uhr
0 2 * * * /opt/rezepte/backup.sh

# Wöchentlich SSL-Zertifikat erneuern
0 3 * * 0 certbot renew --quiet && systemctl reload nginx
```

## 8. Sicherheitshinweise

1. **Firewall konfigurieren**: Nur Ports 22 (SSH), 80 (HTTP), 443 (HTTPS) öffnen
2. **SSH-Key verwenden**: Passwort-Login deaktivieren
3. **Regelmäßige Updates**: System und Docker regelmäßig aktualisieren
4. **Backup-Strategie**: Automatische Backups einrichten
5. **Monitoring**: Log-Monitoring und Alerting einrichten

## Troubleshooting

### Container startet nicht:
```bash
docker-compose -f docker-compose.production.yml logs [service-name]
```

### Database-Probleme:
```bash
# In MySQL-Container einloggen
docker exec -it rezepte-mysql-prod mysql -u root -p

# Database-Status prüfen
SHOW DATABASES;
USE rezepte;
SHOW TABLES;
```

### Permission-Probleme:
```bash
# Upload-Ordner Permissions
docker exec -it rezepte-backend-prod chown -R backend:nodejs /app/uploads
```