TL;DRDocker emballe une application avec tout ce dont elle a besoin dans une image, puis la lance n'importe où sous forme de conteneur. Voici ce qu'est un conteneur, en quoi il diffère d'une machine virtuelle, le vocabulaire indispensable, et une mise en œuvre pas à pas jusqu'à un site PHP avec sa base MariaDB, avec les pièges que nous avons rencontrés en migrant nos hébergements vers Docker et Kubernetes. C'est la base à maîtriser avant de passer à Kubernetes.
Docker en une phrase#
Docker est un outil qui emballe une application avec tout ce dont elle a besoin pour fonctionner (sa version de PHP, ses extensions, ses bibliothèques, sa configuration) dans un paquet standard appelé image, puis qui lance ce paquet sur n'importe quel serveur sous la forme d'un conteneur, isolé du reste de la machine.
Le problème que Docker résout est connu de tous les développeurs : « ça marche sur mon poste, mais pas sur le serveur ». Une version de PHP différente, une extension absente, un réglage du php.ini qui change, et le site ne se comporte plus de la même façon. Avec Docker, ce qui tourne en production est exactement ce qui a été construit et testé : la même image, octet pour octet.
Cet article est le premier d'une série de quatre. Il pose les bases : ce qu'est un conteneur, le vocabulaire indispensable, puis la mise en œuvre pas à pas, du premier docker run jusqu'à un site PHP avec sa base MariaDB. Les articles suivants traitent de Kubernetes, de Docker et Kubernetes utilisés ensemble avec la supervision, et de la CI/CD.
Qu'est-ce qu'un conteneur ?#
Un conteneur est un programme qui s'exécute sur un serveur Linux, mais qui croit être seul sur la machine. Il voit ses propres fichiers, ses propres processus, sa propre adresse réseau. Il ne voit pas les autres conteneurs ni les fichiers de l'hôte, sauf si on le lui permet explicitement.
Ce cloisonnement ne repose pas sur une machine simulée, mais sur deux fonctions du noyau Linux :
- Les namespaces (espaces de noms) : ils donnent au conteneur sa propre vue du système. Un namespace pour les processus, un pour le réseau, un pour les points de montage, un pour le nom d'hôte, etc.
- Les cgroups (control groups) : ils limitent et mesurent les ressources consommées, comme la mémoire ou le processeur. Un conteneur limité à 512 Mo ne peut pas prendre toute la mémoire du serveur.
Docker n'a pas inventé ces mécanismes, qui existaient déjà dans Linux. Son apport, lors de sa présentation en 2013, a été de les rendre simples à utiliser et de standardiser la façon de fabriquer, de stocker et de distribuer les applications ainsi isolées.
Conteneur ou machine virtuelle : quelle différence ?#
Une machine virtuelle (VM) simule un ordinateur complet. Un logiciel appelé hyperviseur (KVM, VMware, Hyper-V…) découpe le serveur physique en plusieurs machines, et chacune démarre son propre système d'exploitation, avec son propre noyau.
Un conteneur, lui, n'embarque pas de système d'exploitation complet. Tous les conteneurs d'un serveur partagent le noyau du système hôte ; chacun n'apporte que son application et les bibliothèques dont elle a besoin.

