Laravel-Entwicklung

Laravel-Anwendungen – entwickelt und zuverlässig betrieben.

Vom ersten Model bis zu den Queue-Workern, den Deployments und dem Upgrade Jahre später – geschrieben, gehostet und betreut von einem einzigen Team.

Ein Release, wie es auf dem Server aussieht

Jede Laravel-Anwendung, die wir betreiben, geht auf dieselbe Weise live: getestet, gebaut, gecacht und ohne eine Sekunde Ausfallzeit umgeschaltet.

ci ~/app $ php artisan test   PASS  Tests\Feature\CheckoutTest  ✓ a paid order queues the invoice  ✓ a declined card never marks the order paid   PASS  Tests\Unit\VatTest  ✓ vat is added once, on the total app ~/releases/1400 $ composer install --no-dev --optimize-autoloaderInstalling dependencies from lock fileGenerating optimized autoload files app ~/releases/1400 $ php artisan migrate --force   INFO  Running migrations.  2026_09_27_090000_add_due_date_to_invoices ....... DONE app ~/releases/1400 $ php artisan optimize   INFO  Caching framework bootstrap, configuration, and metadata.  config ...................................... DONE  events ...................................... DONE  routes ...................................... DONE  views ....................................... DONE app ~/releases/1400 $ ln -sfn ~/releases/1400 ~/currentapp ~/releases/1400 $ php artisan horizon:terminate && php artisan octane:reload app ~/releases/1400 $ sudo supervisorctl statushorizon                 RUNNING   pid 48211, uptime 0:00:09octane                  RUNNING   pid 31877, uptime 6 days, 2:14:51 app ~/releases/1400 $ php artisan schedule:list  */5 * * * *  php artisan horizon:snapshot ... Next Due: 3 minutes from now  0   2 * * *  php artisan model:prune ........ Next Due: 9 hours from now  0   9 * * *  php artisan invoices:remind .... Next Due: 16 hours from now
Eine Beispielsitzung mit einer Beispielanwendung. Namen, Pfade und Ausgaben dienen nur der Veranschaulichung.
  1. Zuerst die Tests

    Die Tests laufen, bevor irgendetwas den Server erreicht. Ein einziger fehlgeschlagener Test stoppt das Release.

  2. Abhängigkeiten

    Nur aus der Lock-Datei installiert, ohne Entwicklungspakete und mit optimiertem Autoloader.

  3. Migrationen

    So geschrieben, dass der laufende Code auch mit dem neuen Schema funktioniert, während das Release umgeschaltet wird.

  4. Caches

    Konfiguration, Events, Routen und Views werden gecacht. Ab hier wird die Umgebungsdatei gar nicht mehr gelesen – deshalb gehört env() ausschließlich in die Konfigurationsdateien.

  5. Die Umschaltung

    Ein Link wird umgesetzt, und das neue Release ist live. Das vorherige bleibt für einen Rollback auf der Festplatte.

  6. Worker

    Horizon arbeitet die laufenden Jobs noch ab und startet dann mit dem neuen Code neu; Octane lädt seine Worker auf dieselbe Weise neu.

  7. Überwacht

    Supervisor hält Horizon und Octane am Laufen und startet jeden der beiden neu, falls er stoppt.

  8. Der Scheduler

    Eine einzige Cron-Zeile führt jede geplante Aufgabe aus. Das hier läuft als Nächstes.

Vom Klick bis zum erledigten Job

Die langsame Arbeit verlässt die Anfrage. Der Kunde erhält sofort eine Antwort, und ein Worker erledigt den Rest im Hintergrund.

  1. 01 · Anfrage POST /checkout

    Der Kunde bezahlt

    Der Controller validiert die Bestellung, speichert sie und antwortet sofort. Hier passiert nichts Langsames.

  2. 02 · Job PayOrder::dispatch()

    Der langsame Teil wird zum Job

    Erst nach dem Commit der Datenbank abgesetzt, damit ein Worker nie eine Bestellung aufgreift, die zurückgerollt wurde.

  3. 03 · Queue redis · payments

    Er wartet in seiner eigenen Queue

    Zahlungen haben ihre eigene Queue, damit ein langer Export sie nie aufhält.

  4. 04 · Worker horizon · supervisor

    Ein Worker übernimmt ihn

    Mit Timeout, Wiederholungen mit jedes Mal längerer Wartezeit und einer Grenze dafür, wie viele gleichzeitig laufen.

  5. 05 · Benachrichtigung OrderPaid → mail, database

    Alle werden informiert

    Der Kunde erhält die Rechnung per E-Mail, und die Bestellung erscheint in Ihrem Dashboard als bezahlt.

Wenn er immer wieder scheitert failed_jobs

Ein Job, der keine Wiederholungen mehr übrig hat, wird mit seinem Fehler aufbewahrt, und wir werden alarmiert. Sobald die Ursache behoben ist, wird er erneut ausgeführt – er geht nie stillschweigend verloren.

