Aller au contenu principal
Site en cours de refonte — quelques pages peuvent bouger ou évoluer.
23 avril 2026

Dev de package Laravel : arrête de débugger un “projet hôte sale”

Le piège en dev de package Laravel, c’est de “valider” ton code dans une app hôte déjà bricolée. Avec Docker + un Laravel clean + un path repository, tu reprends le contrôle.

9 min de lecture
44 vues
réactions
Partager :
Dev de package Laravel : arrête de débugger un “projet hôte sale”

Développer un package Laravel dans “une app qui existe déjà”, ça marche… jusqu’au jour où tu te bats contre un bug qui n’est pas dans ton package. Une config traîne, un service provider est déjà chargé, une extension PHP est installée chez toi mais pas ailleurs, un cache a survécu à 15 branches. Résultat : tu as l’impression d’avancer, mais tu fabriques des faux positifs et des tests impossibles à reproduire.

Mon setup préféré, c’est l’inverse : un environnement Docker minimal et un projet Laravel hôte jetable, recréable en deux minutes, dans lequel ton package est lié via Composer en path repository (symlink). C’est plus strict, donc ça fait parfois un peu mal au début, mais c’est exactement ce qui évite de perdre une journée sur un “ça marche chez moi”.

Le vrai problème : ton projet hôte te ment (et tu le crois)

Quand tu développes un package, ton objectif n’est pas juste de “faire marcher une feature” dans une app donnée. Tu dois produire un truc qui tient dans plein de contextes : versions PHP différentes, apps Laravel pas configurées pareil, environnements CI plus stricts, serveurs sans les mêmes extensions.

Le projet hôte “sale”, c’est celui qui a vécu. Il a des providers ajoutés à la main, des macros globales, des helpers chargés partout, des dépendances installées “parce qu’un autre package en avait besoin”, des configs publiées puis modifiées. Et le pire : tout ça peut masquer un défaut dans ton package. Tu crois que ton auto-discovery marche alors que c’est juste l’app qui t’a déjà enregistré ton provider. Tu crois que ton code est compatible alors que tu utilises une extension PHP absente en prod. Tu crois que tes tests sont stables alors qu’ils passent grâce à un cache ou à une dépendance fantôme.

Donc oui : si tu maintiens un package, tu veux un environnement qui te contredit vite. Pas un environnement qui te donne raison.

Le setup que je recommande : Docker + PHP CLI + un Laravel “clean” jetable

L’idée est simple : tu démarres d’une image officielle PHP CLI, tu ajoutes le strict nécessaire (extensions, git/unzip, Composer), puis tu montes deux répertoires en volume. Un pour ton package, un pour une app Laravel hôte créée avec composer create-project.

Pourquoi PHP CLI et pas un gros stack Nginx/MySQL ? Parce qu’en dev de package, la priorité c’est la reproductibilité et les tests. Tu peux très bien tester un package sans serveur HTTP au début, et ajouter un serveur plus tard seulement si tu as besoin de valider un flow navigateur. Garder le setup minimal évite aussi de “cacher” des problèmes.

Dockerfile + docker-compose : un environnement reproductible sans bazar

Je te montre une version volontairement sobre. Elle te donne un container où tu peux installer une app Laravel clean, installer ton package en symlink, lancer les tests, et recommencer autant de fois que nécessaire.

# docker-compose.yml
services:
  pkg:
    build:
      context: .
      dockerfile: Dockerfile
    working_dir: /workspace
    volumes:
      - ./:/workspace/package
      - ./workbench:/workspace/workbench
      - composer-cache:/tmp/composer-cache
    environment:
      COMPOSER_CACHE_DIR: /tmp/composer-cache

volumes:
  composer-cache:

