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.
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.
01ci ~/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 02app ~/releases/1400 $ composer install --no-dev --optimize-autoloaderInstalling dependencies from lock fileGenerating optimized autoload files 03app ~/releases/1400 $ php artisan migrate --force INFO Running migrations. 2026_09_27_090000_add_due_date_to_invoices ....... DONE 04app ~/releases/1400 $ php artisan optimize INFO Caching framework bootstrap, configuration, and metadata. config ...................................... DONE events ...................................... DONE routes ...................................... DONE views ....................................... DONE 05app ~/releases/1400 $ ln -sfn ~/releases/1400 ~/current06app ~/releases/1400 $ php artisan horizon:terminate && php artisan octane:reload 07app ~/releases/1400 $ sudo supervisorctl statushorizon RUNNING pid 48211, uptime 0:00:09octane RUNNING pid 31877, uptime 6 days, 2:14:51 08app ~/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 nowPrima i test
I test girano prima che qualsiasi cosa arrivi al server. Un solo test fallito blocca il rilascio.
Dipendenze
Installate solo dal file di lock, senza pacchetti di sviluppo, con un autoloader ottimizzato.
Migrazioni
Scritte in modo che il codice in esecuzione continui a funzionare con il nuovo schema durante il passaggio al nuovo rilascio.
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.
Il cambio
Un link si sposta e il nuovo rilascio è online. Quello precedente resta su disco per un eventuale rollback.
Worker
Horizon completa i job in corso e riparte con il nuovo codice; Octane ricarica i suoi worker allo stesso modo.
Supervisionati
Supervisor mantiene in esecuzione Horizon e Octane, e riavvia l'uno o l'altro se si ferma.
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.
-
01 · Richiesta
POST /checkoutIl cliente paga
Il controller convalida l'ordine, lo salva e risponde subito. Qui non avviene nulla di lento.
-
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.
-
03 · Coda
redis · paymentsAspetta nella sua coda
I pagamenti hanno una coda tutta loro, così un'esportazione lunga non ne blocca mai uno.
-
04 · Worker
horizon · supervisorUn 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.
-
05 · Notifica
OrderPaid → mail, databaseTutti vengono avvisati
Il cliente riceve la fattura via email e l'ordine risulta pagato nella tua dashboard.
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 web
APP_DEBUG=false - Worker delle code sotto Supervisor, riavviati a ogni rilascio
supervisord - Una sola riga di cron per lo scheduler
* * * * * php artisan schedule:run - Redis per cache, sessioni e code
CACHE_STORE=redis - Configurazione, eventi, rotte e viste in cache a ogni rilascio
php artisan optimize - OPcache attivo e azzerato a ogni rilascio
opcache.validate_timestamps=0 - Un pool PHP-FPM dimensionato sulla memoria del server
pm.max_children - Rilasci in directory separate, a un passo dal rollback
current → releases/… - Job falliti segnalati a noi, non lasciati in una tabella
failed_jobs - Rotazione dei log e avvisi sulle eccezioni
LOG_CHANNEL=daily - Un backup notturno del database, copiato fuori dal server
backup · offsite - Un certificato TLS che si rinnova da solo
Let's Encrypt
Un rilascio su disco
/var/www/example-app
├── current → releases/1400
├── releases/
│ ├── 1400
│ └── 0930
└── shared/
├── .env
└── storage/
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.
| Funzionalità | PHP-FPM | FrankenPHP | RoadRunner | Swoole · 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.
-
0mesi dal rilascioSupporto 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.
-
0–18mesi dal rilascioSupporto 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.
-
12mesi dal rilascioSupporto completo
Arriva la versione principale successiva
La versione che usate è ancora pienamente supportata, quindi questo è il momento comodo per pianificare il passaggio.
-
18mesi dal rilascioSolo correzioni di sicurezza
Le correzioni di bug finiscono
Da qui la versione riceve solo correzioni di sicurezza.
-
24mesi dal rilascioFine 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.