Conteneuriser votre site : configuration Docker, optimisation des images, orchestration et limites de ressources

Avec Docker, l'objectif d'un site autonome n'est pas de passer à K8s, mais de transformer « ça tourne sur ce serveur » en « ça tourne sur n'importe quelle machine ». Les critères à respecter : une image de production sous 200 Mo, un build multi-étapes, des limites CPU et mémoire déclarées explicitement pour chaque conteneur, et un simple docker compose sur un seul VPS. Le point contre-intuitif : une image gonflée ne vient presque jamais d'un excès de code, mais des outils de compilation, du cache npm et du code source laissés dans l'image d'exécution. Ces trois éléments réunis font passer une image de 200 Mo à 1,5 Go.

独立站Docker镜像:从1.2GB臃肿镜像到180MB生产镜像Independent-site Docker: from 1.2GB bloated image to 180MB prod 反直觉:镜像大不是因为代码多,而是因为把构建工具和源码全塞进了运行层Counter-intuitive: bloat comes from build tools shipped into runtime 错误做法:单阶段构建Wrong: single-stage build 正确做法:多阶段构建Right: multi-stage build Ubuntu基础镜像 500MBUbuntu base 500MB Node/PHP 全量 200MBFull runtime 200MB 源码 + node_modules 300MBSource + node_modules 300MB 编译工具链 200MBBuild toolchain 200MB alpine 基础 5MBalpine base 5MB 运行时 40MBRuntime 40MB 系统库 20MBSystem libs 20MB 应用代码 30MBApp code 30MB 静态资源 80MBAssets 80MB PHP扩展/依赖 50MBPHP ext 50MB 合计 ≈ 225MBTotal ≈ 225MB 资源限制:CPU 1至2核、内存512MB至1GB是独立站容器的甜蜜点;不设限制会把宿主机内存吃光Limits: 1-2 CPU, 512MB-1GB RAM; without limits host starves 编排选择:单台VPS用docker compose即可,3台以上再考虑Swarm;K8s对独立站是过度设计Compose for 1 box, Swarm for 3+, K8s overkill
Comparaison de la taille des images : build mono-étape vs multi-étapes

Conteneuriser votre site : configuration Docker, optimisation des images, orchestration et limites de ressources

Conclusion d’abord : Avec Docker, l’objectif d’un site autonome n’est pas de passer à K8s, mais de transformer « ça tourne sur ce serveur » en « ça tourne sur n’importe quelle machine ». Les critères à respecter : une image de production sous 200 Mo, un build multi-étapes, des limites CPU et mémoire déclarées explicitement pour chaque conteneur, et un simple docker compose sur un seul VPS. Le point contre-intuitif : une image gonflée ne vient presque jamais d’un excès de code, mais des outils de compilation, du cache npm et du code source laissés dans l’image d’exécution. Ces trois éléments réunis font passer une image de 200 Mo à 1,5 Go.

1. Pourquoi conteneuriser un site autonome plutôt que de tout installer directement sur le serveur

Installer PHP, Nginx et MySQL directement sur un VPS fonctionne, mais trois problèmes surgissent au bout de six mois. D’abord, un nouveau collaborateur met deux jours à configurer son environnement. Ensuite, pour migrer d’Aliyun vers Tencent Cloud, il faut réinstaller toutes les dépendances. Enfin, lors d’une mise à jour de sécurité, on n’ose pas toucher à la version en production. Docker empaquette l’application et ses dépendances dans une image immuable, et c’est précisément ce qu’il résout.

Un critère simple : si votre documentation de déploiement contient « d’abord apt install php8.3-fpm, puis installez ces 12 extensions, puis modifiez ces 8 lignes de php.ini », c’est que vous avez besoin de conteneuriser. Mettez ces 12 extensions et ces 8 réglages dans le Dockerfile : n’importe quelle machine les reproduira ensuite avec un simple docker run. Pour l’articulation avec le CDN et les ressources statiques, voir Accélération mondiale par CDN.

Modes de déploiement Coût de reproduction de l’environnement Migration de serveur Vitesse de rollback Taille adaptée
Installation directe sur le VPS 2 jours-homme Réinstaller toutes les dépendances Via snapshot, 30 minutes Phase de prototype
Installation par script Shell 0,5 jour-homme Exécution du script, écarts persistants 15 minutes Site unique en production depuis 1 an
Image Docker 5 minutes Pull de l’image et exécution Changement de tag, 3 minutes Site en production, environnements multiples
Orchestration Docker Compose 5 minutes Copie du yaml et exécution Rollback en un clic Application + base de données + file d’attente

