Replace default Laravel README with project overview and link detailed Plesk deployment steps. Co-authored-by: Cursor <cursoragent@cursor.com>
324 lines
7.8 KiB
Markdown
324 lines
7.8 KiB
Markdown
# 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
|
||
```
|