| Machine virtuelle | Conteneur | |
|---|---|---|
| Ce qu'elle contient | Un système d'exploitation complet, noyau compris | L'application et ses bibliothèques, sans noyau |
| Démarrage | Celui d'un système complet (démarrage du noyau, des services) | Celui d'un simple processus : bien plus rapide |
| Isolation | Forte : chaque VM a son noyau | Plus légère : un défaut du noyau partagé concerne tous les conteneurs |
| Systèmes possibles | Linux, Windows, BSD… sur le même serveur | Des conteneurs Linux sur un noyau Linux (Docker Desktop fait tourner une petite VM Linux sur Mac et Windows) |
| Usage typique | Découper un serveur en machines indépendantes | Emballer et déployer des applications de façon reproductible |
Les deux ne s'opposent pas : dans beaucoup d'infrastructures, les conteneurs tournent à l'intérieur de machines virtuelles. Le choix dépend du besoin d'isolation et de la façon dont vous voulez livrer vos applications.
Les mots essentiels de Docker#
Docker a son propre vocabulaire. Voici les termes que vous croiserez dans toute documentation, regroupés par thème. Un glossaire récapitulatif figure en fin d'article.
Image, conteneur, couches#
- Image : un modèle figé, en lecture seule, qui contient le système de fichiers d'une application (programmes, bibliothèques, code, configuration) et des métadonnées (commande de démarrage, port, variables). Une image ne « tourne » pas : elle sert à créer des conteneurs.
- Conteneur : une instance d'une image en cours d'exécution. On peut lancer dix conteneurs à partir de la même image, comme on imprime dix exemplaires d'un même document. Chaque conteneur ajoute au-dessus de l'image une fine couche inscriptible qui disparaît quand on le supprime.
- Couche (layer) : une image est un empilement de couches. Chaque instruction du Dockerfile qui modifie des fichiers produit une couche. Les couches sont partagées : dix images basées sur
php:8.4-apachene stockent cette base qu'une fois sur le disque, et Docker réutilise en cache les couches qui n'ont pas changé lors d'une reconstruction. - Dockerfile : le fichier texte qui décrit, instruction par instruction, comment construire une image. C'est la recette ; l'image est le plat préparé.

