Sviluppo Laravel

Applicazioni Laravel, sviluppate e mantenute in funzione.

Dal primo modello ai worker delle code, dai rilasci all'aggiornamento di anni dopo: scritte, ospitate e seguite da un unico team.

Funziona su e costruito con
  • Laravel
  • PHP
  • Redis
  • Let's Encrypt

Un rilascio, così come appare sul server

Ogni applicazione Laravel che gestiamo va online allo stesso modo: testata, preparata, messa in cache e attivata senza un secondo di interruzione.

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
Una sessione di esempio su un'applicazione di esempio. Nomi, percorsi e output sono indicativi.
  1. Prima i test

    I test girano prima che qualsiasi cosa arrivi al server. Un solo test fallito blocca il rilascio.

  2. Dipendenze

    Installate solo dal file di lock, senza pacchetti di sviluppo, con un autoloader ottimizzato.

  3. Migrazioni

    Scritte in modo che il codice in esecuzione continui a funzionare con il nuovo schema durante il passaggio al nuovo rilascio.

  4. Cache

    Configurazione, eventi, rotte e viste vengono messi in cache. Da qui in poi il file d'ambiente non viene più letto, ed è per questo che env() va usato solo nei file di configurazione.

  5. Il cambio

    Un link si sposta e il nuovo rilascio è online. Quello precedente resta su disco per un eventuale rollback.

  6. Worker

    Horizon completa i job in corso e riparte con il nuovo codice; Octane ricarica i suoi worker allo stesso modo.

  7. Supervisionati

    Supervisor mantiene in esecuzione Horizon e Octane, e riavvia l'uno o l'altro se si ferma.

  8. Lo scheduler

    Una sola riga di cron esegue ogni attività pianificata. Ecco la prossima che eseguirà.

Da un clic a un job completato

Il lavoro lento esce dalla richiesta. Il cliente riceve subito una risposta e un worker fa il resto in background.

  1. 01 · Richiesta POST /checkout

    Il cliente paga

    Il controller convalida l'ordine, lo salva e risponde subito. Qui non avviene nulla di lento.

  2. 02 · Job PayOrder::dispatch()

    La parte lenta diventa un job

    Inviato dopo il commit del database, così un worker non prende mai in carico un ordine annullato da un rollback.

  3. 03 · Coda redis · payments

    Aspetta nella sua coda

    I pagamenti hanno una coda tutta loro, così un'esportazione lunga non ne blocca mai uno.

  4. 04 · Worker horizon · supervisor

    Un worker lo prende in carico

    Con un timeout, nuovi tentativi che attendono ogni volta più a lungo e un limite a quanti ne girano contemporaneamente.

  5. 05 · Notifica OrderPaid → mail, database

    Tutti vengono avvisati

    Il cliente riceve la fattura via email e l'ordine risulta pagato nella tua dashboard.

Se continua a fallire failed_jobs

Un job che esaurisce i tentativi viene conservato con il suo errore e noi riceviamo un avviso. Viene rieseguito una volta risolta la causa: mai perso in silenzio.

L'intera applicazione, non solo il server

Il nostro team porta venticinque anni di esperienza in PHP in ogni progetto Laravel, dal primo modello all'aggiornamento di anni dopo.

Sviluppare

L'applicazione in sé.

Architettura
Logica di business in azioni e servizi, non nei controller. Form request per la validazione, policy per stabilire chi può fare cosa.
Eloquent
Relazioni caricate in anticipo dove una pagina le elenca, così una pagina costa poche query e non centinaia. In sviluppo il lazy loading genera un errore, così il problema emerge subito.
Livewire · Inertia
Livewire quando il team scrive PHP e Blade; Inertia con Vue o React quando il front end è un progetto a sé.
API con Sanctum
Token per app mobili e partner, sessioni con cookie per il tuo front end e limiti di richieste per ogni client.
Pest · PHPUnit
Test per ogni percorso che incassa denaro o invia email, eseguiti a ogni push prima che venga preparato un rilascio.

Gestire

Ciò che la mantiene reattiva.

Code e Horizon
Code separate per il lavoro urgente e per quello massivo, ognuna con i propri worker, timeout e tentativi, monitorate nella dashboard di Horizon.
Lo scheduler
Una sola riga di cron esegue ogni attività. Le attività che non devono sovrapporsi, o che devono girare su un solo server, sono contrassegnate come tali.
Octane
Swoole, RoadRunner o FrankenPHP tengono l'applicazione in memoria tra una richiesta e l'altra. Prima di attivarlo, controlliamo che nel codice non ci sia stato che passa da una richiesta alla successiva.
Redis
Cache, sessioni, code e lock, su un Redis non raggiungibile da internet.
Supervisor
Worker delle code, Horizon e Octane girano come processi supervisionati, riavviati se si fermano e dopo ogni rilascio.

Mantenere

Ciò che la mantiene aggiornata.

Rilasci senza interruzioni
Ogni rilascio viene preparato in una propria directory e attivato con un solo link. Tornare indietro è lo stesso passaggio al contrario.
Log ed eccezioni
File di log giornalieri conservati per un periodo stabilito, e ogni eccezione segnalata a noi insieme alla richiesta che l'ha causata.
Aggiornamenti di versione
Laravel pubblica una versione major ogni anno. Portiamo avanti un'applicazione una versione alla volta, con i test superati a ogni passaggio.

