Setup & Installation
Voraussetzungen
| Komponente | Version | Hinweis |
|---|---|---|
| PHP | 8.4+ | Extensions: pdo_pgsql, redis, mbstring, xml, curl, pcov (fuer Coverage/Mutation Testing) |
| PostgreSQL | 15+ | Kein SQLite, kein MySQL in Production. Extension pg_trgm erforderlich |
| Redis | 7+ | Für Cache, Queue-Monitoring, Reverb |
| Node.js | 20+ | Vite Build-Tooling |
| Composer | 2.x | Mit Flux Pro Auth (s. unten) |
| Chromium Libs | — | Fuer OG-Image-Generierung via Puppeteer/Browsershot (s. unten) |
Repository klonen
git clone git@github.com:yeapea/postbox.git
cd postbox
Composer Authentication (Flux Pro)
Flux UI Pro ist ein kommerzielles Package und erfordert Authentifizierung. Die Credentials liegen als composer.auth im Repository:
cp composer.auth auth.json
composer install
Ohne auth.json schlaegt composer install bei livewire/flux-pro fehl.
Location: composer.auth, auth.json (in .gitignore)
Environment konfigurieren
cp .env.example .env
php artisan key:generate
Wichtige .env-Variablen fuer lokale Entwicklung:
# Datenbank
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=postbox_db1
DB_USERNAME=root
DB_PASSWORD=
# Queue & Cache
QUEUE_CONNECTION=database
CACHE_STORE=database
# WebSockets (Reverb)
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=postbox
REVERB_APP_KEY=postbox-key
REVERB_APP_SECRET=postbox-secret
REVERB_HOST=localhost
REVERB_PORT=8081
# Auth (WorkOS SSO)
WORKOS_CLIENT_ID=
WORKOS_API_KEY=
WORKOS_REDIRECT_URL="${APP_URL}/authenticate"
# Admin
POSTBOX_ADMIN_EMAILS=deine@email.de
Datenbank einrichten
# PostgreSQL-Datenbank erstellen
createdb postbox_db1
# pg_trgm Extension aktivieren (fuer Trigram-Suche in Discover + Watcher-Suche)
psql -d postbox_db1 -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
# Migrationen ausfuehren
php artisan migrate
# Optional: Seeder laufen lassen
php artisan db:seed
PostgreSQL Extension: pg_trgm
Die Extension pg_trgm wird fuer Fuzzy-Suche (Trigram-Matching) benoetigt. Sie aktiviert similarity() Funktionen und GIN-Trigram-Indexes auf:
social_profiles.handle_normalized— Discover-Suchesocial_profiles.title— Discover-Suchewatchers.name— Watcher-Suche (manueller Index)
Ohne die Extension schlaegt die Migration 2026_02_21_100000_add_trigram_indexes_for_discover fehl mit:
SQLSTATE[42704]: Undefined object: operator class "gin_trgm_ops" does not exist
Loesung:
# Als DB-Owner oder Superuser:
psql -d postbox_db1 -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
# Falls Berechtigungen fehlen:
sudo -u postgres psql -d postbox_db1 -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
Optionaler Index fuer Watcher-Suche (nicht in Migration, manuell anlegen):
CREATE INDEX CONCURRENTLY watchers_name_trgm_index ON watchers USING gin (name gin_trgm_ops);
Dieser Index beschleunigt ILIKE '%term%' und similarity() Queries auf der Watcher-Indexseite.
Location: database/migrations/, database/seeders/
Frontend-Assets
npm install
npm run dev
Vite laeuft standardmaessig auf http://localhost:5173 und proxied Hot-Module-Replacement.
Location: vite.config.js, package.json
Queue Workers (lokal)
Fuer lokale Entwicklung reicht ein einzelner Worker. In Production laufen mehrere dedizierte Workers:
# Alle Queues in einem Worker (Entwicklung)
php artisan queue:work --queue=imports-youtube,imports-youtube-priority,imports-youtube-video,imports-youtube-video-priority,youtube-related-channels,ai-detection,profile-retry,emails
# Einzelne Queue isoliert testen
php artisan queue:work --queue=imports-youtube --tries=3 --timeout=120
| Queue | Zweck | Timeout |
|---|---|---|
imports-youtube | YouTube Channel Updates | 120s |
imports-youtube-priority | Prioritaets-Updates + Research Batch | 120s (Job-$timeout ueberschreibt: 600s fuer Research) |
imports-youtube-video | Video-Statistiken Sync | 120s |
imports-youtube-video-priority | Prioritaets-Video-Sync | 120s |
youtube-related-channels | Related Channels Discovery | 300s |
ai-detection | Gemini AI Detection | 60s |
profile-retry | Retry inaktiver Profile | 120s |
emails | Notification-Mails, Feedback, Admin-Alerts | 60s |
Wichtig: retry_after in config/queue.php ist auf 3600s gesetzt (statt Laravel-Default 90s). Muss hoeher als der laengste Job-$timeout (aktuell 2400s) sein, sonst gibt der Database-Driver den Job vorzeitig frei. Siehe Konfiguration.
Location: config/queue.php, routes/console.php
WebSocket-Server (Reverb)
php artisan reverb:start
Reverb laeuft auf Port 8081. Die Frontend-Integration nutzt Laravel Echo mit Pusher-Protokoll.
Location: config/reverb.php, config/broadcasting.php, resources/js/echo.js
Nuetzliche Befehle fuer die Entwicklung
# Code-Qualitaet: Rector + Pint + PHPStan (empfohlen vor jedem Commit)
composer lint
# Code-Qualitaet: Dry-Run (CI-Modus, keine Aenderungen)
composer lint:check
# Einzelne Tools
composer rector # Rector apply (Code-Modernisierung)
composer pint # Pint apply (Code-Formatierung)
composer phpstan # PHPStan analyse (statische Analyse, Level 10)
composer phpstan:baseline # PHPStan Baseline neu generieren
# Tests ausfuehren
php artisan test
php artisan test --filter=DashboardRollupTest
php artisan test --parallel
# Mutation Testing
composer mutate # Alle covered Lines mutieren
php artisan test --mutate --class='App\Services\SomeService'
# Cache leeren
php artisan optimize:clear
# Artisan-Befehle auflisten
php artisan list postbox
php artisan list social
php artisan list youtube
# Scheduler manuell triggern
php artisan schedule:run --verbose
# Tinker-Session starten
php artisan tinker
# Collector-Token fuer Browser-Extension erzeugen
php artisan collector:token mein-client
Composer Scripts
Das composer.json definiert ein Setup-Script:
composer setup
Dieses Script fuehrt automatisch composer install, .env-Kopie, key:generate, migrate und npm build aus.
Location: composer.json (scripts-Sektion)
Troubleshooting
composer install schlaegt fehl
# Flux Pro Auth pruefen
cp composer.auth auth.json
composer install
PostgreSQL nicht erreichbar
# Pruefen ob PostgreSQL laeuft
pg_isready -h 127.0.0.1 -p 5432
# Datenbank erstellen falls noetig
createdb postbox_db1
Puppeteer/Browsershot: chrome-headless-shell startet nicht
OG-Image-Generierung nutzt Browsershot (Puppeteer) mit chrome-headless-shell. Auf headless Linux-Servern fehlen haeufig die noetigen GTK/X11-Libraries:
chrome-headless-shell: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file
Loesung — vollstaendige Paketliste (Debian/Ubuntu):
# Ubuntu 22.04 / Debian 12:
sudo apt-get install -y \
libxcomposite1 libxfixes3 libxcursor1 libxi6 libxtst6 \
libxss1 libdrm2 libxshmfence1 fonts-liberation \
libatk1.0-0 libatk-bridge2.0-0 libcups2 libxdamage1 \
libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2 \
libnspr4 libnss3
# Ubuntu 24.04+ (t64-Paketnamen):
sudo apt-get install -y \
libxcomposite1 libxfixes3 libxcursor1 libxi6 libxtst6 \
libxss1 libdrm2 libxshmfence1 fonts-liberation \
libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 libxdamage1 \
libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2t64 \
libnspr4 libnss3
| Paket | Zweck |
|---|---|
libxcomposite1, libxfixes3, libxcursor1, libxi6, libxtst6 | X11 Input/Rendering Extensions |
libxss1 | X11 Screen Saver Extension |
libdrm2, libxshmfence1 | DRM/GPU Shared Memory |
fonts-liberation | Metrisch kompatible Schriften (Arial/Times/Courier) |
libatk1.0-0(t64), libatk-bridge2.0-0(t64) | Accessibility Toolkit |
libcups2(t64) | Drucksystem (von Chromium vorausgesetzt) |
libxdamage1, libxrandr2, libgbm1 | X11 Damage/RandR, Generic Buffer Manager |
libpango-1.0-0, libcairo2 | Text-Rendering und 2D-Grafik |
libasound2(t64) | ALSA Audio (von Chromium vorausgesetzt) |
libnspr4, libnss3 | Mozilla NSS Crypto/TLS Libraries |
Hinweis: Ab Ubuntu 24.04 (Noble) wurden einige Pakete mit dem
t64-Suffix umbenannt (64-bit time_t Transition). Wennlibasound2nicht gefunden wird, stattdessenlibasound2t64verwenden. Die obere Zeile (22.04) und untere Zeile (24.04) unterscheiden sich nur bei 4 Paketen:libatk1.0-0,libatk-bridge2.0-0,libcups2,libasound2.
Diese Dependencies werden von Chromium/Chrome Headless benoetigt, auch wenn kein vollstaendiger Browser installiert ist. Nach Installation den Queue Worker (og-images) neu starten.
Tests fallen auf SQLite zurueck
Wenn PostgreSQL lokal nicht verfuegbar ist, fallen Tests automatisch auf SQLite in-memory zurueck. Einige Tests mit PostgreSQL-spezifischer Syntax (JSONB, ::bigint) werden dann uebersprungen.
Location: tests/Pest.php (Zeile 18-29)