# Dockerfile
FROM php:8.3-cli

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    git unzip libzip-dev \
  && docker-php-ext-install zip \
  && rm -rf /var/lib/apt/lists/*

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /workspace

Tu remarques deux choix importants. D’abord, une version PHP fixée. C’est tentant de mettre “latest”, mais tu veux justement éviter les surprises. Ensuite, un cache Composer en volume pour aller vite, sans pour autant figer les dépendances de ton projet hôte. La vitesse c’est bien, mais la reproductibilité c’est mieux.

Créer une app Laravel hôte propre, puis la jeter sans regret

Le répertoire workbench sert d’app hôte. Le mot n’a rien de magique, c’est juste un dossier. L’important c’est qu’il soit séparé de ton package, et qu’il puisse être supprimé et recréé quand tu sens que “ça sent le cache”.

Une fois le container buildé, tu crées l’app Laravel dedans. Typiquement, je fais ça une fois, puis je n’hésite pas à la régénérer quand j’ai un doute.

Concrètement : tu build, tu lances un shell dans le container, et tu fais un create-project dans /workspace/workbench. Si ton package vise une version précise de Laravel, fixe-la ici aussi. Ce détail évite un paquet de discussions stériles du type “ça casse sur Laravel 10 mais pas 11”.

Le but est que l’app Laravel hôte consomme ton package comme si c’était un vrai package, mais sans passer par un dépôt Packagist ou un repo Git distant. Composer sait faire ça proprement avec un repository de type path.

Tu ajoutes le repository dans le composer.json de l’app hôte, tu demandes l’installation, et Composer crée un lien vers ton code local. Résultat : tu modifies ton package, l’app voit instantanément les changements, et tu restes dans une logique “dépendance” réaliste. C’est beaucoup plus sain qu’un copier-coller de classes dans app/ ou qu’un montage douteux.

{
  "repositories": [
    {
      "type": "path",
      "url": "../package",
      "options": {
        "symlink": true
      }
    }
  ],
  "require": {
    "vendor/mon-package": "*"
  }
}

Deux mises en garde terrain. La première : pense à garder ton name et ton autoload PSR-4 propres côté package, sinon tu vas passer une heure à croire que “Docker ne refresh pas”, alors que c’est juste Composer qui n’arrive pas à autoloader correctement. La seconde : évite de “tricher” en ajoutant ton provider à la main dans l’app hôte si ton package est censé être auto-discovered. Si tu le fais, tu masques le bug que ton utilisateur verra.

Tests : ce que Docker rend beaucoup plus fiable (et ce qu’il ne règle pas)

Avec ce setup, ton app hôte sert surtout à faire du QA manuel rapide et à reproduire des cas d’intégration. Pour les tests automatisés de package, la base reste de tester dans un environnement contrôlé, typiquement avec un harness de type Testbench si tu es dans l’écosystème Laravel. L’intérêt de Docker ici, c’est que tu peux faire tourner ces tests dans un PHP et un set d’extensions connus, pas dans ton PHP local “custom”.

Ce que Docker ne règle pas tout seul, c’est la discipline des versions. Si tu laisses ton composer.json accepter n’importe quoi, tu auras une matrice “au hasard” qui passe aujourd’hui et casse demain. Mon approche est simple : je garde des contraintes réalistes côté package, je locke proprement dans le repo du package, et je fais tourner une petite matrice de versions PHP/Laravel en CI. Localement, Docker me sert à reproduire exactement une case de cette matrice, sans improvisation.

Workflow quotidien : reset instant, diff clair, et moins de temps perdu

Dans la vraie vie, ce setup change surtout ton rythme. Tu peux repartir de zéro dès que tu sens que tu n’es plus sûr. Tu supprimes le dossier workbench, tu le recrées, tu relink le package, tu relances. Le reset devient un réflexe sain, pas une corvée de 45 minutes.

Autre bénéfice : quand quelqu’un te dit “tes tests cassent chez moi”, tu peux lui répondre avec un environnement. Pas avec une incantation. Fixer PHP, documenter deux commandes, et savoir recréer l’app hôte en clean, c’est ce qui transforme une discussion floue en bug reproductible.

Le bonus important : aller vite sans rendre l’environnement non déterministe

Le piège classique, c’est de vouloir optimiser trop tôt. Oui, tu peux accélérer avec un cache Composer en volume, et c’est très bien. Mais évite les caches “magiques” qui rendent les résultats incohérents entre deux machines. Garde le cache pour les downloads, pas pour masquer des changements de dépendances. Et quand tu doutes, n’hésite pas à le purger. Un cache qui te fait gagner 30 secondes mais te coûte 2 heures de debug, ce n’est pas un cache, c’est une arnaque.

Dernier point : si ton package dépend d’extensions PHP spécifiques (gd, intl, redis, etc.), installe-les explicitement dans l’image. Ne pars pas du principe qu’elles seront là. Le jour où tu publies un package, ton vrai utilisateur, c’est un serveur minimal. Ton environnement de dev doit ressembler à ça, pas à ton laptop dopé aux extensions.

Conclusion : un environnement “clean” te rend plus lent 10 minutes, puis plus rapide pendant des mois

Développer un package Laravel, ce n’est pas juste coder. C’est produire une intégration robuste, qui ne dépend pas d’un état local implicite. Docker + une app hôte jetable + un path repository Composer, c’est une combinaison qui te force à être honnête avec ton code. Et ce genre d’honnêteté, en maintenance, c’est de l’or.

Si tu veux pousser le curseur plus loin, la suite logique c’est d’industrialiser la matrice (plusieurs versions PHP/Laravel), et d’aligner ton environnement local Docker sur ce que fait ta CI. Là, tu commences vraiment à dormir tranquille.

Sources

Cet article vous a plu ?

Commentaires

Laisser un commentaire

Entre 10 et 2000 caractères

Les commentaires sont modérés avant publication.

Aucun commentaire pour le moment.

Soyez le premier à donner votre avis !