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

643 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🚀 Deployment
Anleitung für das Deployment des Ninja Cross Parkour Systems in verschiedenen Umgebungen.
## 📋 Inhaltsverzeichnis
- [🏗️ Deployment-Übersicht](#-deployment-übersicht)
- [🔧 Vorbereitung](#-vorbereitung)
- [🐳 Docker-Deployment](#-docker-deployment)
- [☁️ Cloud-Deployment](#-cloud-deployment)
- [🖥️ VPS-Deployment](#-vps-deployment)
- [🔧 Konfiguration](#-konfiguration)
- [📊 Monitoring](#-monitoring)
- [🔄 CI/CD](#-cicd)
## 🏗️ 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
```bash
# 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
```bash
# .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
```sql
-- 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
```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
```yaml
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
```bash
#!/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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# App Service erstellen
az webapp create \
--resource-group ninja-rg \
--plan ninja-plan \
--name ninja-app \
--runtime "NODE|18-lts"
```
#### PostgreSQL
```bash
# 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
```yaml
# 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
```bash
#!/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
```bash
#!/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
```javascript
// 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
# 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
```bash
# 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
```bash
#!/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
```javascript
// 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
```bash
# 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
```yaml
# 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
```yaml
# .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
```yaml
# .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
```groovy
// 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
```bash
#!/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
```bash
#!/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
```bash
#!/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.