Update
This commit is contained in:
642
wiki/Deployment.md
Normal file
642
wiki/Deployment.md
Normal file
@@ -0,0 +1,642 @@
|
||||
# 🚀 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.
|
||||
Reference in New Issue
Block a user