# Blair Dashboard — Deployment Guide ## Node.js + MySQL auf eigenem Linux VPS --- ## 1. Voraussetzungen auf dem Server installieren ```bash # 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 ```bash # 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 ```bash 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 ```bash cd /var/www/blair cp .env.example .env nano .env ``` Ausfüllen: ```env PORT=3000 NODE_ENV=production SESSION_SECRET= DB_HOST=localhost DB_PORT=3306 DB_NAME=blair_dashboard DB_USER=blair_user DB_PASS= DISCORD_CLIENT_ID= DISCORD_CLIENT_SECRET= APP_URL=https://deinedomain.de OWNER_DISCORD_ID= OWNER_DISCORD_NAME= ``` Session Secret generieren: ```bash node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" ``` --- ## 6. Dependencies installieren & starten ```bash 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: ```bash 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 ```bash sudo nano /etc/nginx/sites-available/blair ``` Inhalt: ```nginx 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; } } ``` ```bash 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) ```bash 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).