Développement Laravel

Des applications Laravel, construites et maintenues en service.

Du premier modèle aux workers de file d'attente, des déploiements à la mise à niveau des années plus tard – écrit, hébergé et suivi par une seule équipe.

Fonctionne sur et construit avec
  • Laravel
  • PHP
  • Redis
  • Let's Encrypt

Une livraison, telle qu'elle se présente sur le serveur

Chaque application Laravel que nous exploitons est livrée de la même façon : testée, construite, mise en cache et basculée sans une seconde d'interruption.

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
Une session d'exemple sur une application d'exemple. Les noms, chemins et sorties sont donnés à titre d'illustration.
  1. Les tests d'abord

    Les tests s'exécutent avant que quoi que ce soit n'atteigne le serveur. Un seul test en échec bloque la livraison.

  2. Dépendances

    Installées uniquement depuis le fichier de verrouillage, sans les paquets de développement, avec un autoloader optimisé.

  3. Migrations

    Écrites pour que le code en service fonctionne encore avec le nouveau schéma pendant la bascule de la livraison.

  4. Caches

    La configuration, les événements, les routes et les vues sont mis en cache. Dès lors, le fichier d'environnement n'est plus lu du tout : c'est pourquoi env() n'a sa place que dans les fichiers de configuration.

  5. La bascule

    Un lien change de cible et la nouvelle livraison est en ligne. La précédente reste sur le disque pour un retour arrière.

  6. Workers

    Horizon termine les jobs en cours et redémarre sur le nouveau code ; Octane recharge ses workers de la même façon.

  7. Supervisés

    Supervisor maintient Horizon et Octane en marche, et relance l'un ou l'autre s'il s'arrête.

  8. Le planificateur

    Une seule ligne cron lance toutes les tâches planifiées. Voici ce qu'elle exécutera ensuite.

D'un clic à un job terminé

Le travail lent sort de la requête. Le client obtient une réponse immédiate, et un worker fait le reste en arrière-plan.

  1. 01 · Requête POST /checkout

    Le client paie

    Le contrôleur valide la commande, l'enregistre et répond aussitôt. Rien de lent ne se passe ici.

  2. 02 · Job PayOrder::dispatch()

    La partie lente devient un job

    Envoyé une fois la transaction validée en base, pour qu'aucun worker ne prenne une commande dont la transaction a été annulée.

  3. 03 · File d'attente redis · payments

    Il attend dans sa propre file

    Les paiements ont leur propre file : un long export ne les retarde jamais.

  4. 04 · Worker horizon · supervisor

    Un worker le prend en charge

    Avec un délai maximal, des nouvelles tentatives de plus en plus espacées et une limite au nombre d'exécutions simultanées.

  5. 05 · Notification OrderPaid → mail, database

    Tout le monde est prévenu

    Le client reçoit la facture par e-mail, et la commande apparaît comme payée dans votre tableau de bord.

Si l'échec persiste failed_jobs

Un job qui épuise ses tentatives est conservé avec son erreur, et nous sommes alertés. Il est relancé une fois la cause corrigée – jamais perdu en silence.

Toute l'application, pas seulement le serveur

Notre équipe apporte vingt-cinq ans d'expérience en PHP à chaque projet Laravel, du premier modèle à la mise à niveau des années plus tard.

Construire

L'application elle-même.

Architecture
La logique métier dans des actions et des services, pas dans les contrôleurs. Des form requests pour la validation, des policies pour définir qui peut faire quoi.
Eloquent
Les relations chargées d'avance quand une page les liste : une page coûte quelques requêtes, pas des centaines. En développement, le lazy loading déclenche une erreur, et le problème est repéré tôt.
Livewire · Inertia
Livewire quand l'équipe écrit du PHP et du Blade ; Inertia avec Vue ou React quand le front-end est un projet à part entière.
API avec Sanctum
Des jetons pour les applications mobiles et les partenaires, des sessions par cookie pour votre propre front-end, et des limites de débit par client.
Pest · PHPUnit
Des tests pour chaque parcours qui encaisse de l'argent ou envoie des e-mails, exécutés à chaque push avant la construction d'une livraison.

Exploiter

Ce qui lui permet de toujours répondre.

Files d'attente et Horizon
Des files séparées pour le travail urgent et le travail de masse, chacune avec ses workers, ses délais et ses nouvelles tentatives, surveillées dans le tableau de bord Horizon.
Le planificateur
Une seule ligne cron lance toutes les tâches. Celles qui ne doivent pas se chevaucher, ou ne doivent s'exécuter que sur un seul serveur, sont marquées comme telles.
Octane
Swoole, RoadRunner ou FrankenPHP gardent l'application en mémoire entre les requêtes. Avant de l'activer, nous vérifions que le code ne laisse aucun état fuir d'une requête à l'autre.
Redis
Cache, sessions, files d'attente et verrous, sur un Redis inaccessible depuis Internet.
Supervisor
Les workers de file d'attente, Horizon et Octane tournent comme processus supervisés, relancés s'ils s'arrêtent et après chaque livraison.

Maintenir

Ce qui la garde à jour.

Déploiements sans interruption
Chaque livraison est construite dans son propre répertoire et activée par un seul lien. Revenir en arrière, c'est la même étape dans l'autre sens.
Journaux et exceptions
Des fichiers journaux quotidiens conservés pendant une durée définie, et chaque exception nous est signalée avec la requête qui l'a provoquée.
Mises à niveau
Laravel sort une version majeure chaque année. Nous faisons monter une application d'une version à la fois, avec des tests qui passent à chaque étape.

