582 lines
13 KiB
Markdown
582 lines
13 KiB
Markdown
# TimeClock v3 - Deployment Guide für Ubuntu 22.04
|
|
|
|
Dieser Guide beschreibt das komplette Deployment der TimeClock-App auf einem Ubuntu 22.04 Server unter der URL **stechuhr3.tsschulz.de**.
|
|
|
|
## Voraussetzungen
|
|
|
|
### Software-Anforderungen
|
|
- Ubuntu 22.04 LTS
|
|
- Node.js v18+ (empfohlen: v20)
|
|
- MySQL 8.0 oder MariaDB 10.6+
|
|
- Nginx
|
|
- Certbot (für SSL/Let's Encrypt)
|
|
- PM2 oder systemd für Process Management
|
|
|
|
### Domain & DNS
|
|
- Domain: `stechuhr3.tsschulz.de`
|
|
- DNS A-Record muss auf die Server-IP zeigen
|
|
|
|
## Schritt 1: System-Vorbereitung
|
|
|
|
```bash
|
|
# System aktualisieren
|
|
sudo apt update && sudo apt upgrade -y
|
|
|
|
# Node.js 20.x installieren
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
sudo apt install -y nodejs
|
|
|
|
# Nginx installieren
|
|
sudo apt install -y nginx
|
|
|
|
# Certbot für SSL installieren
|
|
sudo apt install -y certbot python3-certbot-nginx
|
|
|
|
# PM2 global installieren (empfohlen)
|
|
sudo npm install -g pm2
|
|
|
|
# MySQL/MariaDB sollte bereits installiert sein
|
|
# Falls nicht:
|
|
# sudo apt install -y mysql-server
|
|
```
|
|
|
|
## Schritt 2: Datenbank vorbereiten
|
|
|
|
```bash
|
|
# In MySQL/MariaDB einloggen
|
|
sudo mysql -u root -p
|
|
|
|
# Datenbank und User erstellen (falls noch nicht vorhanden)
|
|
CREATE DATABASE IF NOT EXISTS stechuhr2;
|
|
CREATE USER IF NOT EXISTS 'timeclock'@'localhost' IDENTIFIED BY 'SICHERES_PASSWORT';
|
|
GRANT ALL PRIVILEGES ON stechuhr2.* TO 'timeclock'@'localhost';
|
|
FLUSH PRIVILEGES;
|
|
EXIT;
|
|
|
|
# Schema importieren (falls noch nicht vorhanden)
|
|
# mysql -u timeclock -p stechuhr2 < backend/database-schema.sql
|
|
```
|
|
|
|
## Schritt 3: Projekt auf Server klonen/übertragen
|
|
|
|
```bash
|
|
# Projekt-Verzeichnis erstellen
|
|
sudo mkdir -p /var/www
|
|
cd /var/www
|
|
|
|
# Mit Git klonen (oder per SCP übertragen)
|
|
# sudo git clone https://github.com/IHR-USERNAME/TimeClock.git timeclock
|
|
# ODER das lokale Projekt übertragen:
|
|
# rsync -avz --exclude 'node_modules' ~/Programs/TimeClock/ user@server:/var/www/timeclock/
|
|
|
|
# Eigentümer setzen
|
|
sudo chown -R $USER:$USER /var/www/timeclock
|
|
```
|
|
|
|
## Schritt 4: Backend konfigurieren
|
|
|
|
```bash
|
|
cd /var/www/timeclock/backend
|
|
|
|
# Dependencies installieren
|
|
npm install --production
|
|
|
|
# .env Datei erstellen
|
|
cp .env.production.example .env
|
|
|
|
# .env bearbeiten und folgende Werte anpassen:
|
|
nano .env
|
|
```
|
|
|
|
**Wichtige .env Variablen:**
|
|
```env
|
|
NODE_ENV=production
|
|
PORT=3010
|
|
|
|
# Datenbank
|
|
DB_HOST=localhost
|
|
DB_NAME=stechuhr2
|
|
DB_USER=timeclock
|
|
DB_PASSWORD=IHR_DB_PASSWORT
|
|
|
|
# JWT
|
|
JWT_SECRET=IHR_SICHERER_JWT_SECRET_KEY
|
|
JWT_EXPIRES_IN=7d
|
|
|
|
# Session
|
|
SESSION_SECRET=IHR_SICHERER_SESSION_SECRET
|
|
|
|
# Frontend URL
|
|
FRONTEND_URL=https://stechuhr3.tsschulz.de
|
|
|
|
# Email (optional, für Passwort-Reset)
|
|
EMAIL_HOST=smtp.example.com
|
|
EMAIL_PORT=587
|
|
EMAIL_USER=your-email@example.com
|
|
EMAIL_PASSWORD=your-email-password
|
|
EMAIL_FROM=noreply@tsschulz.de
|
|
|
|
# OAuth (optional, falls Google OAuth verwendet wird)
|
|
GOOGLE_CLIENT_ID=your-client-id
|
|
GOOGLE_CLIENT_SECRET=your-client-secret
|
|
GOOGLE_CALLBACK_URL=https://stechuhr3.tsschulz.de/api/auth/oauth/google/callback
|
|
```
|
|
|
|
## Schritt 5: Frontend bauen
|
|
|
|
```bash
|
|
cd /var/www/timeclock/frontend
|
|
|
|
# Dependencies installieren
|
|
npm install
|
|
|
|
# Produktions-Build erstellen
|
|
npm run build
|
|
|
|
# Build-Dateien werden in /var/www/timeclock/frontend/dist erstellt
|
|
```
|
|
|
|
## Schritt 6: Nginx konfigurieren
|
|
|
|
```bash
|
|
# Nginx-Konfiguration erstellen
|
|
sudo nano /etc/nginx/sites-available/stechuhr3.tsschulz.de
|
|
```
|
|
|
|
Folgende Konfiguration einfügen (siehe `nginx.conf` im Projekt):
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name stechuhr3.tsschulz.de;
|
|
|
|
# Zunächst nur HTTP für Certbot
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/certbot;
|
|
}
|
|
|
|
location / {
|
|
return 301 https://$server_name$request_uri;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name stechuhr3.tsschulz.de;
|
|
|
|
# SSL-Zertifikate (werden von Certbot automatisch eingefügt)
|
|
ssl_certificate /etc/letsencrypt/live/stechuhr3.tsschulz.de/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/stechuhr3.tsschulz.de/privkey.pem;
|
|
|
|
# SSL-Konfiguration
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
|
|
|
# Frontend (Vue.js SPA)
|
|
root /var/www/timeclock/frontend/dist;
|
|
index index.html;
|
|
|
|
# Logging
|
|
access_log /var/log/nginx/stechuhr3.access.log;
|
|
error_log /var/log/nginx/stechuhr3.error.log;
|
|
|
|
# Gzip Compression
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_min_length 1024;
|
|
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
|
|
|
# API Proxy zum Backend
|
|
location /api {
|
|
proxy_pass http://localhost:3010;
|
|
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;
|
|
|
|
# Timeouts
|
|
proxy_connect_timeout 60s;
|
|
proxy_send_timeout 60s;
|
|
proxy_read_timeout 60s;
|
|
}
|
|
|
|
# SPA Fallback - alle anderen Requests zu index.html
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# Cache für statische Assets
|
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
# Security Headers
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
}
|
|
```
|
|
|
|
```bash
|
|
# Konfiguration aktivieren
|
|
sudo ln -s /etc/nginx/sites-available/stechuhr3.tsschulz.de /etc/nginx/sites-enabled/
|
|
|
|
# Default-Seite deaktivieren (optional)
|
|
sudo rm -f /etc/nginx/sites-enabled/default
|
|
|
|
# Nginx-Konfiguration testen
|
|
sudo nginx -t
|
|
|
|
# Nginx neuladen
|
|
sudo systemctl reload nginx
|
|
```
|
|
|
|
## Schritt 7: SSL-Zertifikat mit Let's Encrypt
|
|
|
|
```bash
|
|
# Certbot ausführen
|
|
sudo certbot --nginx -d stechuhr3.tsschulz.de
|
|
|
|
# Folgen Sie den Anweisungen:
|
|
# - E-Mail-Adresse eingeben
|
|
# - Nutzungsbedingungen akzeptieren
|
|
# - Optional: Newsletter ablehnen
|
|
# - HTTPS-Redirect: Ja (empfohlen)
|
|
|
|
# Automatische Erneuerung testen
|
|
sudo certbot renew --dry-run
|
|
```
|
|
|
|
## Schritt 8: Backend als Service einrichten
|
|
|
|
### Option A: PM2 (empfohlen)
|
|
|
|
```bash
|
|
cd /var/www/timeclock/backend
|
|
|
|
# Backend mit PM2 starten
|
|
pm2 start src/index.js --name timeclock-backend --env production
|
|
|
|
# PM2 Auto-Start konfigurieren
|
|
pm2 startup systemd
|
|
# Führen Sie den angezeigten Befehl aus
|
|
|
|
# Aktuelle PM2-Prozesse speichern
|
|
pm2 save
|
|
|
|
# Status überprüfen
|
|
pm2 status
|
|
pm2 logs timeclock-backend
|
|
```
|
|
|
|
### Option B: Systemd Service
|
|
|
|
```bash
|
|
# Service-Datei erstellen
|
|
sudo nano /etc/systemd/system/timeclock.service
|
|
```
|
|
|
|
Folgende Konfiguration einfügen:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=TimeClock v3 Backend API
|
|
After=network.target mysql.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=www-data
|
|
WorkingDirectory=/var/www/timeclock/backend
|
|
Environment=NODE_ENV=production
|
|
ExecStart=/usr/bin/node src/index.js
|
|
Restart=always
|
|
RestartSec=10
|
|
StandardOutput=append:/var/log/timeclock/backend.log
|
|
StandardError=append:/var/log/timeclock/backend.error.log
|
|
|
|
# Sicherheit
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=true
|
|
ReadWritePaths=/var/www/timeclock/backend
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
```bash
|
|
# Log-Verzeichnis erstellen
|
|
sudo mkdir -p /var/log/timeclock
|
|
sudo chown www-data:www-data /var/log/timeclock
|
|
|
|
# Service aktivieren und starten
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable timeclock
|
|
sudo systemctl start timeclock
|
|
|
|
# Status prüfen
|
|
sudo systemctl status timeclock
|
|
|
|
# Logs ansehen
|
|
sudo journalctl -u timeclock -f
|
|
```
|
|
|
|
## Schritt 9: Firewall konfigurieren
|
|
|
|
```bash
|
|
# UFW Firewall aktivieren (falls noch nicht aktiv)
|
|
sudo ufw allow ssh
|
|
sudo ufw allow 'Nginx Full'
|
|
sudo ufw enable
|
|
|
|
# Status prüfen
|
|
sudo ufw status
|
|
```
|
|
|
|
## Schritt 10: Deployment testen
|
|
|
|
```bash
|
|
# Backend-Health-Check
|
|
curl http://localhost:3010/api/health
|
|
|
|
# Frontend über Domain aufrufen
|
|
# https://stechuhr3.tsschulz.de
|
|
|
|
# SSL-Test
|
|
curl -I https://stechuhr3.tsschulz.de
|
|
```
|
|
|
|
## Wartung und Updates
|
|
|
|
### Backend aktualisieren
|
|
|
|
```bash
|
|
cd /var/www/timeclock/backend
|
|
git pull # oder neue Dateien übertragen
|
|
npm install --production
|
|
|
|
# Mit PM2:
|
|
pm2 restart timeclock-backend
|
|
|
|
# Mit systemd:
|
|
sudo systemctl restart timeclock
|
|
```
|
|
|
|
### Frontend aktualisieren
|
|
|
|
```bash
|
|
cd /var/www/timeclock/frontend
|
|
git pull # oder neue Dateien übertragen
|
|
npm install
|
|
npm run build
|
|
# Nginx cached automatisch neu
|
|
```
|
|
|
|
### Logs überwachen
|
|
|
|
```bash
|
|
# PM2 Logs
|
|
pm2 logs timeclock-backend
|
|
|
|
# Systemd Logs
|
|
sudo journalctl -u timeclock -f
|
|
|
|
# Nginx Logs
|
|
sudo tail -f /var/log/nginx/stechuhr3.access.log
|
|
sudo tail -f /var/log/nginx/stechuhr3.error.log
|
|
```
|
|
|
|
### Datenbank-Backup
|
|
|
|
```bash
|
|
# Tägliches Backup einrichten
|
|
sudo nano /usr/local/bin/backup-timeclock.sh
|
|
```
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
BACKUP_DIR="/var/backups/timeclock"
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|
mkdir -p $BACKUP_DIR
|
|
|
|
# Datenbank-Backup
|
|
mysqldump -u timeclock -p'IHR_PASSWORT' stechuhr2 | gzip > $BACKUP_DIR/timeclock_$DATE.sql.gz
|
|
|
|
# Alte Backups löschen (älter als 30 Tage)
|
|
find $BACKUP_DIR -name "timeclock_*.sql.gz" -mtime +30 -delete
|
|
|
|
echo "Backup erstellt: timeclock_$DATE.sql.gz"
|
|
```
|
|
|
|
```bash
|
|
# Ausführbar machen
|
|
sudo chmod +x /usr/local/bin/backup-timeclock.sh
|
|
|
|
# Cronjob einrichten (täglich um 2 Uhr)
|
|
sudo crontab -e
|
|
# Folgende Zeile hinzufügen:
|
|
# 0 2 * * * /usr/local/bin/backup-timeclock.sh
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Backend startet nicht
|
|
|
|
```bash
|
|
# Logs prüfen
|
|
pm2 logs timeclock-backend --err
|
|
# oder
|
|
sudo journalctl -u timeclock -n 50
|
|
|
|
# Port-Belegung prüfen
|
|
sudo netstat -tulpn | grep 3010
|
|
|
|
# .env Datei prüfen
|
|
cat /var/www/timeclock/backend/.env
|
|
```
|
|
|
|
### Frontend zeigt nicht an
|
|
|
|
```bash
|
|
# Nginx-Konfiguration testen
|
|
sudo nginx -t
|
|
|
|
# Nginx neuladen
|
|
sudo systemctl reload nginx
|
|
|
|
# Dist-Verzeichnis prüfen
|
|
ls -la /var/www/timeclock/frontend/dist/
|
|
```
|
|
|
|
### SSL-Probleme
|
|
|
|
```bash
|
|
# Zertifikat erneuern
|
|
sudo certbot renew --force-renewal -d stechuhr3.tsschulz.de
|
|
|
|
# Nginx neustarten
|
|
sudo systemctl restart nginx
|
|
```
|
|
|
|
### API-Requests schlagen fehl
|
|
|
|
```bash
|
|
# CORS-Probleme: FRONTEND_URL in .env prüfen
|
|
# Nginx Proxy-Konfiguration prüfen
|
|
sudo nginx -t
|
|
|
|
# Backend-Logs prüfen
|
|
pm2 logs timeclock-backend
|
|
```
|
|
|
|
## Performance-Optimierung
|
|
|
|
### PM2 Cluster-Modus (optional)
|
|
|
|
```bash
|
|
cd /var/www/timeclock/backend
|
|
|
|
# PM2 im Cluster-Modus starten (nutzt alle CPU-Kerne)
|
|
pm2 delete timeclock-backend
|
|
pm2 start src/index.js --name timeclock-backend --instances max --env production
|
|
pm2 save
|
|
```
|
|
|
|
### Nginx Caching (optional)
|
|
|
|
Füge in der Nginx-Konfiguration hinzu:
|
|
|
|
```nginx
|
|
# Im http-Block von /etc/nginx/nginx.conf
|
|
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=100m inactive=60m use_temp_path=off;
|
|
|
|
# Im server-Block der stechuhr3.tsschulz.de Konfiguration
|
|
location /api {
|
|
proxy_cache api_cache;
|
|
proxy_cache_valid 200 5m;
|
|
proxy_cache_bypass $http_cache_control;
|
|
add_header X-Cache-Status $upstream_cache_status;
|
|
|
|
# ... rest der proxy_pass Konfiguration
|
|
}
|
|
```
|
|
|
|
## Sicherheits-Checkliste
|
|
|
|
- [x] SSL/TLS aktiviert (Let's Encrypt)
|
|
- [x] Firewall konfiguriert (UFW)
|
|
- [x] Starke Passwörter für DB und JWT_SECRET
|
|
- [x] NODE_ENV=production gesetzt
|
|
- [x] Nginx Security Headers aktiviert
|
|
- [x] Backend läuft nicht als Root
|
|
- [x] Regelmäßige Backups eingerichtet
|
|
- [ ] fail2ban installieren (optional)
|
|
- [ ] Rate Limiting in Nginx konfigurieren (optional)
|
|
- [ ] ModSecurity WAF installieren (optional)
|
|
|
|
## Monitoring (optional)
|
|
|
|
### PM2 Plus Monitoring
|
|
|
|
```bash
|
|
# PM2 Plus Account erstellen: https://id.keymetrics.io
|
|
pm2 plus
|
|
# Link folgen und Account verbinden
|
|
```
|
|
|
|
### Einfaches Uptime-Monitoring
|
|
|
|
```bash
|
|
# Einfaches Health-Check Script
|
|
sudo nano /usr/local/bin/check-timeclock.sh
|
|
```
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
if ! curl -sf http://localhost:3010/api/health > /dev/null; then
|
|
echo "Backend ist down! $(date)" >> /var/log/timeclock/health-check.log
|
|
pm2 restart timeclock-backend
|
|
# oder: sudo systemctl restart timeclock
|
|
fi
|
|
```
|
|
|
|
```bash
|
|
# Ausführbar machen
|
|
sudo chmod +x /usr/local/bin/check-timeclock.sh
|
|
|
|
# Cronjob alle 5 Minuten
|
|
sudo crontab -e
|
|
# */5 * * * * /usr/local/bin/check-timeclock.sh
|
|
```
|
|
|
|
## Zusammenfassung der Endpunkte
|
|
|
|
- **Frontend:** https://stechuhr3.tsschulz.de
|
|
- **API:** https://stechuhr3.tsschulz.de/api
|
|
- **Health-Check:** https://stechuhr3.tsschulz.de/api/health
|
|
|
|
## Support
|
|
|
|
Bei Problemen:
|
|
1. Logs prüfen (`pm2 logs` oder `journalctl -u timeclock`)
|
|
2. Nginx-Logs prüfen (`/var/log/nginx/`)
|
|
3. Datenbank-Verbindung testen
|
|
4. .env Konfiguration überprüfen
|
|
|
|
---
|
|
|
|
**Deployment erfolgreich! 🎉**
|
|
|
|
Ihre TimeClock-App läuft jetzt auf https://stechuhr3.tsschulz.de
|
|
|