2. Comment écrire un Dockerfile sans le gonfler

L’erreur la plus fréquente dans un Dockerfile de site autonome, c’est le build mono-étape : FROM ubuntu, puis installation de PHP, installation de Composer, composer install, COPY du code source, exposition du port. Les images produites ainsi dépassent souvent 1 Go, car elles embarquent les outils de compilation, le cache npm et le dossier .git. La bonne approche est le build multi-étapes : la première étape utilise une image builder pour compiler le front-end et installer les dépendances composer ; la seconde ne copie dans l’image alpine que les artefacts compilés et le runtime.

Quelques règles strictes : choisissez alpine plutôt qu’ubuntu comme image de base ; le .dockerignore doit exclure node_modules, .git, .env et le répertoire d’upload ; ajoutez –no-dev et –no-cache à npm/composer install ; exécutez l’application avec un utilisateur non-root. Objectif de taille d’image : rester sous 200 Mo pour une application PHP/Node pure, et sous 400 Mo avec des ressources statiques. Pour l’analyse des images et la base de sécurité, voir Sauvegarde et restauration : s’entraîner à réagir.

Un cas concret : une équipe découvre six mois après la mise en production que son image pèse 1,4 Go. En inspectant les couches avec docker history, elle constate que composer install n’avait pas l’option –no-dev, embarquant phpunit et toutes les dépendances de développement dans l’image de production ; et que COPY . . avait aussi copié le répertoire .git. Après passage à un build multi-étapes, l’étape builder installe les dépendances et l’étape d’exécution ne copie que le répertoire vendor et le répertoire public : l’image tombe à 180 Mo et le déploiement passe de 3 minutes à 40 secondes.

Niveau Erreur fréquente Écriture optimisée Gain de taille
Image de base FROM ubuntu:22.04 FROM php:8.3-fpm-alpine environ 400 Mo
Dépendances système apt-get install build-essential Build multi-étapes, installation dans l’étape builder environ 200 Mo
Dépendances PHP composer install composer install –no-dev –no-cache environ 80 Mo
Dépendances front-end COPY . . npm ci && npm run build dans l’étape builder environ 300 Mo
Répertoire source COPY . /var/www COPY –from=builder /app/public ./public environ 100 Mo
Utilisateur d’exécution exécution en root RUN adduser -D app gain de sécurité, pas de taille

III. Comment orchestrer un site indépendant avec docker compose

L’architecture type d’un site indépendant repose sur quatre conteneurs : Nginx en reverse proxy, l’application PHP-FPM ou Node, MySQL/PostgreSQL et Redis. Un seul docker-compose.yml relie ces quatre services, un volume persistant conserve les données MySQL, seuls les ports 80 et 443 de Nginx sont exposés, les autres services communiquent sur le réseau interne. N’exposez pas le port MySQL sur Internet.

Un extrait de configuration prêt à l’emploi : Nginx depends_on php, php depends_on db et redis ; le healthcheck exécute curl -fsS http://localhost/health toutes les 30 secondes ; la politique de redémarrage est unless-stopped pour tous. Pour la sauvegarde, montez régulièrement le volume de données MySQL vers un répertoire de sauvegarde sur l’hôte, puis synchronisez-le à distance avec rsync. Pour le monitoring d’une orchestration multi-conteneurs, voir Surveillance et alertes du site.

Exemple concret : un serveur léger Alibaba Cloud de 4 cœurs et 8 Go fait tourner trois conteneurs WordPress, MySQL et Redis. Le conteneur MySQL monte un named volume pour stocker les données, Nginx mappe les ports 80 et 443 sur l’hôte, le conteneur WordPress n’expose aucun port et passe uniquement par le réseau interne. Après un redémarrage de l’hôte, docker compose up -d relance automatiquement les trois services, sans avoir à se connecter pour démarrer quoi que ce soit à la main. C’est la valeur la plus simple de compose.

Services Image de base Limite CPU Limite mémoire Persistance
nginx nginx:1.27-alpine 0,5 cœur 128 Mo Non
php-fpm / node php:8.3-fpm-alpine 1 à 2 cœurs 512 Mo à 1 Go non (volume monté pour les uploads)
mysql mysql:8.4 1 à 2 cœurs 1 à 2 Go oui (répertoire data)
redis redis:7-alpine 0,5 cœur 256 Mo oui (persistance AOF)
cron/file d’attente même image que l’application 0,5 cœur 256 Mo Non

4. Limites de ressources : un conteneur sans plafond finit par étouffer toute la machine

