Files
Ninjaserver/wiki/Deployment.md
2025-09-23 14:13:24 +02:00

13 KiB

🚀 Deployment

Anleitung für das Deployment des Ninja Cross Parkour Systems in verschiedenen Umgebungen.

📋 Inhaltsverzeichnis

🏗️ Deployment-Übersicht

Deployment-Optionen

  • Docker - Containerisierte Bereitstellung
  • Cloud - AWS, Azure, Google Cloud
  • VPS - Virtuelle private Server
  • On-Premise - Lokale Server

System-Anforderungen

  • CPU: 2+ Kerne
  • RAM: 4+ GB
  • Storage: 50+ GB SSD
  • Network: 100+ Mbps

🔧 Vorbereitung

Code vorbereiten

# Repository klonen
git clone <repository-url>
cd ninjaserver

# Abhängigkeiten installieren
npm install

# Produktions-Build erstellen
npm run build

# Tests ausführen
npm test

Umgebungsvariablen

# .env.production erstellen
cp .env.example .env.production

# Produktionswerte setzen
NODE_ENV=production
PORT=3000
DB_HOST=production-db-host
DB_PORT=5432
DB_NAME=ninjaserver
DB_USER=ninja_user
DB_PASSWORD=secure_password
JWT_SECRET=your_jwt_secret_here
SESSION_SECRET=your_session_secret_here

Datenbank vorbereiten

-- Produktionsdatenbank erstellen
CREATE DATABASE ninjaserver;
CREATE USER ninja_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE ninjaserver TO ninja_user;

-- Schema initialisieren
\c ninjaserver
\i scripts/init-db.sql

🐳 Docker-Deployment

Dockerfile

# Multi-stage build
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:18-alpine AS runtime

# Sicherheitsupdates
RUN apk update && apk upgrade

# Nicht-root Benutzer erstellen
RUN addgroup -g 1001 -S nodejs
RUN adduser -S ninja -u 1001

WORKDIR /app

# Abhängigkeiten kopieren
COPY --from=builder /app/node_modules ./node_modules
COPY . .

# Berechtigungen setzen
RUN chown -R ninja:nodejs /app
USER ninja

# Port freigeben
EXPOSE 3000

# Health Check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Anwendung starten
CMD ["npm", "start"]

Docker Compose

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_NAME=ninjaserver
      - DB_USER=ninja_user
      - DB_PASSWORD=secure_password
    depends_on:
      - postgres
      - redis
    volumes:
      - ./logs:/app/logs
    restart: unless-stopped

  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=ninjaserver
      - POSTGRES_USER=ninja_user
      - POSTGRES_PASSWORD=secure_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
    ports:
      - "5432:5432"
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

Deployment-Skript

#!/bin/bash
# deploy.sh

set -e

echo "🚀 Starting deployment..."

# Docker Images bauen
echo "📦 Building Docker images..."
docker-compose build

# Alte Container stoppen
echo "🛑 Stopping old containers..."
docker-compose down

# Neue Container starten
echo "▶️ Starting new containers..."
docker-compose up -d

# Health Check
echo "🔍 Checking health..."
sleep 30
curl -f http://localhost:3000/health || exit 1

echo "✅ Deployment completed successfully!"

☁️ Cloud-Deployment

AWS Deployment

EC2-Instanz

# EC2-Instanz starten
aws ec2 run-instances \
  --image-id ami-0c02fb55956c7d316 \
  --instance-type t3.medium \
  --key-name ninja-key \
  --security-groups ninja-sg \
  --user-data file://user-data.sh

RDS-Datenbank

# RDS-Instanz erstellen
aws rds create-db-instance \
  --db-instance-identifier ninja-db \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --master-username ninja_user \
  --master-user-password secure_password \
  --allocated-storage 20

Load Balancer

# Application Load Balancer erstellen
aws elbv2 create-load-balancer \
  --name ninja-alb \
  --subnets subnet-12345 subnet-67890 \
  --security-groups sg-12345

Azure Deployment

App Service

# App Service erstellen
az webapp create \
  --resource-group ninja-rg \
  --plan ninja-plan \
  --name ninja-app \
  --runtime "NODE|18-lts"

PostgreSQL

# PostgreSQL-Server erstellen
az postgres flexible-server create \
  --resource-group ninja-rg \
  --name ninja-db \
  --admin-user ninja_user \
  --admin-password secure_password \
  --sku-name Standard_B1ms

Google Cloud Deployment

Cloud Run

# cloudbuild.yaml
steps:
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/$PROJECT_ID/ninja-app', '.']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/ninja-app']
  - name: 'gcr.io/cloud-builders/gcloud'
    args: ['run', 'deploy', 'ninja-app', '--image', 'gcr.io/$PROJECT_ID/ninja-app', '--region', 'europe-west1']

🖥️ VPS-Deployment

Server-Setup

#!/bin/bash
# server-setup.sh

# System aktualisieren
sudo apt update && sudo apt upgrade -y

# Node.js installieren
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# PostgreSQL installieren
sudo apt install postgresql postgresql-contrib -y

# Nginx installieren
sudo apt install nginx -y

