« Ça marche sur ma machine! 🤷♂️ »
Cette phrase légendaire, on l’a tous entendue (ou prononcée 😅). C’est le cauchemar des équipes de dev :
- Les versions qui matchent pas
- Le code tourne nickel en local
- Impossible à déployer en prod
- Les dépendances qui partent en vrille
C’est exactement le problème que Docker résout avec une approche simple : « Si ça marche dans le container, ça marchera partout ».
Plongeons dans le monde des containers avec des exemples concrets et sans jargon inutile. Tu vas voir, c’est plus simple qu’il n’y paraît !
💩 Le problème de « ça marche chez moi »
Imaginez cette situation (totalement fictive, bien sûr 😅) :
- Vous : PHP 8.2, MySQL 8.0, Apache 2.4
- Collègue 1 : PHP 8.1, MariaDB 10.5, Nginx
- Collègue 2 : XAMPP avec PHP 7.4
- Production : PHP 8.0, MySQL 5.7, Apache 2.2
Résultat ? Un code qui fonctionne parfaitement sur votre machine peut :
- Générer des warnings chez votre collègue
- Créer des bugs impossibles à reproduire en local
- Carrément crasher en production 💥
La solution container : l’analogie du transport maritime
🚢 Avant les containers maritimes, charger un navire était un cauchemar :
- Caisses de tailles différentes
- Processus de chargement complexe
- Risques de dégâts importants
- Temps de manutention considérable
📦 L’invention du container maritime standardisé a tout changé :
- Taille standardisée
- Empilable facilement
- Transférable entre bateau, train, camion
- Processus de manutention unifié
🐳 Docker fait exactement la même chose pour nos applications :
| AVANT : « Ça dépend de plein de trucs… » 😰 | APRÈS : « Ça marche partout ! » 🐳 |
🤔 Pourquoi Docker change la donne ?
🎯 Cohérence
• Même environnement pour TOUTE l’équipe
• Production = Local : enfin !
• Adieu le fameux « ça marche chez moi » !
🔒 Isolation
• Chaque projet vit dans sa bulle
• Fini les conflits de versions
• Votre machine reste propre
🌍 Portabilité
• Déployez où vous voulez
• Windows, Mac, Linux ? Peu importe !
• CI/CD ? Un jeu d’enfant
⚡️ Productivité
• Nouveau dev ? Pas de stress !
• Exit les docs d’install interminables
• « git clone && docker compose up » 🚀
🎯 Au programme de cette aventure Docker
Vous allez découvrir :
- 🐳 Les concepts clés (images, containers, volumes…)
- 📝 Comment créer votre première image Docker
- ⚡️ Les commandes Docker indispensables
- 🔧 La mise en place d’un environnement LAMP complet
- 👍 Les bonnes pratiques pour bien démarrer
⏱️ Temps de lecture estimé : 15 minutes
🎯 Niveau : Débutant → Intermédiaire
Prêt(e) à révolutionner votre façon de développer ? C’est parti ! 🚀
🎓 Les concepts clés de Docker : Images vs Containers
🧑🍳 L’Image Docker = La Recette
- Les instructions étape par étape
- La liste des ingrédients (dépendances)
- Partageable avec d’autres (DockerHub)
- Immuable (comme une recette bien établie)
🍽️ Le Container = Le Plat Cuisiné
- Une « instance » de votre recette
- Modifiable en cours d’utilisation
- Multipliable à volonté
- Isolé des autres plats
💡 En pratique :
- Une image PHP = la recette de base
- Chaque container = une instance en cours d’exécution
- Besoin de 3 projets PHP ? = 3 containers différents !
🤔 Pour bien comprendre :
Si l’image est votre recette de gâteau préférée, les containers sont tous les gâteaux que vous préparez avec !
# Créer plusieurs containers à partir d'une même image docker run --name php-app-1 php:8.2-apache docker run --name php-app-2 php:8.2-apache # Comme faire plusieurs gâteaux avec la même recette !
La différence entre VM et Container
Pas de grand discours : une VM c’est comme déménager avec toute ta maison, un container c’est juste prendre ton sac à dos ! 🎒
Le Dockerfile expliqué
Un Dockerfile, c’est comme une liste d’instructions pour construire votre environnement :
# L'image de base (comme les ingrédients de base)
FROM php:8.2-apache
# Installation des dépendances (comme préparer ses ustensiles)
RUN apt-get update && apt-get install -y \
libzip-dev \
zip \
&& docker-php-ext-install zip pdo_mysql
# Copie des fichiers de l'application (comme mettre les ingrédients)
COPY ./src /var/www/html/
# Configuration d'Apache (comme régler le four)
RUN a2enmod rewrite
# Le port à exposer (comme choisir le plat de service)
EXPOSE 80
🏛️ Docker Hub ?
Imaginez un « Spotify » pour vos images Docker : cherchez, téléchargez, utilisez !
# Télécharger une image depuis Docker Hub docker pull php:8.2-apache # Voir les images disponibles localement docker images # Chercher une image sur Docker Hub docker search mysql
Les concepts réseau 🌐 dans Docker
Docker crée des réseaux virtuels pour connecter vos containers :
# Créer un réseau docker network create mon-reseau # Connecter des containers docker run --network mon-reseau --name php-app php:8.2-apache docker run --network mon-reseau --name db mysql:8.0
Imaginez un immeuble où chaque container est un appartement :
- Les voisins (containers) peuvent se parler
- Chacun a son adresse (nom)
- L’entrée est sécurisée (isolation)
Les volumes : Persistance des données
Les volumes permettent de :
- Persister les données
- Partager des fichiers entre host et container
- Sauvegarder facilement
# Créer un volume docker volume create mes-donnees # Utiliser un volume docker run -v mes-donnees:/var/www/html php:8.2-apache
🎯 Docker en 30 secondes :
🏗️ Image = Le plan de construction
📦 Container = Le bâtiment en activité
📝 Dockerfile = Les instructions de montage
💾 Volume = Le garage (où on stocke)
🌐 Network = Les routes entre bâtiments
Votre première image Docker : Un projet PHP simple 🛠️
Préparation du projet
Créons une structure simple pour démarrer :
mon-projet/
├── Dockerfile
├── docker-compose.yml
└── src/
└── index.php
Dans index.php
<?php phpinfo();
Le Dockerfile pas à pas
# Étape 1 : L'image de base
FROM php:8.2-apache
# Étape 2 : Installation des extensions PHP courantes
RUN apt-get update && apt-get install -y \
libzip-dev \
zip \
&& docker-php-ext-install zip pdo_mysql
# Étape 3 : Activation des modules Apache
RUN a2enmod rewrite
# Étape 4 : Copie des fichiers sources
COPY src/ /var/www/html/
# Étape 5 : Permissions
RUN chown -R www-data:www-data /var/www/html
Explications détaillées :
- FROM php:8.2-apache
- Image officielle PHP avec Apache intégré
- Basée sur Debian
- Déjà configurée pour le web
- RUN apt-get update && apt-get install
- Mise à jour des paquets
- Installation des dépendances
- Les extensions PHP courantes
- a2enmod rewrite
- Active le module de réécriture Apache
- Nécessaire pour les URL propres
- Standard pour les frameworks PHP
- COPY src/
- Copie vos fichiers sources
- Le point de départ est relatif au Dockerfile
- La destination est dans le container
Construction de l’image
# Construction basique docker build -t mon-app-php:1.0 . # Avec des arguments de build docker build \ --build-arg PHP_VERSION=8.2 \ -t mon-app-php:1.0 . # Voir le résultat docker images
Lancement et test
# Lancement basique docker run -p 8080:80 mon-app-php:1.0 # Avec montage de volume pour le développement docker run \ -p 8080:80 \ -v $(pwd)/src:/var/www/html \ mon-app-php:1.0
🚀 Décollage immédiat ! ➡️ http://localhost:8080
⚠️ Attention : Un détail important !
Le COPY src/ copie vos fichiers « en dur » dans l’image.
C’est comme une photo : une fois prise, elle ne change plus.
Deux façons de lancer :
– Avec volume : fichiers synchronisés en direct 🔄
– Sans volume : fichiers figés 📸
Les commandes essentielles pour débugger
# Voir les logs docker logs mon-container # Entrer dans le container docker exec -it mon-container bash # Voir les processus docker ps # Inspecter le container docker inspect mon-container
Bonnes pratiques pour votre première image
Optimisation de la taille
# Mauvais ❌
RUN apt-get update
RUN apt-get install -y package1
RUN apt-get install -y package2
# Bon ✅
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
Utilisation du cache
# Mauvais ❌ COPY . /app RUN composer install # Bon ✅ COPY composer.json composer.lock /app/ RUN composer install COPY . /app
Sécurité
# Mauvais ❌ RUN chmod 777 /var/www/html # Bon ✅ RUN chown -R www-data:www-data /var/www/html
🚨 Erreurs courantes et solutions
Le container ne démarre pas
# Vérifier les logs docker logs mon-container # Vérifier les permissions docker exec -it mon-container ls -la /var/www/html
Les modifications ne sont pas prises en compte
# Reconstruire l'image docker build --no-cache -t mon-app-php:1.0 .
Problèmes de performance
# Utiliser les volumes pour le développement docker run -v $(pwd)/src:/var/www/html mon-app-php:1.0
Docker Compose : Orchestrer votre stack LAMP 🎼
Pourquoi Docker Compose ?
Imaginez devoir taper à chaque fois :
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=secret mysql:8.0 docker run -d --name phpmyadmin -e PMA_HOST=mysql -p 8080:80 phpmyadmin docker run -d --name php -v $(pwd):/var/www/html -p 80:80 mon-app-php
🎮 Docker Compose = La télécommande universelle
Un fichier, une commande et toute votre app démarre !
Votre premier docker-compose.yml
services:
# Votre application PHP
app:
build: .
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
depends_on:
- db
# Base de données MySQL
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: mon_app
volumes:
- mysql_data:/var/lib/mysql
# Interface phpMyAdmin
phpmyadmin:
image: phpmyadmin
ports:
- "8082:80"
environment:
- PMA_HOST=db
depends_on:
- db
volumes:
mysql_data:
🎭 Les acteurs de notre application :
📦 APP (PHP + Apache)
- Construit depuis notre Dockerfile
- Accessible sur http://localhost:8080
- Vos fichiers sources sont synchronisés en direct
- Attend que la DB soit prête avant de démarrer
🗄️ DB (MySQL)
- Version 8.0 prête à l’emploi
- Mot de passe root : « secret »
- Base « mon_app » créée automatiquement
- Les données persistent même si on redémarre (le volume qu’on a connecté)
🔧 PHPMYADMIN
- Interface web pour gérer la DB
- Accessible sur http://localhost:8082
- Se connecte automatiquement à MySQL (Utilisateur root par défaut)
- Parfait pour débugger !
💡 Le petit plus : Tous les services démarrent dans le bon ordre grâce à depends_on
A savoir
🗄️ Il y a 2 façons de gérer les volumes :
📂 Version « ./data/mysql:/var/lib/mysql »
- Lie un dossier de la machine au container
- Vous voyez les fichiers directement sur votre machine
- Pratique pour débugger, mais attention aux permissions !
🔒 Version « mysql_data:/var/lib/mysql »
- Crée un espace géré par Docker
- Plus propre et portable
- Idéal pour les données de DB
💡 En résumé :
Premier cas = comme un dossier partagé Dropbox
Deuxième cas = comme un coffre-fort Docker
Les commandes essentielles
# Démarrer tous les services docker compose up -d # Voir les logs de tous les services docker compose logs # Logs d'un service spécifique docker compose logs app # Arrêter tous les services docker compose down # Rebuilder un service docker compose up -d --build app # Voir le statut des services docker compose ps
🤔 docker-compose vs docker compose
Vous verrez les deux écritures, c’est normal ! Ça dépend de :
- Votre installation :
- Docker Desktop → docker compose (intégré)
- Installation manuelle → docker-compose (si installé séparément)
- L’âge des tuto/docs :
- Anciens → docker-compose
- Récents → docker compose
💡 Les deux fonctionnent, mais préférez docker compose quand c’est possible. C’est la version moderne intégrée directement dans Docker !
Debugging avec Docker Compose
📍 Vous devez être dans le même dossier que votre docker-compose.yml avant de lancer les commandes suivantes.
Voir les logs en temps réel
docker compose logs -f
Entrer dans un container
docker compose exec app bash docker compose exec db mysql -u root -p
Vérifier la configuration
docker compose config
Bonnes pratiques et conseils avancés pour Docker 🎯
1. Optimisation des images
Multi-stage builds pour PHP
# Build stage FROM composer:2 as vendor WORKDIR /app COPY composer.json composer.lock ./ RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist # Final stage FROM php:8.2-apache COPY --from=vendor /app/vendor/ /var/www/html/vendor/ COPY src/ /var/www/html/ RUN composer dump-autoload --optimize
💪 Les avantages en 3 points : Plus léger, plus sûr, plus pro !
2. Sécurité
Ne jamais utiliser root
# Créer un utilisateur dédié RUN useradd -r -u 1000 -g www-data appuser USER appuser # Ou utiliser l'utilisateur www-data existant USER www-data
Secrets et variables d’environnement
# ❌ À éviter dans docker-compose.yml (comme ce qu'on a fait avant)
environment:
DB_PASSWORD: super_secret
# ✅ Utiliser des fichiers .env
environment:
DB_PASSWORD: ${DB_PASSWORD}
🎯 Hey ! Notre config est « mode tutoriel ». C’est comme apprendre à faire du vélo : d’abord les petites roues, ensuite le Tour de France !
Debugging et maintenance
Commandes de diagnostic
# Vérifier l'utilisation des ressources docker stats # Nettoyer les ressources inutilisées docker system prune -a # Inspecter les logs docker compose logs -f --tail=100
En conclusion… 🎓
Cet article est conçu comme une introduction approfondie à Docker, pensé pour faciliter la compréhension de concepts parfois complexes. Comme dans tout domaine technique, il existe de nombreuses façons d’accomplir la même chose, et les approches présentées ici ne sont qu’une des multiples possibilités.
L’objectif n’était pas de vous présenter « LA » solution définitive, mais plutôt de :
- Démystifier les concepts fondamentaux de Docker
- Fournir une base solide pour démarrer
- Partager des pratiques qui ont fait leurs preuves (pour moi) dans un contexte pédagogique
N’oubliez pas que la « meilleure » configuration est celle qui :
- Répond à VOS besoins spécifiques
- S’adapte à VOTRE contexte
- Est comprise par VOTRE équipe
Je vous encourage vivement à :
- Expérimenter avec ces concepts
- Adapter ces exemples à vos besoins
- Challenger ces approches
- Explorer d’autres solutions
Comme dirait un vieux sage du DevOps : « Il n’y a pas de mauvaise configuration, il n’y a que des configurations mal adaptées à leur contexte. » 😉
Si cet article vous a donné envie d’explorer davantage Docker, alors il a atteint son objectif.
N’hésitez pas à partager vos retours d’expérience ou à poser vos questions dans les commentaires. Et si vous voulez approfondir certains aspects, jetez un œil à mon article plus avancé sur la mise en place d’un environnement local avec Gluetun VPN et Nginx Proxy Manager.
Happy Dockerizing! 🐳