Beaucoup de gens utilisent Docker pour se simplifier la vie et ne précisent ni –cpus ni –memory au démarrage. Résultat : dès que PHP-FPM rencontre une requête lente, la mémoire passe de 512 Mo à 4 Go et pousse le MySQL hébergé sur la même machine à l’OOM. Chaque conteneur doit déclarer explicitement ses limites de ressources, c’est une obligation.

Repères de quota pour un site en propre : conteneur applicatif 1 à 2 cœurs de CPU, 512 Mo à 1 Go de mémoire ; conteneur MySQL selon le volume de données, 1 cœur et 1 Go suffisent en dessous de 10 Go ; Nginx et Redis 0,5 cœur et 128 à 256 Mo chacun. Réservez 20 % de marge sur l’hôte pour le daemon Docker et le système. Un critère simple : 80 % de la mémoire totale de l’hôte allouée aux conteneurs, 20 % au système ; au-delà de ce ratio, ajoutez une machine. Allouez le CPU en fonction des pics, pas de la moyenne : le trafic d’un site en propre connaît des pics en semaine et des creux la nuit, dimensionner sur la moyenne provoque des files d’attente aux heures de pointe.

Taille du site Configuration recommandée Allocation CPU Allocation mémoire Visites mensuelles indicatives
Phase de validation 1 VPS 2 cœurs 2 Go App 1 cœur + DB 0,5 cœur App 512 Mo + DB 1 Go <50 000
Phase de croissance stable 1 VPS 4 cœurs 8 Go App 2 cœurs + DB 1,5 cœur App 2 Go + DB 4 Go 50 000 à 300 000
Pic multilingue 2 × 4 cœurs 8 Go App 2 cœurs par machine 2 Go par machine, DB 4 Go à part 300 000 à 1 million
Pic du jour de promotion App étendue horizontalement à 3 ou 4 machines 2 cœurs par machine 2 Go par machine Trafic salon et promotion

5. Quand passer à Swarm ou K8s

La conclusion contre-intuitive est la suivante : 90 % des sites en propre n’ont pas besoin de K8s. docker compose fait tourner 4 à 8 conteneurs sur un seul VPS, de quoi tenir un site B2B jusqu’à 100 000 visites par jour. Ne passez à Swarm que si l’un de ces trois signaux apparaît : besoin de faire tourner l’application sur plus de deux VPS, besoin de basculer automatiquement le trafic en déploiement bleu-vert, besoin de redémarrer automatiquement les conteneurs tombés via les health checks.

Le critère est simple : si votre docker-compose.yml dépasse 30 services, ou si plus de 5 personnes maintiennent cet environnement en même temps, envisagez un orchestrateur. Sinon, compose reste la meilleure solution : consacrer à la rédaction et au SEO l’énergie que demanderait la maintenance de K8s rapporte davantage.

La difficulté de K8s, c’est qu’il faut une personne dédiée à la maintenance d’etcd, des plugins réseau et du contrôleur Ingress, et le seul dépannage prend une journée par semaine. Pour une petite équipe, il est plus rentable de consacrer ce temps à la rédaction et au SEO. Si vous devez vraiment déployer plusieurs instances à l’avenir, la conception de l’équilibrage de charge est détaillée dans Équilibrage de charge et déploiement multi-instances.

Outil d’orchestration Temps d’apprentissage Coût de maintenance Nombre de nœuds adapté Quand le choisir
docker compose 1 à 2 jours Très faible 1 instance Premier choix pour 90 % des sites en propre
docker swarm 3 à 5 jours Faible 2 à 10 machines Besoin d’orchestration multi-machines et de mises à jour progressives
K8s 2 à 4 semaines Élevée Plus de 5 machines Plusieurs équipes, plusieurs services, mise à l’échelle automatique
K8s managé par un cloud 1 à 2 semaines Moyenne Plus de 10 machines DevOps dédié déjà en place

FAQ — Questions fréquentes