Ce que nous mettons en place dès le premier jour

Avant l'arrivée du premier client, chaque serveur Laravel que nous exploitons a déjà tout ceci en place.

  • Mode debug désactivé en production, et seul le répertoire public exposé au webAPP_DEBUG=false
  • Workers de file d'attente sous Supervisor, relancés à chaque livraisonsupervisord
  • Une seule ligne cron pour le planificateur* * * * * php artisan schedule:run
  • Redis pour le cache, les sessions et les files d'attenteCACHE_STORE=redis
  • Configuration, événements, routes et vues mis en cache à chaque livraisonphp artisan optimize
  • OPcache activé, et réinitialisé à chaque livraisonopcache.validate_timestamps=0
  • Un pool PHP-FPM dimensionné selon la mémoire du serveurpm.max_children
  • Des livraisons dans leurs propres répertoires, à une étape d'un retour arrièrecurrent → releases/…
  • Les jobs en échec nous sont signalés, au lieu de rester oubliés dans une tablefailed_jobs
  • Rotation des journaux et alertes sur les exceptionsLOG_CHANNEL=daily
  • Une sauvegarde nocturne de la base de données, copiée hors du serveurbackup · offsite
  • Un certificat TLS qui se renouvelle tout seulLet's Encrypt

Une livraison sur le disque

/var/www/example-app
├── current → releases/1400
├── releases/
│   ├── 1400
│   └── 0930
└── shared/
    ├── .env
    └── storage/
Le serveur web pointe vers current. Une livraison est en ligne dès que le lien change de cible, et la précédente reste là pour un retour arrière.

Quatre façons de servir une application Laravel

La même application peut tourner de la façon classique, sur PHP-FPM, ou sur l'un des trois serveurs que Laravel Octane prend en charge. Ils diffèrent par ce qu'ils exigent et par ce qu'ils apportent.

PHP-FPM
Le modèle classique. L'application redémarre à chaque requête.
FrankenPHP
Un serveur d'applications PHP écrit en Go, construit sur Caddy, avec HTTP/3, Early Hints et compression Brotli et Zstandard.
RoadRunner
Un serveur d'applications écrit en Go, lancé à partir d'un seul binaire. Octane propose de le télécharger.
Swoole · Open Swoole
Une extension PHP, installée avec PECL. Open Swoole offre les mêmes fonctions.
Ce que propose chaque façon de servir une application Laravel
Fonctionnalité PHP-FPMFrankenPHPRoadRunnerSwoole · Open Swoole
L'application démarre une seule fois et reste en mémoire entre les requêtes Non Oui Oui Oui
Fonctionne sans extension PHP supplémentaire pour le serveur Oui Oui Oui Non
Chaque requête repart de zéro, sans état partagé à vérifier Oui Non Non Non
Tâches concurrentes au sein d'une même requête Non Non Non Oui
Ticks : du code qui s'exécute toutes les quelques secondes Non Non Non Oui
Le cache Octane et les tables en mémoire partagée Non Non Non Oui

Une coche signifie que le serveur en dispose ; un tiret, qu'il n'en dispose pas. Octane est facultatif : une application Laravel tourne telle quelle sur PHP-FPM, et Octane l'accélère en la gardant en mémoire, c'est pourquoi le code est examiné, avant son activation, pour repérer l'état qui fuit d'une requête à l'autre. Sources : Documentation de Laravel Octane, Documentation de FrankenPHP.

Combien de temps une version de Laravel est prise en charge

Laravel publie une version majeure par an, et chacune est prise en charge pendant une durée fixe. Voici la vie d'une seule version, comptée en mois depuis sa sortie, pour voir quand une mise à niveau doit avoir lieu.

  1. 0mois après la sortie
    Support complet

    Une nouvelle version majeure sort

    Les versions majeures arrivent environ une fois par an, au premier trimestre. Les versions mineures et correctifs intermédiaires ne contiennent jamais de changement cassant.

  2. 0–18mois après la sortie
    Support complet

    Corrections de bugs et correctifs de sécurité

    Les deux sont fournis. Chaque version majeure prend en charge une plage de versions de PHP : monter de version signifie donc souvent monter aussi PHP.

  3. 12mois après la sortie
    Support complet

    La version majeure suivante arrive

    Votre version est toujours pleinement prise en charge : c'est le bon moment pour préparer la migration.

  4. 18mois après la sortie
    Correctifs de sécurité uniquement

    Les corrections de bugs s'arrêtent

    À partir d'ici, la version ne reçoit plus que des correctifs de sécurité.

  5. 24mois après la sortie
    Fin de vie

    Les correctifs de sécurité s'arrêtent aussi

    Une application encore sur cette version tourne sur du code que plus personne ne corrige.

Laravel vise à ce qu'une mise à niveau majeure prenne une journée ou moins. Nous faisons monter une application une version à la fois, avec les tests au vert à chaque étape. Politique de support de Laravel

Demander un devis

Parlez-nous de votre application

Un nouveau développement, une application qui cherche un hébergement, ou une autre bloquée sur une ancienne version. Chaque projet fait l'objet d'un devis après un court échange.

MickeyRépond en quelques secondes