Cosa configuriamo fin dal primo giorno

Prima che arrivi il primo cliente, ogni server Laravel che gestiamo ha già tutto questo al suo posto.

  • Modalità debug disattivata in produzione e solo la directory pubblica esposta sul webAPP_DEBUG=false
  • Worker delle code sotto Supervisor, riavviati a ogni rilasciosupervisord
  • Una sola riga di cron per lo scheduler* * * * * php artisan schedule:run
  • Redis per cache, sessioni e codeCACHE_STORE=redis
  • Configurazione, eventi, rotte e viste in cache a ogni rilasciophp artisan optimize
  • OPcache attivo e azzerato a ogni rilascioopcache.validate_timestamps=0
  • Un pool PHP-FPM dimensionato sulla memoria del serverpm.max_children
  • Rilasci in directory separate, a un passo dal rollbackcurrent → releases/…
  • Job falliti segnalati a noi, non lasciati in una tabellafailed_jobs
  • Rotazione dei log e avvisi sulle eccezioniLOG_CHANNEL=daily
  • Un backup notturno del database, copiato fuori dal serverbackup · offsite
  • Un certificato TLS che si rinnova da soloLet's Encrypt

Un rilascio su disco

/var/www/example-app
├── current → releases/1400
├── releases/
│   ├── 1400
│   └── 0930
└── shared/
    ├── .env
    └── storage/
Il web server punta a current. Un rilascio è online nel momento in cui il link si sposta, e quello precedente resta per un eventuale rollback.

Quattro modi per servire un'applicazione Laravel

La stessa applicazione può girare nel modo classico, su PHP-FPM, oppure su uno dei tre server supportati da Laravel Octane. Si differenziano per ciò che richiedono e per ciò che aggiungono.

PHP-FPM
Il modello classico. L'applicazione si avvia da capo a ogni richiesta.
FrankenPHP
Un application server PHP scritto in Go, costruito su Caddy, con HTTP/3, Early Hints e compressione Brotli e Zstandard.
RoadRunner
Un application server scritto in Go e avviato da un unico binario. Octane si offre di scaricarlo.
Swoole · Open Swoole
Un'estensione di PHP, installata con PECL. Open Swoole offre le stesse funzioni.
Che cosa offre ciascun modo di servire un'applicazione Laravel
Funzionalità PHP-FPMFrankenPHPRoadRunnerSwoole · Open Swoole
L'applicazione si avvia una volta sola e resta in memoria tra una richiesta e l'altra No Sì Sì Sì
Funziona senza un'estensione PHP aggiuntiva per il server Sì Sì Sì No
Ogni richiesta parte pulita, senza stato condiviso da verificare Sì No No No
Attività concorrenti all'interno di una richiesta No No No Sì
Tick: codice che viene eseguito ogni pochi secondi No No No Sì
La cache di Octane e le tabelle in memoria condivisa No No No Sì

Una spunta significa che il server la offre; un trattino, che non la offre. Octane è facoltativo: un'applicazione Laravel gira su PHP-FPM così com'è, e Octane aggiunge velocità tenendola in memoria, per questo il codice viene controllato prima dell'attivazione per individuare lo stato che passa da una richiesta alla successiva. Fonti: Documentazione di Laravel Octane, Documentazione di FrankenPHP.

Per quanto tempo una versione di Laravel è supportata

Laravel pubblica una versione principale all'anno, e ognuna è supportata per un tempo stabilito. Ecco la vita di una singola versione, contata in mesi dal rilascio, per vedere quando un aggiornamento diventa necessario.

  1. 0mesi dal rilascio
    Supporto completo

    Esce una nuova versione principale

    Le versioni principali arrivano circa una volta all'anno, nel primo trimestre. Le versioni minori e di patch nel mezzo non contengono mai modifiche incompatibili.

  2. 0–18mesi dal rilascio
    Supporto completo

    Correzioni di bug e di sicurezza

    Vengono fornite entrambe. Ogni versione principale supporta un intervallo di versioni di PHP, quindi salire di versione spesso significa aggiornare anche PHP.

  3. 12mesi dal rilascio
    Supporto completo

    Arriva la versione principale successiva

    La versione che usate è ancora pienamente supportata, quindi questo è il momento comodo per pianificare il passaggio.

  4. 18mesi dal rilascio
    Solo correzioni di sicurezza

    Le correzioni di bug finiscono

    Da qui la versione riceve solo correzioni di sicurezza.

  5. 24mesi dal rilascio
    Fine del ciclo di vita

    Finiscono anche le correzioni di sicurezza

    Un'applicazione ancora su questa versione gira su codice che nessuno corregge più.

Laravel punta a far sì che un aggiornamento di versione principale richieda un giorno o meno. Noi portiamo un'applicazione avanti una versione alla volta, con i test che passano a ogni passo. Politica di supporto di Laravel

Richiedi un preventivo

Raccontaci la tua applicazione

Un nuovo sviluppo, un'applicazione che cerca casa o una ferma a una vecchia versione. Ogni progetto viene preventivato dopo una breve conversazione.

MickeyRisponde in pochi secondi