2026-05-17 21:05:19 +02:00

5.8 KiB

Blair Dashboard — Deployment Guide

Node.js + MySQL auf eigenem Linux VPS


1. Voraussetzungen auf dem Server installieren

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

# MySQL / MariaDB (falls noch nicht vorhanden)
sudo apt install mariadb-server -y
sudo mysql_secure_installation

# PM2 (Prozessmanager — hält den Server am Laufen)
sudo npm install -g pm2

# Nginx (Reverse Proxy)
sudo apt install nginx -y

2. Projekt auf den Server übertragen

# Option A: Per SCP (von deinem PC aus)
scp -r blair-selfhosted/ user@dein-server.de:/var/www/blair

# Option B: Git (empfohlen für Updates)
# Auf dem Server:
cd /var/www
git clone https://github.com/dein-repo/blair-dashboard blair

3. Datenbank einrichten

sudo mysql -u root -p

# Im MySQL-Prompt:
CREATE DATABASE blair_dashboard CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'blair_user'@'localhost' IDENTIFIED BY 'SICHERES_PASSWORT_HIER';
GRANT ALL PRIVILEGES ON blair_dashboard.* TO 'blair_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

# Schema importieren
mysql -u blair_user -p blair_dashboard < /var/www/blair/schema.sql

4. Discord App erstellen

  1. Gehe zu https://discord.com/developers/applications
  2. "New Application" → Name: "Blair Dashboard"
  3. Links → OAuth2 → Redirects → Add Redirect:
    https://deinedomain.de/auth/discord/callback
    
  4. Kopiere Client ID 1505635813072044062 und Client Secret fXQyM6oXGQWR23m3QbilHLTJiObg_kP-

5. .env Datei erstellen

cd /var/www/blair
cp .env.example .env
nano .env

Ausfüllen:

PORT=3000
NODE_ENV=production
SESSION_SECRET=<langer-zufälliger-string>
DB_HOST=localhost 
DB_PORT=3306
DB_NAME=blair_dashboard
DB_USER=blair_user
DB_PASS=<dein-db-passwort>
DISCORD_CLIENT_ID=<deine-discord-client-id>
DISCORD_CLIENT_SECRET=<dein-discord-client-secret>
APP_URL=https://deinedomain.de
OWNER_DISCORD_ID=<deine-discord-id>
OWNER_DISCORD_NAME=<dein-discord-name>

Session Secret generieren:

node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"

6. Dependencies installieren & starten

cd /var/www/blair
npm install

# Testlauf (Fehler prüfen)
node server.js

# Wenn alles läuft: mit PM2 als Dienst starten
pm2 start server.js --name blair
pm2 save
pm2 startup   # zeigt Befehl an, den du dann als root ausführst

PM2 Befehle:

pm2 status        # Status aller Apps
pm2 logs blair    # Live-Logs
pm2 restart blair # Neustart nach Änderungen
pm2 stop blair    # Stoppen

7. Nginx als Reverse Proxy einrichten

sudo nano /etc/nginx/sites-available/blair

Inhalt:

server {
    listen 80;
    server_name deinedomain.de www.deinedomain.de;

    location / {
        proxy_pass         http://localhost:3000;
        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;
    }
}
sudo ln -s /etc/nginx/sites-available/blair /etc/nginx/sites-enabled/
sudo nginx -t          # Konfiguration prüfen
sudo systemctl reload nginx

8. HTTPS mit Let's Encrypt (kostenlos)

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d deinedomain.de -d www.deinedomain.de

# Automatische Erneuerung testen
sudo certbot renew --dry-run

9. Discord OAuth Redirect URL updaten

Wenn du jetzt HTTPS hast, gehe nochmal zu: https://discord.com/developers/applications → deine App → OAuth2 → Redirects

Und aktualisiere zu:

https://deinedomain.de/auth/discord/callback

Fertig! 🎃

Öffne https://deinedomain.de im Browser.

  • Als Admin anmelden: Discord-Login → deine OWNER_DISCORD_ID wird automatisch als erster Admin eingetragen
  • Weitere Admins hinzufügen: Im Admin-Panel → Whitelist-Sektion → Discord ID eingeben

Struktur

blair-selfhosted/
├── server.js              ← Express-Server (Einstiegspunkt)
├── db.js                  ← MySQL Connection Pool
├── schema.sql             ← Datenbankschema + Standardgeister
├── package.json
├── .env.example           ← Kopieren zu .env, ausfüllen
├── middleware/
│   ├── passport.js        ← Discord OAuth + Admin-Check
│   └── auth.js            ← requireAuth / requireAdmin
├── routes/
│   ├── auth.js            ← /auth/discord, /auth/me, /auth/logout
│   ├── api.js             ← /api/ghosts, /api/submissions (public)
│   └── admin.js           ← /admin/* (nur Whitelist-Admins)
└── public/
    └── index.html         ← Das komplette Frontend (SPA)

Sicherheitsarchitektur

Browser
  │
  ├─ GET /auth/me          → Sucht Session → gibt User + isAdmin zurück
  ├─ GET /auth/discord     → Startet Discord OAuth
  ├─ GET /auth/discord/callback → Discord bestätigt → Session anlegen
  │
  ├─ GET /api/ghosts       → Öffentlich, kein Auth nötig
  ├─ POST /api/submissions → Nur eingeloggte User (requireAuth)
  │
  └─ /admin/*              → requireAdmin-Middleware prüft:
                              1. Ist User eingeloggt? (Session)
                              2. Ist Discord-ID in admin_whitelist? (DB-Abfrage)
                              → NEIN → 403 Forbidden
                              → JA  → Route ausführen

Admin-Prüfung passiert bei JEDEM Request live in der DB — wenn du jemanden aus der Whitelist entfernst, verliert er sofort den Zugriff (nicht erst beim nächsten Login).