Tu veux une base Docker PHP 8.4 réutilisable sans repartir de zéro à chaque projet ? J’utilise une image simple et durcie pour démarrer plus vite, garder un environnement cohérent et éviter les conteneurs bricolés qui finissent par casser au pire moment. Si tu dois fiabiliser ce type de socle sur plusieurs environnements, regarde aussi mon offre d’infogérance serveurs Linux en entreprise et ma page maintenance serveurs Linux.

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.
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.
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.
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.
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.
FAQ
Pourquoi mettre PHP et Node.js dans la même image ?
Parce que certains projets ont besoin des deux au même moment, surtout pendant le build : Composer pour les dépendances PHP, puis Node.js pour les assets. Pour une image de travail ou de CI, c’est souvent plus simple à maintenir.
Est-ce qu’un utilisateur non-root suffit pour sécuriser le conteneur ?
Non. C’est une bonne pratique importante, mais il faut aussi surveiller les dépendances, limiter les privilèges, contrôler les images de base et garder une politique de mise à jour propre.
Pourquoi copier Composer depuis l’image officielle ?
Ça réduit la complexité du build et évite d’ajouter une logique de téléchargement/validation de plus. Pour une image simple, c’est une solution propre et lisible.
Faut-il séparer image de build et image de production ?
Dans beaucoup de cas, oui. Une image de build peut contenir plus d’outils. Une image de production doit rester plus minimale. Le bon choix dépend de ton application, de ta CI et de tes contraintes d’exploitation.
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.