Tu dĂ©veloppes une application et tu passes plus de temps Ă rĂ©gler des problĂšmes d’environnement que Ă coder ? « Ăa marche sur ma machine » â on a tous dit ou entendu cette phrase au moins une fois. La bonne nouvelle, c’est qu’il existe une solution Ă©prouvĂ©e : Docker.
Dans cet article, tu vas apprendre Ă maĂźtriser la conteneurisation avec Docker, depuis les bases jusqu’aux bonnes pratiques pour tes projets de dĂ©veloppement quotidiens. Que tu sois dĂ©veloppeur backend, frontend ou full-stack, Docker est devenu un outil indispensable â et pas seulement pour les DevOps.
Qu’est-ce que Docker et pourquoi l’utiliser ?
Docker est une plateforme de conteneurisation qui permet d’empaqueter une application avec toutes ses dĂ©pendances dans un conteneur lĂ©ger et portable. Contrairement Ă une machine virtuelle classique, un conteneur partage le noyau du systĂšme hĂŽte tout en isolant complĂštement l’application.
Les avantages concrets pour un développeur
- Environnement reproductible : fini les « ça marche en local mais pas en prod ». Le mĂȘme Dockerfile produit le mĂȘme environnement partout.
- Isolation : chaque projet a ses propres dépendances, sans conflit avec les autres projets sur ta machine.
- Onboarding rapide : un nouveau dĂ©veloppeur dans l’Ă©quipe lance un
docker compose upet tout est opĂ©rationnel en quelques secondes. - ĂcosystĂšme riche : PostgreSQL, Redis, MySQL, MongoDB, Nginx⊠tout est disponible en une ligne de commande.
Selon l’enquĂȘte Stack Overflow 2025, Docker est utilisĂ© par plus de 55% des dĂ©veloppeurs professionnels, ce qui en fait l’outil de dĂ©veloppement le plus adoptĂ© aprĂšs Git.
Installer Docker sur sa machine
L’installation varie selon ton systĂšme d’exploitation :
- Windows / macOS : tĂ©lĂ©charge Docker Desktop, l’installateur inclut tout ce dont tu as besoin.
- Linux (Ubuntu/Debian) :
# Mettre à jour les paquets sudo apt update # Installer les prérequis sudo apt install ca-certificates curl gnupg # Ajouter la clé GPG officielle de Docker sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # Ajouter le dépÎt echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Installer Docker sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin # Vérifier l'installation docker --version docker compose version
AprÚs installation, ajoute ton utilisateur au groupe docker pour éviter de taper sudo à chaque commande :
sudo usermod -aG docker $USER # Déconnecte-toi et reconnecte-toi (ou redémarre la session)
Les concepts fondamentaux
Avant de coder, il faut comprendre trois notions clés :
- Image : un template en lecture seule contenant l’OS, les dĂ©pendances et le code de l’application. On la construit avec un
Dockerfile. - Conteneur : une instance exĂ©cutable d’une image. Tu peux en lancer plusieurs Ă partir de la mĂȘme image.
- Volume : un espace de stockage persistant qui survit Ă l’arrĂȘt du conteneur (idĂ©al pour les bases de donnĂ©es).
Ton premier Dockerfile
Prenons une application Python avec FastAPI. Voici un Dockerfile typique :
# Utiliser une image de base légÚre FROM python:3.12-slim # Définir le répertoire de travail WORKDIR /app # Copier d'abord les dépendances (cache layer) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copier le code de l'application COPY . . # Exposer le port EXPOSE 8000 # Commande de démarrage CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Remarque l’ordre : on copie requirements.txt avant le code source. Docker met en cache chaque Ă©tape (layer) du Dockerfile. Tant que requirements.txt ne change pas, Docker rĂ©utilise le cache pour l’installation des dĂ©pendances â ce qui accĂ©lĂšre considĂ©rablement les builds quotidiens.
Construire et lancer l’image
# Construire l'image docker build -t mon-api . # Lancer un conteneur docker run -d -p 8000:8000 --name mon-api-container mon-api # Voir les logs docker logs mon-api-container # ArrĂȘter le conteneur docker stop mon-api-container # Supprimer le conteneur docker rm mon-api-container
Docker Compose : orchestrer plusieurs services
Une application moderne a rarement un seul service. GĂ©nĂ©ralement, tu as besoin d’une base de donnĂ©es, d’un cache Redis, d’un serveur web⊠C’est lĂ que Docker Compose entre en jeu.
Crée un fichier compose.yaml (ou docker-compose.yml) à la racine de ton projet :
services:
api:
build: .
ports:
- "8000:8000"
volumes:
- .:/app # Montage du code local (hot reload)
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydb
- REDIS_URL=redis://cache:6379
depends_on:
- db
- cache
db:
image: postgres:16
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
cache:
image: redis:7-alpine
volumes:
postgres_data:Un simple docker compose up -d lance toute la stack : ton API, PostgreSQL et Redis, avec un réseau interne qui les relie automatiquement.
Astuce pratique : le volume montĂ© .:/app te permet de modifier ton code en local et de voir les changements en temps rĂ©el (grĂące au hot reload d’Uvicorn/FastAPI). Plus besoin de rebuild Ă chaque modification !
Bonnes pratiques pour un Dockerfile optimisé
1. Utilise des images légÚres
PrĂ©fĂšre -alpine ou -slim aux images complĂštes. Une image python:3.12-slim pĂšse ~150 Mo contre ~900 Mo pour python:3.12. C’est plus rapide Ă tĂ©lĂ©charger, plus rapide Ă builder, et moins de surface d’attaque.
2. Multi-stage builds
Pour les langages compilĂ©s (Go, Rust, Java), ou mĂȘme pour Python avec des dĂ©pendances natives, le multi-stage build est indispensable :
# Stage 1 : compilation FROM node:20 AS builder WORKDIR /app COPY package*.json . RUN npm ci COPY . . RUN npm run build # Stage 2 : production (image finale légÚre) FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
L’image finale ne contient que les fichiers statiques servis par Nginx (quelques Mo), sans Node.js ni les dĂ©pendances de build.
3. Ăvite d’exĂ©cuter en root
Par sécurité, crée un utilisateur non-root dans ton Dockerfile :
FROM python:3.12-slim # Créer un utilisateur non-root RUN addgroup --system app && adduser --system --ingroup app app WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . # Passer à l'utilisateur non-root USER app CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
4. Utilise .dockerignore
Comme .gitignore, le fichier .dockerignore Ă©vite d’envoyer des fichiers inutiles dans le contexte de build :
node_modules .git .env *.log __pycache__ *.pyc .venv
Résultat : un build plus rapide, des images plus petites, et moins de risques de fuite de secrets.
Docker pour le développement quotidien
Au-delà du déploiement, Docker est un véritable couteau suisse pour le développeur.
Base de données en un clic
Besoin d’une base PostgreSQL pour tester une feature ? Pas besoin d’installer PostgreSQL sur ta machine :
docker run -d --name mypg \ -e POSTGRES_USER=dev \ -e POSTGRES_PASSWORD=dev \ -e POSTGRES_DB=testdb \ -p 5432:5432 \ postgres:16
Quand tu as fini, docker stop mypg && docker rm mypg et ta machine reste propre.
Tests d’intĂ©gration avec Docker
Docker est parfait pour les tests d’intĂ©gration en CI/CD. Tu lances des conteneurs temporaires (base de donnĂ©es, cache, API mockĂ©e), tu exĂ©cutes les tests, puis tu dĂ©truis tout :
# Dans ta CI (GitHub Actions, GitLab CI) docker compose -f compose.test.yml up -d # Attendre que les services soient prĂȘts sleep 5 # Lancer les tests pytest # Nettoyer docker compose -f compose.test.yml down -v
Environnement de développement isolé
Avec les Dev Containers (VS Code + extension Dev Containers), tu peux mĂȘme dĂ©velopper directement dans un conteneur. Ton IDE est connectĂ© au conteneur : tout l’outillage (Python, Node, extensions) vit dans le conteneur, pas sur ta machine hĂŽte. Chaque projet a son environnement parfaitement isolĂ©.
Commandes Docker essentielles
Voici un mémo des commandes que tu utiliseras le plus souvent :
| Commande | à quoi ça sert |
|---|---|
docker ps | Lister les conteneurs en cours d’exĂ©cution |
docker ps -a | Lister tous les conteneurs (y compris arrĂȘtĂ©s) |
docker images | Lister les images disponibles localement |
docker pull postgres | Télécharger une image sans lancer de conteneur |
docker exec -it <id> bash | Ouvrir un terminal dans un conteneur en cours |
docker logs -f <id> | Suivre les logs en temps réel |
docker system prune | Nettoyer les ressources inutilisées (images, conteneurs, volumes) |
docker compose logs -f | Suivre les logs de tous les services |
Les erreurs courantes (et comment les éviter)
â « Port dĂ©jĂ utilisĂ© »
Si le port 8000 est dĂ©jĂ occupĂ©, change le mappage : -p 8001:8000 (port hĂŽte 8001 â port conteneur 8000).
â Conteneur qui s’arrĂȘte immĂ©diatement
Un conteneur s’arrĂȘte dĂšs que le processus principal se termine. VĂ©rifie que ton CMD ou ENTRYPOINT lance un processus qui reste en avant-plan (pas de daemon off manquant cĂŽtĂ© Nginx, pas de script qui se termine immĂ©diatement).
â Permissions sur les volumes montĂ©s
Le conteneur tourne souvent avec UID 1000 (ou 0 en root), alors que ton utilisateur local a un UID diffĂ©rent. Les fichiers créés par le conteneur dans un volume appartiennent Ă l’utilisateur du conteneur. Solution : aligner les UIDs ou utiliser user dans compose.yaml.
â Oubli de .dockerignore
Sans .dockerignore, le répertoire node_modules (plusieurs centaines de Mo) est envoyé au daemon Docker à chaque build, ce qui ralentit tout. Ajoute-le dÚs le début du projet.
Docker en production : ce qu’il faut savoir
Docker est excellent en dĂ©veloppement et en CI, mais en production, tu auras besoin d’un orchestrateur comme Docker Swarm ou Kubernetes pour gĂ©rer le dĂ©ploiement, le scaling et la rĂ©silience. Pour commencer, Docker Compose en production sur un VPS unique est tout Ă fait acceptable pour un projet personnel ou une petite PME.
Points d’attention pour la production :
- Utiliser des secrets Docker (
docker secret) plutĂŽt que des variables d’environnement pour les mots de passe - Mettre en place des healthchecks pour que l’orchestrateur sache si ton service est vivant
- Limiter les ressources (
--memory,--cpus) pour Ă©viter qu’un conteneur ne monopolise le serveur - Configurer des logging drivers (json-file avec rotation, ou fluentd)
Pour aller plus loin
Docker est un outil qui s’apprend par la pratique. Voici quelques pistes pour continuer :
- Dockeriser un projet existant : prends un de tes projets actuels et ajoute-lui un Dockerfile et un compose.yaml
- Multi-container : ajoute un reverse proxy Nginx, un cache Redis, une file de messages RabbitMQ
- CI/CD pipeline : configure GitHub Actions pour builder et pousser ton image sur Docker Hub
- Certification DCA : la certification Docker Certified Associate est reconnue dans l’industrie
Conclusion
Docker a transformĂ© la façon dont on dĂ©veloppe, teste et dĂ©ploie les applications. En maĂźtrisant la conteneurisation, tu gagnes en productivitĂ©, tu Ă©limines les problĂšmes d’environnement et tu rends tes projets plus professionnels.
Commence par dockeriser un petit projet ce week-end â un script Python, une API Node.js, ou mĂȘme un site statique. La courbe d’apprentissage est rapide, et les bĂ©nĂ©fices sont immĂ©diats.
Tu as dĂ©jĂ utilisĂ© Docker dans un projet ? Des questions sur un cas particulier ? Partage ton expĂ©rience en commentaire â c’est en confrontant la thĂ©orie Ă la pratique qu’on progresse vraiment.