Die ganze Anwendung, nicht nur der Server

Unser Team bringt fünfundzwanzig Jahre PHP-Erfahrung in jedes Laravel-Projekt ein, vom ersten Model bis zum Upgrade Jahre später.

Entwickeln

Die Anwendung selbst.

Architektur
Geschäftslogik in Actions und Services, nicht in Controllern. Form Requests für die Validierung, Policies dafür, wer was darf.
Eloquent
Relationen werden vorab geladen, wo eine Seite sie auflistet – so kostet eine Seite wenige Abfragen statt Hunderter. In der Entwicklung löst Lazy Loading einen Fehler aus, damit das Problem früh auffällt.
Livewire · Inertia
Livewire, wenn das Team PHP und Blade schreibt; Inertia mit Vue oder React, wenn das Frontend ein eigenes Projekt ist.
APIs mit Sanctum
Tokens für mobile Apps und Partner, Cookie-Sessions für Ihr eigenes Frontend und Rate Limits pro Client.
Pest · PHPUnit
Tests für jeden Pfad, bei dem Geld fließt oder E-Mails verschickt werden – bei jedem Push ausgeführt, bevor ein Release gebaut wird.

Betreiben

Was sie reaktionsfähig hält.

Queues und Horizon
Getrennte Queues für dringende Aufgaben und Massenverarbeitung, jede mit eigenen Workern, Timeouts und Wiederholungen, überwacht im Horizon-Dashboard.
Der Scheduler
Eine Cron-Zeile führt jede Aufgabe aus. Aufgaben, die sich nicht überschneiden dürfen oder nur auf einem Server laufen sollen, werden entsprechend markiert.
Octane
Swoole, RoadRunner oder FrankenPHP halten die Anwendung zwischen den Anfragen im Speicher. Bevor wir das einschalten, prüfen wir den Code auf Zustand, der von einer Anfrage in die nächste durchsickert.
Redis
Cache, Sessions, Queues und Locks auf einem Redis, der aus dem Internet nicht erreichbar ist.
Supervisor
Queue-Worker, Horizon und Octane laufen als überwachte Prozesse und werden neu gestartet, wenn sie stoppen, sowie nach jedem Release.

Pflegen

Was sie aktuell hält.

Deployments ohne Ausfallzeit
Jedes Release wird in einem eigenen Verzeichnis gebaut und mit einem Link aktiviert. Der Weg zurück ist derselbe Schritt in umgekehrter Richtung.
Logs und Exceptions
Tägliche Logdateien, die für eine festgelegte Zeit aufbewahrt werden, und jede Exception wird uns zusammen mit der Anfrage gemeldet, die sie ausgelöst hat.
Upgrades
Laravel veröffentlicht jedes Jahr eine neue Hauptversion. Wir heben eine Anwendung Version für Version an, und bei jedem Schritt laufen die Tests erfolgreich durch.

Was wir am ersten Tag einrichten

Bevor der erste Kunde kommt, ist all das auf jedem Laravel-Server, den wir betreiben, bereits eingerichtet.

  • Debug-Modus in der Produktion aus, und nur das öffentliche Verzeichnis im Web erreichbarAPP_DEBUG=false
  • Queue-Worker unter Supervisor, bei jedem Release neu gestartetsupervisord
  • Eine Cron-Zeile für den Scheduler* * * * * php artisan schedule:run
  • Redis für Cache, Sessions und QueuesCACHE_STORE=redis
  • Konfiguration, Events, Routen und Views bei jedem Release gecachtphp artisan optimize
  • OPcache aktiv und bei jedem Release zurückgesetztopcache.validate_timestamps=0
  • Ein PHP-FPM-Pool, passend zum Arbeitsspeicher des Serverspm.max_children
  • Releases in eigenen Verzeichnissen, nur einen Schritt vom Rollback entferntcurrent → releases/…
  • Fehlgeschlagene Jobs werden uns gemeldet, statt in einer Tabelle liegen zu bleibenfailed_jobs
  • Log-Rotation und Benachrichtigungen bei ExceptionsLOG_CHANNEL=daily
  • Ein nächtliches Datenbank-Backup, außerhalb des Servers gespeichertbackup · offsite
  • Ein TLS-Zertifikat, das sich selbst erneuertLet's Encrypt

Ein Release auf der Festplatte

/var/www/example-app
├── current → releases/1400
├── releases/
│   ├── 1400
│   └── 0930
└── shared/
    ├── .env
    └── storage/
Der Webserver zeigt auf current. Ein Release ist live, sobald der Link umgesetzt wird, und das vorherige bleibt für einen Rollback erhalten.

Erzählen Sie uns von Ihrer Anwendung

Eine Neuentwicklung, eine Anwendung, die ein Zuhause braucht, oder eine, die auf einer alten Version feststeckt. Jedes Projekt erhält nach einem kurzen Gespräch ein Angebot.