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:
323
DEPLOY.md
Normal file
323
DEPLOY.md
Normal 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. **Let’s 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
|
||||
```
|
||||
Reference in New Issue
Block a user