Add README and DEPLOY documentation for HexaHost Panel.

Replace default Laravel README with project overview and link detailed Plesk deployment steps.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
TheOnlyMace
2026-05-17 13:30:07 +02:00
parent 75299b723d
commit 5b260022f8
2 changed files with 473 additions and 38 deletions

323
DEPLOY.md Normal file
View File

@@ -0,0 +1,323 @@
# Deployment auf Plesk HexaHost Panel
Anleitung für **panel.hexahost.de** auf Plesk mit PHP 8.3+, MariaDB, Queue-Worker und Scheduler.
---
## Übersicht
| Komponente | Pflicht | Hinweis |
|------------|---------|---------|
| Document Root → `public/` | Ja | Nicht Projektroot |
| `composer install --no-dev` | Ja | Auf dem Server |
| `npm run build` | Ja | `public/build/` ist nicht im Git |
| MariaDB | Ja (Prod.) | Session, Cache, Queue, Daten |
| Cron `schedule:run` | Ja | Jede Minute |
| Queue-Worker | Ja | WHMCS-Provisioning |
| Traefik-Pfad beschreibbar | Bei Traefik-VMs | Oder Sync von anderem Host |
| Console-Proxy | Optional | Empfohlen für VNC |
---
## 1. Domain & PHP (Plesk)
1. Domain **panel.hexahost.de** anlegen.
2. **Document Root** auf das `public`-Verzeichnis der App setzen, z.B.:
```
/var/www/vhosts/panel.hexahost.de/panel-app/public
```
3. **PHP 8.3 oder 8.4** aktivieren.
4. Extensions: `pdo_mysql`, `mbstring`, `openssl`, `curl`, `fileinfo`, `zip`, `bcmath`.
5. **Lets Encrypt** für HTTPS aktivieren.
PHP-Binary notieren (für Cron/Worker), z.B.:
```text
/opt/plesk/php/8.3/bin/php
```
---
## 2. MariaDB (Plesk)
1. Datenbank anlegen: `hexahost_panel`
2. Benutzer `panel_user` mit vollen Rechten auf diese DB.
3. In `.env`:
```env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://panel.hexahost.de
DB_CONNECTION=mariadb
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=hexahost_panel
DB_USERNAME=panel_user
DB_PASSWORD=<sicher>
```
---
## 3. Code deployen
### Per Git (empfohlen)
```bash
cd /var/www/vhosts/panel.hexahost.de
git clone ssh://git@git.hexahost.dev:8006/smueller/HexaHost-Panel.git panel-app
cd panel-app
```
Plesk *Git*-Extension: Repository verknüpfen, Deploy-Pfad `panel-app`, Document Root auf `panel-app/public` zeigen.
### Nicht deployen
- `vendor/`, `node_modules/`, `.env`
- `database/database.sqlite` (nur lokal)
---
## 4. Installation (SSH)
Als **Domain-Systembenutzer** (nicht root, sofern möglich):
```bash
cd /var/www/vhosts/panel.hexahost.de/panel-app
composer install --no-dev --optimize-autoloader
npm ci
npm run build
cp .env.example .env
nano .env # alle Werte für Produktion setzen
php artisan key:generate
php artisan migrate --force
php artisan db:seed --class=HostingSeeder --force # nur beim Erst-Setup
chmod -R ug+rwx storage bootstrap/cache
php artisan config:cache
php artisan route:cache
php artisan view:cache
```
### `.env` Produktions-Checkliste
- [ ] `PROXMOX_TOKEN` gesetzt (API-Token, nicht Root-Passwort)
- [ ] `PLESK_URL`, `PLESK_USER`, `PLESK_PASS`
- [ ] `WHMCS_API_SECRET` (stark, identisch in WHMCS-Modul)
- [ ] `WHMCS_ALLOWED_IPS` = WHMCS-Server-IP
- [ ] `TRAEFIK_PUBLIC_IP`, `TRAEFIK_DYNAMIC_CONFIG_PATH`, `TRAEFIK_RELOAD_COMMAND`
- [ ] Netzwerk: `HOSTING_GATEWAY=10.32.0.1`, `HOSTING_PUBLIC_GATEWAY=185.45.149.241`, `HOSTING_PUBLIC_CIDR=28`
- [ ] Admin-2FA: `ADMIN_2FA_REQUIRED=true`
Nach Seeder: Admin-Passwort ändern, 2FA einrichten.
---
## 5. Scheduler (Cron in Plesk)
**Websites & Domains → panel.hexahost.de → Geplante Aufgaben**
| Feld | Wert |
|------|------|
| Befehl | `/opt/plesk/php/8.3/bin/php /var/www/vhosts/panel.hexahost.de/panel-app/artisan schedule:run` |
| Intervall | **Jede Minute** |
Läuft u.a.: VMID-Freigabe, ISO-Purge, Snapshot-Prune, Metriken.
---
## 6. Queue-Worker (Pflicht)
Ohne Worker bleiben WHMCS-Bestellungen in `jobs` hängen.
### systemd (empfohlen)
Datei `/etc/systemd/system/hexahost-queue.service`:
```ini
[Unit]
Description=HexaHost Panel Queue Worker
After=network.target mariadb.service
[Service]
Type=simple
User=<plesk-domain-user>
Group=psacln
WorkingDirectory=/var/www/vhosts/panel.hexahost.de/panel-app
ExecStart=/opt/plesk/php/8.3/bin/php artisan queue:work database --sleep=3 --tries=3 --max-time=3600
Restart=always
RestartSec=5
StandardOutput=append:/var/www/vhosts/panel.hexahost.de/panel-app/storage/logs/queue.log
StandardError=append:/var/www/vhosts/panel.hexahost.de/panel-app/storage/logs/queue.log
[Install]
WantedBy=multi-user.target
```
```bash
systemctl daemon-reload
systemctl enable --now hexahost-queue
systemctl status hexahost-queue
```
`<plesk-domain-user>` z.B. mit `ls -la /var/www/vhosts/panel.hexahost.de` ermitteln.
### Notlösung (nur wenig Traffic)
Cron jede Minute:
```bash
php artisan queue:work database --stop-when-empty --max-time=55
```
---
## 7. Traefik
Das Panel schreibt Kunden-Routen nach `TRAEFIK_DYNAMIC_CONFIG_PATH` und führt `TRAEFIK_RELOAD_COMMAND` aus.
**Voraussetzungen:**
- Panel-Prozess (PHP-FPM-User) darf die YAML-Datei **schreiben**
- Reload-Befehl ist ausführbar (ggf. `sudoers` für `docker exec …`)
**Traefik auf anderem Server:** Pfad muss per NFS/SSH/rsync erreichbar sein reines Plesk-Upload reicht dann nicht.
Beispiel `.env`:
```env
TRAEFIK_DYNAMIC_CONFIG_PATH=/etc/traefik/dynamic/customers.yaml
TRAEFIK_RELOAD_COMMAND="docker exec traefik kill -HUP 1"
TRAEFIK_PUBLIC_IP=185.45.149.98
```
---
## 8. Console-WebSocket-Proxy (optional)
### `.env`
```env
CONSOLE_PROXY_ENABLED=true
CONSOLE_PROXY_WS_URL=wss://panel.hexahost.de/ws/vm
CONSOLE_PROXY_SECRET=<langes-zufallssecret>
CONSOLE_PROXY_VALIDATE_URL=https://panel.hexahost.de/api/console/validate
```
### Node-Abhängigkeit
```bash
cd panel-app
npm install ws
```
### systemd für Proxy
`/etc/systemd/system/hexahost-console-proxy.service`:
```ini
[Unit]
Description=HexaHost VNC WebSocket Proxy
After=network.target
[Service]
User=<plesk-domain-user>
WorkingDirectory=/var/www/vhosts/panel.hexahost.de/panel-app
Environment=CONSOLE_PROXY_PORT=6090
Environment=CONSOLE_PROXY_SECRET=<gleich wie .env>
Environment=CONSOLE_PROXY_VALIDATE_URL=https://panel.hexahost.de/api/console/validate
ExecStart=/usr/bin/node scripts/console-ws-proxy.mjs
Restart=always
[Install]
WantedBy=multi-user.target
```
### nginx (Plesk zusätzliche nginx-Direktive)
```nginx
location /ws/vm/ {
proxy_pass http://127.0.0.1:6090;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
```
---
## 9. Firewall / Netzwerk
| Quelle | Ziel | Port |
|--------|------|------|
| Panel-Server | Proxmox (hyperion) | 8006/tcp |
| WHMCS-Server | panel.hexahost.de | 443/tcp |
| Panel-Server | Plesk API | 8443/tcp |
---
## 10. WHMCS-Modul
1. `whmcs-module/hexahost/` nach `modules/servers/hexahost/` in WHMCS kopieren.
2. Server in WHMCS anlegen: API-URL `https://panel.hexahost.de/api/whmcs`
3. `WHMCS_API_SECRET` identisch mit Panel-`.env`.
---
## 11. Updates deployen
```bash
cd /var/www/vhosts/panel.hexahost.de/panel-app
php artisan down # optional
git pull
composer install --no-dev --optimize-autoloader
npm ci && npm run build
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart
php artisan up
```
---
## 12. Abnahme-Tests
| Test | Erwartung |
|------|-----------|
| `GET /login` | 200, HexaHost-UI |
| Admin-Login + 2FA | Dashboard |
| VM-Liste / Status | Proxmox erreichbar |
| Manuelle VM / WHMCS-Order | Job verarbeitet, Status `active` |
| Traefik-VM | DNS + YAML + Reload |
| `storage/logs/laravel.log` | keine wiederholten Errors |
| `systemctl status hexahost-queue` | active (running) |
---
## Fehlerbehebung
| Symptom | Lösung |
|---------|--------|
| 500 nach Deploy | `storage/` Rechte, `php artisan config:clear`, Log prüfen |
| Provisioning hängt | Queue-Worker läuft? `jobs`-Tabelle prüfen |
| Keine Traefik-Route | Pfad/Rechte/Reload-Befehl |
| WHMCS 403 | `WHMCS_API_SECRET`, Uhrzeit (Replay), `WHMCS_ALLOWED_IPS` |
| Konsole verbindet nicht | Proxy + nginx WebSocket, VM läuft |
| Assets fehlen | `npm run build` auf Server |
---
## Support-Logs
```bash
tail -f storage/logs/laravel.log
tail -f storage/logs/queue.log # falls konfiguriert
php artisan queue:failed
```