Registre et tag#
- Registre (registry) : un serveur qui stocke et distribue les images, comme un dépôt de paquets. Docker Hub est le registre public par défaut ; il héberge notamment les « images officielles » (
php,mariadb,nginx…). Une entreprise peut aussi faire tourner son propre registre privé. - Tag : l'étiquette qui désigne une version d'une image, après les deux-points. Dans
php:8.4-apache,phpest le nom du dépôt et8.4-apachele tag. Sans tag, Docker utiliselatest, qui n'est qu'un nom par défaut : il ne garantit pas que vous obtenez la version la plus récente, ni la même d'un jour à l'autre.
Stockage : volume et bind mount#
Tout ce qu'un conteneur écrit dans sa couche inscriptible est perdu quand le conteneur est supprimé. Pour garder des données, on les place hors du conteneur, de deux façons :
- Volume : un espace de stockage créé et géré par Docker (sous
/var/lib/docker/volumes/sur Linux). C'est la solution recommandée pour les données d'une base de données. - Bind mount (montage d'un dossier de l'hôte) : un dossier existant du serveur est rendu visible dans le conteneur. Pratique quand ces fichiers doivent rester accessibles par d'autres outils de l'hôte, par exemple un serveur FTP.
Réseau, port publié, variables d'environnement#
- Réseau : Docker crée des réseaux virtuels entre conteneurs. Sur un réseau créé par l'utilisateur (et sur celui que Docker Compose crée pour chaque projet), les conteneurs se joignent par leur nom : le conteneur PHP peut contacter la base à l'adresse
db. - Port publié : par défaut, un conteneur n'est pas joignable depuis l'extérieur du serveur. L'option
-p 8080:80publie le port 80 du conteneur sur le port 8080 de l'hôte. L'instructionEXPOSEd'un Dockerfile, elle, ne publie rien : elle documente seulement le port utilisé. - Variable d'environnement : une valeur transmise au conteneur au démarrage (
-e DB_HOST=db). C'est la façon habituelle de configurer une même image différemment en test et en production, sans la reconstruire.
Démarrage et santé : ENTRYPOINT, CMD, HEALTHCHECK#
- ENTRYPOINT : le programme lancé au démarrage du conteneur.
- CMD : la commande par défaut, ou les arguments par défaut passés à l'ENTRYPOINT. Elle est remplacée par ce que vous tapez après le nom de l'image dans
docker run. Dans l'imagephp:8.4-apache, l'ENTRYPOINT est un petit script de préparation (docker-php-entrypoint) et la CMD estapache2-foreground, qui lance Apache au premier plan. - HEALTHCHECK : une commande que Docker exécute à intervalle régulier pour savoir si l'application répond vraiment. Un conteneur peut être « démarré » mais bloqué ; le healthcheck le fait passer à l'état
unhealthy.
Outils et standards : Compose, multi-stage, .dockerignore, OCI, containerd#
- Docker Compose : un outil qui décrit dans un seul fichier YAML (
compose.yaml) plusieurs conteneurs qui fonctionnent ensemble (un site PHP et sa base de données, par exemple), avec leurs réseaux et volumes, et les lance d'une seule commande. - Multi-stage build (construction en plusieurs étapes) : un Dockerfile qui utilise une première image pour préparer quelque chose (installer les dépendances avec Composer, compiler des fichiers CSS) puis ne copie que le résultat dans l'image finale. Les outils de construction ne partent pas en production.
- .dockerignore : un fichier qui liste ce qu'il ne faut pas envoyer à la construction (dossier
.git, fichier.env, journaux,node_modules). Il accélère la construction et évite d'embarquer des secrets par erreur. - OCI (Open Container Initiative) : un projet de la Linux Foundation, créé en 2015, qui définit les standards ouverts des conteneurs : le format des images, la façon de les exécuter et de les distribuer. Grâce à lui, une image construite avec Docker fonctionne avec d'autres outils (Podman, Kubernetes…).
- containerd : le moteur qui gère réellement le cycle de vie des conteneurs (téléchargement des images, démarrage, arrêt). Docker Engine s'appuie sur lui, et Kubernetes l'utilise aussi directement. containerd délègue à son tour le lancement de chaque conteneur à
runc, l'implémentation de référence du standard OCI.
Mise en œuvre pas à pas#
1. Installer Docker#
La méthode dépend de votre système, et elle évolue : suivez la documentation officielle plutôt qu'un tutoriel daté.
- Sur un serveur Linux (Debian, Ubuntu, Fedora…) : installez Docker Engine depuis le dépôt officiel de Docker, en suivant la page Install Docker Engine. Le plugin Docker Compose s'installe en même temps.
- Sur un poste Mac ou Windows : installez Docker Desktop, qui fournit une petite machine virtuelle Linux, le moteur et une interface graphique. Vérifiez ses conditions de licence si vous l'utilisez dans une entreprise.
Vérifiez ensuite l'installation :
# Affiche la version du client et du moteur Docker
docker version
# Lance un conteneur de test qui affiche un message puis s'arrête
docker run hello-worldBon à savoir : sur Linux, ajouter un utilisateur au groupe
dockerlui évite de tapersudo, mais lui donne en pratique des droits équivalents à root sur la machine. Réservez ce groupe aux administrateurs.
2. Lancer et observer un conteneur#
Commençons par un serveur web Nginx, sans rien écrire :
# -d : en arrière-plan ; --name : un nom lisible ; -p : publie le port 80 du conteneur sur le port 8080 de l'hôte
docker run -d --name test-web -p 8080:80 nginx:1.29-alpine
# Liste les conteneurs en cours d'exécution (ajoutez -a pour voir aussi les conteneurs arrêtés)
docker ps
# Interroge le site depuis le serveur : la réponse doit être « HTTP/1.1 200 OK »
curl -sI http://localhost:8080/ | head -1Si l'image n'est pas encore présente sur la machine, docker run la télécharge d'abord depuis Docker Hub. Pour savoir ce qui se passe dans le conteneur :
# Affiche les journaux du conteneur (ce que le programme écrit sur sa sortie standard)
docker logs test-web
# Suit les journaux en direct, en partant des 50 dernières lignes (Ctrl+C pour quitter)
docker logs -f --tail 50 test-web
# Exécute une commande dans le conteneur qui tourne
docker exec test-web nginx -v
# Ouvre un shell interactif dans le conteneur (-i : entrée clavier, -t : terminal) ; tapez exit pour sortir
docker exec -it test-web shEt pour faire le ménage :
# Arrête le conteneur proprement (signal d'arrêt, puis arrêt forcé au bout de 10 secondes par défaut)
docker stop test-web
# Supprime le conteneur arrêté ; l'image, elle, reste sur la machine
docker rm test-web
# Liste les images présentes localement
docker image lsPoint important : docker logs n'affiche que ce que l'application écrit sur sa sortie standard et sa sortie d'erreur. Les images officielles sont prévues pour cela (Apache et Nginx y envoient leurs journaux). Une application qui écrit seulement dans un fichier à l'intérieur du conteneur laissera docker logs vide.
3. Écrire un Dockerfile pour une application PHP#
Prenons un petit site PHP qui se connecte à une base MariaDB. Le projet contient un dossier public/ avec le code. Voici un Dockerfile basé sur l'image officielle PHP avec Apache :
# Image de départ : PHP 8.4 avec Apache, version fixée par le tag
FROM php:8.4-apache
# Extensions PHP dont l'application a besoin
RUN docker-php-ext-install pdo_mysql opcache
# L'image officielle ne fournit pas de php.ini : on part du modèle de production
RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Code de l'application, attribué à l'utilisateur d'Apache
COPY --chown=www-data:www-data public/ /var/www/html/
# Vérification de santé : la page d'accueil doit répondre
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -fsS http://localhost/ || exit 1
# Documente le port utilisé par Apache (ne publie rien)
EXPOSE 80Quelques explications :
FROMchoisit l'image de base. Le tag8.4-apachefixe la version de PHP et la variante avec Apache intégré.docker-php-ext-installest un script fourni par l'image officielle pour compiler et activer les extensions livrées avec PHP. Les extensions externes (redis,imagick…) s'installent avecpecl, et certaines nécessitent d'abord des bibliothèques système installées avecapt-get.COPYcopie le code du projet dans l'image ;--chownévite une couche supplémentaire de changement de propriétaire.HEALTHCHECKutilisecurl, présent dans l'image officielle :-ffait échouer la commande si le serveur renvoie une erreur HTTP.
Bon à savoir : c'est un piège que nous avons rencontré nous-mêmes. Les images officielles PHP sont livrées sans fichier php.ini : seuls deux modèles sont fournis,
php.ini-developmentetphp.ini-production. Sans copie, PHP tourne avec ses valeurs internes par défaut, qui ne correspondent pas à ce qu'un serveur de production configure habituellement (affichage des erreurs, limites, journalisation). Copiez explicitement le modèle de production, puis ajoutez vos propres réglages dans un fichier séparé du dossier$PHP_INI_DIR/conf.d/.
Ajoutez à côté du Dockerfile un fichier .dockerignore :
.git
.env
node_modules
*.log4. Construire l'image#
# Construit l'image à partir du Dockerfile du dossier courant et lui donne le nom mon-site, tag 1.0
# Le point final désigne le « contexte » : les fichiers envoyés à la construction
docker build -t mon-site:1.0 .
# Affiche les couches de l'image et la taille de chacune
docker history mon-site:1.0
# Vérifie la version de PHP et les extensions dans l'image (--rm : supprime le conteneur à la fin)
docker run --rm mon-site:1.0 php -mRelancez docker build sans rien changer : la construction est presque instantanée, car toutes les couches viennent du cache. Modifiez un fichier de public/ : seule la couche COPY et celles qui suivent sont reconstruites. C'est pourquoi on place en haut du Dockerfile ce qui change rarement (extensions, configuration) et en bas ce qui change souvent (le code).
5. Envoyer l'image dans un registre#
Pour que d'autres serveurs puissent utiliser l'image, on la pousse dans un registre. Le nom de l'image doit alors commencer par l'adresse du registre (ici un exemple, registry.example.com) :
# S'authentifie auprès du registre (le mot de passe est demandé, il n'apparaît pas dans l'historique)
docker login registry.example.com
# Ajoute un second nom à l'image locale, qui inclut l'adresse du registre
docker tag mon-site:1.0 registry.example.com/equipe/mon-site:1.0
# Envoie l'image ; seules les couches absentes du registre sont transférées
docker push registry.example.com/equipe/mon-site:1.0
# Sur un autre serveur : récupère l'image
docker pull registry.example.com/equipe/mon-site:1.0Pour Docker Hub, le nom prend la forme votre-compte/mon-site:1.0, sans adresse de registre.
6. Un site PHP et sa base MariaDB avec Docker Compose#
Un site a rarement besoin d'un seul conteneur. Docker Compose décrit l'ensemble dans un fichier compose.yaml, placé à côté du Dockerfile :
services:
web:
build: . # construit l'image à partir du Dockerfile du dossier
ports:
- "8080:80" # publie le site sur le port 8080 de l'hôte
environment:
DB_PASSWORD: ${DB_PASSWORD} # valeur lue dans le fichier .env, jamais écrite ici
depends_on:
db:
condition: service_healthy # attend que la base soit prête
db:
image: mariadb:11.8 # image officielle, version fixée
environment:
MARIADB_DATABASE: boutique
MARIADB_USER: boutique
MARIADB_PASSWORD: ${DB_PASSWORD}
MARIADB_RANDOM_ROOT_PASSWORD: "1"
volumes:
- donnees-db:/var/lib/mysql # les données vivent dans un volume, hors du conteneur
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
volumes:
donnees-db:Le mot de passe est placé dans un fichier .env du même dossier, que Compose lit automatiquement et que l'on n'enregistre pas dans Git :
DB_PASSWORD=remplacez-par-un-mot-de-passe-longCôté PHP, le code se connecte à la base par son nom de service, db, grâce au réseau que Compose crée pour le projet :
$pdo = new PDO('mysql:host=db;dbname=boutique', 'boutique', getenv('DB_PASSWORD'));
echo 'PHP ', PHP_VERSION, ' - MariaDB ', $pdo->query('SELECT VERSION()')->fetchColumn();On lance et on pilote l'ensemble :
# Construit l'image du site si besoin, puis démarre les deux conteneurs en arrière-plan
docker compose up -d --build
# État des services, santé comprise (healthy / unhealthy)
docker compose ps
# Journaux du service web, en direct
docker compose logs -f web
# Ouvre un client SQL dans le conteneur de la base
docker compose exec db mariadb -u boutique -p boutique
# Arrête et supprime les conteneurs et le réseau ; le volume de données est conservé
docker compose downToutes ces commandes ont été vérifiées sur un serveur Docker Engine récent avant publication. Attention à une option : docker compose down -v supprime aussi les volumes, donc les données de la base. Elle sert à repartir de zéro en développement, jamais en production.
7. Construire en plusieurs étapes (multi-stage build)#
Si votre projet utilise Composer, inutile d'installer Composer dans l'image de production. Une première étape installe les dépendances, la seconde ne récupère que le dossier vendor/ :
# Étape 1 : installer les dépendances avec l'image officielle de Composer
FROM composer:2 AS dependances
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-interaction --prefer-dist --no-scripts
# Étape 2 : l'image finale, sans Composer
FROM php:8.4-apache
RUN docker-php-ext-install pdo_mysql opcache \
&& cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY --from=dependances /app/vendor/ /var/www/html/vendor/
COPY --chown=www-data:www-data public/ /var/www/html/L'option --no-scripts évite que Composer exécute des scripts qui auraient besoin du reste du code ; adaptez-la si votre projet en dépend.
Bonnes pratiques#
- Fixer les versions. Écrivez
php:8.4-apacheoumariadb:11.8, jamaislatest. Taguez aussi vos propres images avec un numéro de version ou une date, pas seulementlatest: c'est ce qui permet de revenir à la version précédente en cas de problème. - Garder les images légères. Partez d'une image de base adaptée (les variantes
-alpineou-slimexistent pour beaucoup d'images), n'installez que le nécessaire, supprimez les caches de paquets dans la même instructionRUNque l'installation, et utilisez le multi-stage build pour les outils de construction. - Ne pas tourner en root. Par défaut, le processus principal d'un conteneur est lancé en root. Ajoutez une instruction
USER. Pour Apache, cela suppose d'écouter sur un port supérieur à 1024, car un utilisateur ordinaire ne peut pas ouvrir le port 80 :
FROM php:8.4-apache
RUN docker-php-ext-install pdo_mysql opcache \
&& cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
&& sed -i 's/^Listen 80$/Listen 8080/' /etc/apache2/ports.conf \
&& sed -i 's/<VirtualHost \*:80>/<VirtualHost *:8080>/' /etc/apache2/sites-available/000-default.conf
COPY --chown=www-data:www-data public/ /var/www/html/
# À partir d'ici, tout s'exécute avec l'utilisateur www-data
USER www-data
EXPOSE 8080- Aucun secret dans l'image. Mots de passe, clés d'API et certificats ne doivent jamais être copiés dans une image ni passés en
ARG: quiconque récupère l'image peut les lire, couche par couche. Transmettez-les au démarrage (variables d'environnement, fichiers de secrets de Compose) ; pour un secret nécessaire pendant la construction, utilisezRUN --mount=type=secretde BuildKit. - Une responsabilité par conteneur. Le site dans un conteneur, la base dans un autre, le cache dans un troisième. Chacun se met à jour, redémarre et se surveille séparément.
- Les données hors du conteneur. Un conteneur doit pouvoir être supprimé et recréé à tout moment sans perte : bases de données dans des volumes, fichiers envoyés par les utilisateurs dans un volume ou un bind mount.
- Journaux sur la sortie standard. Envoyez les journaux de l'application sur la sortie standard ou d'erreur pour qu'ils soient lisibles avec
docker logset collectés par vos outils. - Reconstruire régulièrement. Une image figée n'intègre plus les correctifs de sécurité. Reconstruisez vos images pour profiter des mises à jour de l'image de base.
Les pièges les plus fréquents#
- Un port publié ouvert à tout Internet. Docker ajoute ses propres règles de pare-feu sur Linux, et la documentation officielle prévient qu'un port publié peut contourner les règles d'outils comme ufw. Si un service ne doit être joignable que depuis le serveur, publiez-le sur l'adresse locale :
-p 127.0.0.1:8080:80. - Des données perdues au
docker rm. Sans volume, la base de données disparaît avec son conteneur. - Un php.ini absent, déjà évoqué : sans copie du modèle de production, les réglages ne sont pas ceux que vous croyez.
- Des droits de fichiers incohérents avec un bind mount : le conteneur voit les identifiants numériques (UID/GID) des fichiers de l'hôte. Si l'utilisateur du conteneur n'a pas le même identifiant que le propriétaire des fichiers, il ne pourra pas les lire ou les écrire.
- Le disque qui se remplit. Anciennes images, conteneurs arrêtés et cache de construction s'accumulent.
docker system dfmontre la place occupée,docker image prunesupprime les images inutilisées sans nom. - Un conteneur qui ne redémarre pas après un redémarrage du serveur. Ajoutez une politique de redémarrage :
--restart unless-stoppedavecdocker run, ourestart: unless-stoppeddans Compose.
Retour d'expérience : comment Websource utilise Docker#
Le 6 novembre 2026, nous avons migré nos hébergements vers des conteneurs Docker orchestrés par Kubernetes, site par site et sans coupure. Voici ce que nous en retenons côté Docker.
- Chaque site a sa propre image. Un site n'en gêne pas un autre : ses extensions, sa version de PHP et ses réglages lui appartiennent.
- Une image « socle » par version de PHP, alignée sur la configuration de nos serveurs : même php.ini, mêmes extensions que celles proposées dans l'espace client. Les extensions y sont installées mais désactivées ; chaque site active les siennes. Changer une extension ou un réglage depuis l'espace client se répercute sur le conteneur sans reconstruire tout le socle.
- Les fichiers du client restent sur le serveur, montés dans le conteneur (un bind mount). C'est ce qui permet au FTP, à l'espace client, aux sauvegardes et aux quotas de continuer à fonctionner comme avant. Le conteneur tourne avec l'identifiant de l'utilisateur du client, pas en root.
- Création automatique. Quand un client commande un hébergement sur websource.fr, son compte est créé puis, en arrière-plan, son conteneur est construit et déployé, en 25 secondes environ. L'installation en un clic de WordPress ou de PrestaShop fonctionne dans ce conteneur. Si la mise en conteneur échoue, le site reste servi par l'ancienne méthode (PHP-FPM) : pas de coupure pour le client.
- Un registre d'images privé stocke toutes nos images ; chaque nouvelle version est construite, poussée dans ce registre puis déployée.
Trois pièges concrets, en plus de celui du php.ini :
- Garder le même chemin que sur l'hôte. Beaucoup de CMS enregistrent des chemins absolus dans leur configuration ou leur cache. Monter le site au même chemin dans le conteneur que sur le serveur évite des erreurs difficiles à diagnostiquer.
- Les directives
php_admin_valuedans un .htaccess. Sous PHP-FPM, elles étaient simplement ignorées ; dans un conteneur Apache avec le module PHP intégré (mod_php), elles provoquent une erreur 500. Il faut les retirer et placer ces réglages dans le php.ini. - Vérifier les extensions réellement disponibles. Toutes les extensions n'existent pas pour toutes les versions de PHP. Notre construction note la liste de ce qui a réellement été installé, pour signaler une extension indisponible plutôt que de la découvrir en production.
Ces sites sont hébergés dans nos offres d'hébergement web ; la section « Notre infrastructure » de cette page présente l'ensemble.
Les limites de Docker seul#
Docker est excellent pour fabriquer et lancer des conteneurs sur une machine. Dès que l'on gère plusieurs serveurs ou des dizaines de sites, il manque des choses :
- Un seul serveur. Docker Engine pilote les conteneurs de la machine sur laquelle il tourne. Si ce serveur tombe, ses conteneurs tombent avec lui ; rien ne les relance ailleurs.
- Pas de répartition automatique. Choisir sur quel serveur placer un conteneur selon la mémoire et le processeur disponibles reste à votre charge.
- Pas de montée en charge automatique. Ajouter des copies d'un site quand le trafic augmente, puis les retirer, demande des scripts maison.
- Des mises à jour à orchestrer soi-même. Remplacer un conteneur par sa nouvelle version sans couper le site implique de lancer le nouveau, vérifier sa santé, basculer le trafic, puis arrêter l'ancien.
La politique --restart relance un conteneur arrêté, mais seulement sur la même machine. Docker propose aussi un mode multi-serveurs, Swarm ; dans les faits, l'outil le plus répandu pour ce rôle est Kubernetes, un orchestrateur qui répartit les conteneurs sur plusieurs serveurs, les relance en cas de panne, en ajoute quand la charge monte et les met à jour progressivement.
Docker fabrique les images, Kubernetes les fait tourner à grande échelle. Notre article Kubernetes : pods, Deployments, StatefulSets et DaemonSets pour orchestrer vos conteneurs Docker prend la suite de celui-ci, et Docker et Kubernetes ensemble montre comment nous combinons les deux, supervision Prometheus et Grafana comprise. Pour automatiser la chaîne construction, envoi et déploiement, lisez notre article sur la CI/CD.
Glossaire Docker et Kubernetes#
| Terme | Définition |
|---|---|
| Bind mount | Dossier existant du serveur hôte rendu visible dans un conteneur. |
| cgroups | Fonction du noyau Linux qui limite et mesure les ressources (mémoire, processeur) d'un groupe de processus. |
| CMD | Commande ou arguments par défaut d'un conteneur, remplaçables au lancement. |
| Conteneur | Instance en cours d'exécution d'une image, isolée du reste du système. |
| containerd | Moteur qui gère le cycle de vie des conteneurs, utilisé par Docker Engine et par Kubernetes. |
| Docker Compose | Outil qui décrit et lance plusieurs conteneurs liés à partir d'un fichier YAML. |
| Docker Hub | Registre public par défaut de Docker, qui héberge notamment les images officielles. |
| Dockerfile | Fichier texte décrivant les étapes de construction d'une image. |
| .dockerignore | Liste des fichiers exclus du contexte de construction. |
| ENTRYPOINT | Programme exécuté au démarrage d'un conteneur. |
| HEALTHCHECK | Commande périodique qui vérifie que l'application d'un conteneur répond. |
| Image | Modèle en lecture seule, fait de couches, à partir duquel on crée des conteneurs. |
| Couche (layer) | Une étape de l'image, produite par une instruction du Dockerfile, partagée et mise en cache. |
| Kubernetes | Orchestrateur qui répartit, relance et met à jour des conteneurs sur plusieurs serveurs ; présenté dans l'article suivant de cette série. |
| Machine virtuelle | Ordinateur simulé par un hyperviseur, avec son propre système d'exploitation. |
| Multi-stage build | Construction en plusieurs étapes dont seule la dernière forme l'image finale. |
| Namespaces | Fonction du noyau Linux qui donne à un processus sa propre vue du système (processus, réseau, fichiers). |
| OCI | Open Container Initiative : standards ouverts du format et de l'exécution des conteneurs. |
| Orchestrateur | Outil qui répartit et pilote des conteneurs sur plusieurs serveurs, comme Kubernetes. |
| Port publié | Port de l'hôte relié à un port du conteneur pour le rendre joignable de l'extérieur. |
| Registre (registry) | Serveur qui stocke et distribue des images. |
| Réseau Docker | Réseau virtuel où les conteneurs se joignent par leur nom. |
| Tag | Étiquette de version d'une image, après les deux-points (php:8.4-apache). |
| Variable d'environnement | Valeur de configuration transmise au conteneur au démarrage. |
| Volume | Espace de stockage géré par Docker, qui survit à la suppression des conteneurs. |
Questions fréquentes#
Docker est-il une machine virtuelle ?#
Non. Une machine virtuelle simule un ordinateur complet avec son propre système d'exploitation. Un conteneur Docker est un processus isolé qui partage le noyau du système hôte : il n'embarque que l'application et ses bibliothèques. Sur Mac et Windows, Docker Desktop utilise toutefois une petite machine virtuelle Linux pour faire tourner les conteneurs.
Quelle est la différence entre une image et un conteneur ?#
L'image est un modèle figé, en lecture seule, qui contient l'application et sa configuration. Le conteneur est une instance de cette image en cours d'exécution, avec une couche inscriptible qui disparaît à sa suppression. Une même image peut lancer autant de conteneurs que nécessaire.
Où sont stockées les données d'un conteneur ?#
Ce qu'un conteneur écrit dans son propre système de fichiers est perdu quand il est supprimé. Les données à conserver, comme celles d'une base de données ou les fichiers envoyés par les utilisateurs, doivent être placées dans un volume géré par Docker ou dans un dossier de l'hôte monté dans le conteneur (bind mount).
Faut-il utiliser le tag latest ?#
Non, en production. Le tag latest n'est qu'un nom par défaut : il ne garantit ni la version la plus récente ni la même version d'un jour à l'autre. Fixez une version précise, comme php:8.4-apache ou mariadb:11.8, et taguez vos propres images avec un numéro de version pour pouvoir revenir en arrière.
Docker suffit-il pour héberger plusieurs sites en production ?#
Sur un seul serveur, oui, avec une politique de redémarrage et une bonne gestion des volumes. Mais Docker ne relance pas les conteneurs sur un autre serveur en cas de panne, ne répartit pas la charge entre machines et n'ajoute pas de copies automatiquement. Pour cela, on utilise un orchestrateur comme Kubernetes, ce que fait Websource pour ses hébergements.
Article publié le 06/11/2026 sous la signature de Jonathan Gutierrez, rédigé à partir des sources citées ci-dessus, puis relu avant publication. Une information vous semble inexacte ou datée ? Signalez-le nous, nous corrigeons.







