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.

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.

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.