← Blog

Laravel deployen, ohne eine Queue-Worker-Config von Hand zu schreiben

Railyard

12. Oktober 2026 · 2 Min. Lesezeit

Das Nervige am Hosting einer echten Laravel-App liegt meist nicht an Laravel selbst — sondern daran, dass ein typischer Host seine eigene Config-Datei, seine eigene Queue-Worker-Prozessdefinition und seine eigene Kopie von dem will, was in .env.example längst steht. Die Information, die tatsächlich nötig ist, um die App korrekt zu betreiben, existiert schon im Repo; der Hosting-Schritt sollte nicht nochmal danach fragen müssen.

Was automatisch gelesen wird

Bei jedem Push parst Railyard composer.json und .env.example und verdrahtet, was Laravel bereits selbst über sich deklariert:

  • DB_CONNECTION=pgsql oder mysql in .env.example entscheidet, welche Datenbank-Engine tatsächlich provisioniert wird — kein Dropdown zur manuellen Auswahl.
  • php artisan migrate --force läuft als Release-Schritt vor jedem Deploy.
  • APP_KEY wird einmalig generiert, in Laravels eigenem base64:-Format, und verschlüsselt gespeichert — du musst nie selbst php artisan key:generate ausführen und das Ergebnis irgendwo einfügen.
  • QUEUE_CONNECTION, CACHE_STORE, SESSION_DRIVER oder BROADCAST_CONNECTION auf redis gesetzt (oder laravel/horizon überhaupt vorhanden) provisioniert Redis und injiziert die Verbindungsvariablen, ohne dass du ein Addon von Hand hinzufügen musst.
railyard create my-app https://github.com/me/my-app --addons mysql,redis

oder dasselbe über das Dashboard, sobald GitHub verbunden ist — jeder Push danach baut und deployt automatisch neu.

Queue-Worker sind ein Prozesstyp, kein Cron-Hack

Ist laravel/horizon installiert, läuft der queue-Prozess mit php artisan horizon statt dem einfachen queue:work — erkannt aus composer.json, nicht von Hand konfiguriert. Ist laravel/reverb installiert, kommt genauso ein reverb-Prozess mit php artisan reverb:start dazu. Jeder davon ist derselbe Build wie web, nur mit einem anderen artisan-Befehl gestartet und unabhängig skalierbar:

web:    php artisan octane:start --server=frankenphp --host=0.0.0.0 --port=$PORT
queue:  php artisan horizon
reverb: php artisan reverb:start
railyard scale my-app queue=2

Ein scheduler-Prozess wird ebenfalls angeboten, sobald routes/console.php oder bootstrap/app.php irgendetwas plant — er läuft dauerhaft mit php artisan schedule:work, oder du richtest Railyards eigenen Cron auf ein Intervall mit schedule:run aus; beides ist korrekt, da schedule:run nur auslöst, was tatsächlich fällig ist.

Octane, falls die App es schon nutzt

laravel/octane in composer.json ohne eigenes Dockerfile im Repo bedeutet, dass der Web-Prozess automatisch unter FrankenPHP läuft (php artisan octane:start --server=frankenphp) statt dem klassischen PHP-FPM-Request-Zyklus — erkannt, nicht etwas, das du von Hand in einem Procfile verdrahten musst.

Config bleibt Config, kein Rebuild

Alles, was Laravel mit env() liest, liegt unter Variables, oder railyard env:set my-app KEY=VALUE über die CLI — nie fest in das Image gebacken. Derselbe Build läuft unverändert von einem Preview-Branch bis zur Produktion, was der eigentliche Sinn von Dev/Prod-Parität ist: Ein Bug in Staging ist entweder echt oder nicht, nie ein Artefakt davon, dass Staging ein anderes Bundle läuft als Prod.

Vollständige Referenz: Laravel-Docs, Worker und geplante Jobs.

Deploye jetzt eine Laravel-App.

composer.json und .env.example werden automatisch gelesen — Migrationen, Queue-Worker und Datenbank sind direkt verdrahtet.

Kostenloser Plan, keine Kreditkarte, und 14 Tage Pro für jedes neue Team. Ein fester Preis pro Team.