Docker est-il plus lent qu’une installation directe sur serveur pour un site en propre ?
La conteneurisation elle-même coûte moins de 2 % de performance, c’est imperceptible. Ce qui ralentit vraiment, c’est de fournir MySQL dans un conteneur, ou de ne pas monter de volume de données et d’écrire ainsi dans la couche overlay. La bonne méthode : persister les conteneurs MySQL et Redis avec des named volumes, et garder l’application sans état. C’est plus propre qu’une installation directe sur le serveur, à performance égale.
Quelle taille d’image est raisonnable ?
Une image d’exécution PHP/Node pure reste sous 200 Mo, et sous 400 Mo avec les artefacts de build front-end. Au-delà de 1 Go, on peut quasiment affirmer que les outils de compilation ou le code source ont été embarqués. Regardez la taille avec docker images, puis identifiez la couche la plus lourde avec docker history. Les coupables habituels : node_modules non supprimé dans un build multi-étapes, ou apt-get install sans apt-get clean derrière.
docker compose tient-il 100 000 visites par jour ?
Un VPS 4 cœurs 8 Go qui fait tourner compose tient sans problème jusqu’à 100 000 visites par jour. Le goulot d’étranglement est généralement MySQL, pas Nginx. Au-delà de 200 000 visites par jour, commencez par sortir MySQL sur une machine dédiée et faites tourner l’application via compose sur deux VPS. Attendez 500 000 visites par jour avant d’envisager un load balancer et plusieurs instances : n’achetez pas de complexité pour un trafic qui n’existe pas encore.
Comment gérer les logs et les fichiers uploadés dans les conteneurs ?
N’écrivez pas les logs dans la couche du conteneur : montez-les dans un répertoire de l’hôte ou sortez-les sur stdout pour que docker json-file les collecte. Les fichiers uploadés (pièces jointes des demandes, PDF envoyés par les clients) doivent être montés sur un volume de l’hôte, sinon tout est perdu à la reconstruction du conteneur. Je recommande de monter le répertoire uploads sur un volume dédié et de le synchroniser régulièrement vers un stockage objet avec rsync. Pour la méthode complète de dump et de sauvegarde de la base de données, voir Sauvegarde et restauration : s’entraîner à réagir.
Quand passer à K8s, quand rester sur compose ?
Envisagez K8s quand deux de ces trois signaux se manifestent : vos instances applicatives doivent tourner sur plus de trois machines, vous avez un besoin clair d’autoscaling, et quelqu’un dans l’équipe peut assurer la maintenance et le débogage de K8s au quotidien. Avant cela, compose suffit largement. Le coût caché de K8s, c’est le débogage d’etcd, du CNI, d’Ingress et de la gestion des certificats : au moins une journée de travail par semaine et par personne.
Une image alpine peut-elle manquer de dépendances et ne pas démarrer ?
Oui. Le piège le plus courant : la compilation des extensions PHP a besoin de build-base, mais pas l’exécution. Le build multi-étapes résout le problème : l’étape builder installe build-base et les dépendances de compilation comme libpng-dev, l’étape d’exécution n’installe que les bibliothèques d’exécution comme libpng. Si c’est trop de travail, utilisez directement l’image officielle php:8.3-fpm-alpine, qui embarque déjà les extensions courantes. En cas d’undefined symbol, installez ce qui manque au fur et à mesure.

Pour conclure

La conteneurisation apporte 80 % de sa valeur à un site e-commerce indépendant par la cohérence des environnements, et 20 % par l’orchestration. Commencez par écrire correctement le Dockerfile, compresser l’image sous 200 Mo et bien gérer vos quatre services dans le fichier compose : vous réglez ainsi le problème le plus douloureux de votre stack, la dérive des environnements. Ne vous précipitez pas sur K8s, c’est un autre métier à plein temps.

Feuille de route : la première semaine, écrivez un Dockerfile multi-étapes et faites passer l’image de 1 Go à 200 Mo ; la deuxième, orchestrez Nginx + application + MySQL + Redis avec compose, en montant correctement les volumes de données ; la troisième, branchez le pipeline CI/CD sur le registre d’images pour qu’un push de code déclenche automatiquement la création de l’image. Ces trois étapes faites, la migration d’un serveur passe de deux jours à deux heures. Pour l’articulation avec le CDN et la supervision, voir Accélération mondiale par CDN. Au quotidien, un coup d’œil hebdomadaire à docker system df pour nettoyer les images orphelines évite que le disque se remplisse peu à peu d’images inutiles.

Une phrase à retenir : la première étape de la conteneurisation n’est pas de passer à K8s, mais de pouvoir lancer votre site sur n’importe quel serveur vierge avec une seule commande.

Cratère
Cratère Expert Cratère

Officiel de l'organisme · Cratère Crater

Cratère (Crater) est une société de services d'expansion internationale spécialisée dans le développement de sites WordPress autonomes, le référencement Google et la croissance globale GEO, au service des secteurs du matériel intelligent, de l'équipement industriel, du SaaS et des énergies nouvelles.

Capacités produitLivre blanc méthodologiqueRapports sectoriels
965partages
78articles de base de connaissances