
📋 Au programme
Docker · PHP 8.4 · DevOps
Dans cet article, je te montre comment je structure une docker image php 8.4 avec Composer, Node.js 24 et un utilisateur non-root. L’objectif n’est pas d’empiler des outils “par principe”, mais de produire une base exploitable pour des projets PHP modernes qui compilent des assets, installent des dépendances proprement et restent lisibles pour l’équipe.
Pourquoi partir d’une image PHP 8.4 dédiée ?
Sur un projet réel, le problème n’est pas seulement d’avoir php -v qui répond. Il faut aussi :
- une version PHP claire et maintenue ;
- Composer disponible sans installation artisanale à chaque build ;
- Node.js pour les assets, les tests frontend ou certains outils de build ;
- un utilisateur non-root pour limiter les mauvaises surprises en exécution ;
- une base simple à faire évoluer dans GitLab CI.
J’ai conçu ce repo pour répondre à ce besoin avec une approche volontairement sobre : partir de php:8.4-cli-bookworm, installer uniquement le nécessaire, puis valider la toolchain pendant le build.
Pourquoi PHP 8.4 ?
PHP 8.4 apporte des property hooks et de meilleures performances. Migrer maintenant c’est garantir la compatibilité avec Laravel, Symfony et WordPress.
Pourquoi PHP 8.4 ?
PHP 8.4 apporte des property hooks et de meilleures performances. Migrer maintenant garantit la compatibilité avec Laravel, Symfony et WordPress.
Ce que contient mon image Docker PHP 8.4
Le repo babidi34/secure-php84-node24-image embarque quatre briques utiles au quotidien :
- PHP 8.4 comme base de runtime ;
- Composer 2 récupéré depuis l’image officielle Composer ;
- Node.js 24 installé via nvm ;
- un utilisateur
appnon-root pour exécuter le conteneur.
Concrètement, ça donne un socle pratique pour des projets Symfony, Laravel ou des outils internes qui ont besoin de PHP + build frontend dans le même environnement de travail.
Base et variables de build
FROM php:8.4-cli-bookworm
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ARG NVM_VERSION=v0.40.3
ARG NODE_VERSION=24
ARG APP_UID=10001
ARG APP_GID=10001
J’aime bien exposer les versions et UID/GID en arguments de build. C’est plus simple pour faire évoluer l’image sans réécrire toute la logique.
Dépendances minimales et utilisateur non-root
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
xz-utils; \
rm -rf /var/lib/apt/lists/*; \
groupadd --gid "${APP_GID}" app; \
useradd --uid "${APP_UID}" --gid app --create-home --shell /bin/bash app; \
mkdir -p "${NVM_DIR}"; \
chown -R app:app "${NVM_DIR}"
Le gain est double : l’image reste lisible et tu évites de faire tourner ton application en root par défaut. Ce n’est pas une garantie magique, mais c’est une bonne base d’hygiène.
Composer depuis l’image officielle
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
Je préfère cette approche à un installeur téléchargé à la volée. C’est plus direct, plus reproductible et plus simple à relire quand tu reprends l’image plusieurs mois après.
Installation de Node.js 24 via nvm
RUN set -eux; \
curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" -o /tmp/install_nvm.sh; \
bash /tmp/install_nvm.sh; \
rm -f /tmp/install_nvm.sh; \
source "${NVM_DIR}/nvm.sh"; \
nvm install "${NODE_VERSION}"; \
nvm alias default "${NODE_VERSION}"; \
nvm use default; \
node --version; \
npm --version; \
chmod -R a+rX "${NVM_DIR}"
Le point important ici, ce n’est pas seulement Node.js 24. C’est le fait de valider immédiatement la version installée pendant le build. Tu sais vite si ton image sort dans un état exploitable.
💡 Info
Utiliser des images officielles PHP comme base garantit la compatibilité et les mises à jour de sécurité régulières.
Image de base : fixe la version
Évite les images :latest en production. Fixe une version exacte (php:8.4-fpm-alpine) pour garantir la reproductibilité de tes builds.
Fixe la version de l’image
Évite :latest en production. Fixe une version exacte (php:8.4-fpm-alpine) pour garantir la reproductibilité des builds.
Comment je vérifie l’image avant de l’utiliser
Le repo documente aussi une série de tests simples. Je te conseille de garder ce genre de vérification de base avant d’intégrer l’image dans une CI ou dans une chaîne de build applicatif :
docker build -t secure-php84-node24-image:local .
docker run --rm secure-php84-node24-image:local php -v
docker run --rm secure-php84-node24-image:local composer --version
docker run --rm secure-php84-node24-image:local bash -lc 'source /usr/local/nvm/nvm.sh && nvm --version && node -v && npm -v'
Avec ça, tu confirmes rapidement que PHP, Composer, nvm, Node et npm sont bien présents. C’est basique, mais c’est typiquement le garde-fou qui évite de découvrir un problème au milieu d’une chaîne CI/CD.
Bonne pratique multi-stage
Utilise un build multi-stage pour séparer les dépendances de dev des artefacts de production. Résultat : une image finale 2-3x plus légère.
Build multi-stage
Sépare les dépendances de dev des artefacts de production. Résultat : une image finale 2-3x plus légère.
Build multi-stage
Sépare les dépendances de dev des artefacts de prod. Résultat : une image finale 2-3x plus légère.
Dans quels cas cette image est utile
- tu gères plusieurs projets PHP avec des besoins frontend légers ou modérés ;
- tu veux une image de build homogène entre poste local et GitLab CI ;
- tu veux standardiser Composer + Node sans maintenir plusieurs images parallèles ;
- tu veux une base plus propre qu’un conteneur improvisé rempli à la main.
En revanche, si ton besoin impose des extensions PHP spécifiques, un serveur web embarqué ou une séparation stricte build/runtime, il faudra décliner ce socle plutôt que l’utiliser tel quel. C’est normal : une bonne image de base doit rester simple et assumée.
⚠️ Attention
Attention à bien fixer la version de PHP dans votre FROM pour éviter les surprises lors des rebuilds.
Les erreurs que je vois le plus souvent
- Installer trop d’outils d’un coup et transformer l’image en boîte à tout faire impossible à maintenir.
- Oublier l’utilisateur non-root, puis corriger en urgence des problèmes de permissions plus tard.
- Ne pas tester les binaires au build et découvrir l’erreur seulement dans la CI.
- Mélanger runtime et debug dans la même image sans discipline.
- Versionner sans stratégie et casser un projet au changement de version Node ou PHP.
Ma checklist pour une image PHP 8.4 exploitable en entreprise
- partir d’une base officielle maintenue ;
- limiter les paquets installés ;
- éviter l’exécution en root ;
- valider Composer, Node et npm pendant le build ;
- documenter les commandes de vérification ;
- publier l’image dans un registre maîtrisé ;
- garder un historique Git propre pour les montées de version.
Si tu veux industrialiser ce type de base Docker, l’enjeu n’est pas juste de “faire marcher un build”. Il faut surtout rendre le socle compréhensible, maintenable et répétable. C’est exactement le genre de chantier sur lequel je peux t’aider à cadrer l’exploitation, la maintenance et les mises à jour. Le plus simple est de me contacter ici.
✅ Astuce
Pensez à utiliser les builds multi-stage pour réduire la taille finale de votre image Docker.
FAQ
Ce qu’il faut retenir
Une docker image php 8.4 utile n’a pas besoin d’être compliquée. Elle doit surtout être cohérente, testée et assez propre pour être reprise sans douleur par l’équipe. C’est l’approche que j’applique ici : base officielle, dépendances limitées, Composer récupéré proprement, Node.js 24 validé au build et exécution en utilisateur non-root.
Si tu veux mettre ce genre de socle en place sur tes projets PHP, industrialiser tes images Docker ou fiabiliser tes builds Linux, je peux t’aider à cadrer ça côté exploitation et outillage. Tu peux me contacter ici.
Tu veux aller plus loin ?
Je peux t’accompagner sur la containerisation PHP — de l’image de base au déploiement Docker Compose en production.
Contacte-moi →