# PM2 installieren
sudo npm install -g pm2

# Firewall konfigurieren
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

Anwendung deployen

#!/bin/bash
# deploy-vps.sh

# Code aktualisieren
git pull origin main

# Abhängigkeiten installieren
npm install --production

# Datenbank migrieren
npm run migrate

# Anwendung starten
pm2 start ecosystem.config.js

# Nginx konfigurieren
sudo cp nginx.conf /etc/nginx/sites-available/ninja
sudo ln -s /etc/nginx/sites-available/ninja /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

PM2-Konfiguration

// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'ninja-app',
    script: 'server.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: './logs/err.log',
    out_file: './logs/out.log',
    log_file: './logs/combined.log',
    time: true
  }]
};

🔧 Konfiguration

Nginx-Konfiguration

# nginx.conf
upstream ninja_app {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    server_name ninja.reptilfpv.de;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name ninja.reptilfpv.de;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # Security Headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Rate Limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req zone=api burst=20 nodelay;

    location / {
        proxy_pass http://ninja_app;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }

    # Static Files
    location /static/ {
        alias /var/www/ninja/public/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

SSL-Zertifikat

# Let's Encrypt
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d ninja.reptilfpv.de

# Automatische Erneuerung
echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab -

Datenbank-Backup

#!/bin/bash
# backup.sh

# Tägliches Backup
pg_dump -h localhost -U ninja_user -d ninjaserver | gzip > backup_$(date +%Y%m%d).sql.gz

# Alte Backups löschen (älter als 30 Tage)
find /backups -name "backup_*.sql.gz" -mtime +30 -delete

# Backup nach S3 hochladen
aws s3 cp backup_$(date +%Y%m%d).sql.gz s3://ninja-backups/

📊 Monitoring

Application Monitoring

// monitoring.js
const prometheus = require('prom-client');

// Metriken definieren
const httpRequestDuration = new prometheus.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in seconds',
  labelNames: ['method', 'route', 'status_code']
});

const activeConnections = new prometheus.Gauge({
  name: 'active_connections',
  help: 'Number of active connections'
});

// Metriken-Endpoint
app.get('/metrics', (req, res) => {
  res.set('Content-Type', prometheus.register.contentType);
  res.end(prometheus.register.metrics());
});

Log-Monitoring

# Logstash-Konfiguration
input {
  file {
    path => "/var/log/ninja/*.log"
    type => "ninja-logs"
  }
}

filter {
  if [type] == "ninja-logs" {
    grok {
      match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:message}" }
    }
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "ninja-logs-%{+YYYY.MM.dd}"
  }
}

Alerting

# alertmanager.yml
global:
  smtp_smarthost: 'localhost:587'
  smtp_from: 'alerts@ninjaparkour.de'

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'web.hook'

receivers:
- name: 'web.hook'
  email_configs:
  - to: 'admin@ninjaparkour.de'
    subject: 'Ninja Parkour Alert: {{ .GroupLabels.alertname }}'
    body: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'

🔄 CI/CD

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: '18'
    - run: npm ci
    - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Deploy to production
      run: |
        ssh user@server 'cd /var/www/ninja && git pull && npm install && pm2 restart ninja-app'

GitLab CI

# .gitlab-ci.yml
stages:
  - test
  - deploy

test:
  stage: test
  script:
    - npm ci
    - npm test

deploy:
  stage: deploy
  script:
    - ssh user@server 'cd /var/www/ninja && git pull && npm install && pm2 restart ninja-app'
  only:
    - main

Jenkins Pipeline

// Jenkinsfile
pipeline {
    agent any
    
    stages {
        stage('Test') {
            steps {
                sh 'npm ci'
                sh 'npm test'
            }
        }
        
        stage('Deploy') {
            steps {
                sh 'ssh user@server "cd /var/www/ninja && git pull && npm install && pm2 restart ninja-app"'
            }
        }
    }
}

🔧 Wartung

Automatische Updates

#!/bin/bash
# auto-update.sh

# System-Updates
sudo apt update && sudo apt upgrade -y

# Anwendung-Updates
cd /var/www/ninja
git pull origin main
npm install --production
pm2 restart ninja-app

# Datenbank-Updates
npm run migrate

Health Checks

#!/bin/bash
# health-check.sh

# Anwendung prüfen
curl -f http://localhost:3000/health || exit 1

# Datenbank prüfen
psql -d ninjaserver -c "SELECT NOW();" || exit 1

# Speicher prüfen
if [ $(df / | awk 'NR==2{print $5}' | sed 's/%//') -gt 80 ]; then
    echo "Disk space low"
    exit 1
fi

Rollback-Strategie

#!/bin/bash
# rollback.sh

# Vorherige Version wiederherstellen
cd /var/www/ninja
git checkout HEAD~1
npm install --production
pm2 restart ninja-app

# Datenbank-Rollback
psql -d ninjaserver < backup_previous.sql

Hinweis: Diese Deployment-Anleitung sollte an Ihre spezifischen Anforderungen angepasst werden. Testen Sie alle Schritte in einer Staging-Umgebung vor der Produktionsbereitstellung.