Guide pratique et concis pour maîtriser la conteneurisation. Des fondamentaux aux bonnes pratiques.
Fini le "ça marche sur ma machine" ! Docker standardise l'environnement d'exécution. Que vous soyez développeur ou sysadmin, les conteneurs garantissent que votre code s'exécutera de la même manière en dev, en test et en prod. C'est la brique fondamentale du DevOps moderne.
Concepts fondamentaux de la conteneurisation
Docker est une plateforme de conteneurisation qui permet d'empaqueter une application avec toutes ses dépendances dans une unité standardisée appelée conteneur.
| Conteneur | VM |
|---|---|
| Partage le kernel hôte | OS complet inclus |
| Démarrage en secondes | Démarrage en minutes |
| Taille : quelques Mo | Taille : plusieurs Go |
| Isolation au niveau processus | Isolation complète |
Configuration sur différents systèmes
# Mise à jour et installation des dépendances sudo apt update sudo apt install -y ca-certificates curl gnupg # Ajout de la clé GPG officielle curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg # Ajout du dépôt Docker echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list # Installation de Docker Engine sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Téléchargez et installez Docker Desktop depuis docker.com. L'installation inclut :
# Ajouter l'utilisateur au groupe docker (évite sudo) sudo usermod -aG docker $USER # Appliquer les changements (ou se reconnecter) newgrp docker # Vérifier l'installation docker --version Docker version 24.0.7, build afdd53b docker run hello-world
Commandes essentielles au quotidien
# Lancer un conteneur interactif docker run -it ubuntu bash # Lancer en arrière-plan (détaché) docker run -d nginx # Nommer le conteneur docker run -d --name mon-nginx nginx # Mapper un port (hôte:conteneur) docker run -d -p 8080:80 nginx # Supprimer automatiquement à l'arrêt docker run --rm alpine echo "Hello"
| Commande | Description |
|---|---|
docker ps |
Lister les conteneurs en cours |
docker ps -a |
Lister tous les conteneurs |
docker stop ID |
Arrêter un conteneur |
docker start ID |
Démarrer un conteneur arrêté |
docker rm ID |
Supprimer un conteneur |
docker logs ID |
Voir les logs |
docker exec -it ID bash |
Entrer dans un conteneur |
docker stop a1b au lieu de l'ID
complet.
Cycle de vie et gestion avancée
# Infos détaillées (JSON) docker inspect mon-conteneur # Logs en temps réel docker logs -f mon-conteneur # Statistiques d'utilisation docker stats # Processus dans le conteneur docker top mon-conteneur # Copier des fichiers docker cp fichier.txt mon-conteneur:/app/ docker cp mon-conteneur:/app/log.txt ./
# Limiter la mémoire docker run -d --memory 512m nginx # Limiter le CPU docker run -d --cpus 0.5 nginx # Politique de redémarrage docker run -d --restart always nginx docker run -d --restart on-failure:3 nginx
Créer et gérer des images Docker
# Télécharger une image docker pull nginx:latest # Lister les images locales docker images # Supprimer une image docker rmi nginx # Nettoyer les images non utilisées docker image prune -a
# Image de base FROM node:18-alpine # Répertoire de travail WORKDIR /app # Copie des fichiers de dépendances COPY package*.json ./ # Installation des dépendances RUN npm ci --only=production # Copie du code source COPY . . # Port exposé EXPOSE 3000 # Commande de démarrage CMD ["node", "server.js"]
# Build l'image docker build -t mon-app:1.0 . # Tagger pour Docker Hub docker tag mon-app:1.0 username/mon-app:1.0 # Se connecter à Docker Hub docker login # Publier l'image docker push username/mon-app:1.0
.dockerignore pour exclure node_modules, .git, etc.
Persistance et partage de données
| Type | Usage | Exemple |
|---|---|---|
| Volume | Données persistantes gérées par Docker | -v data:/app/data |
| Bind mount | Partage de fichiers hôte ↔ conteneur | -v ./src:/app/src |
| tmpfs | Données temporaires en RAM | --tmpfs /tmp |
# Créer un volume docker volume create mes-donnees # Lister les volumes docker volume ls # Utiliser un volume docker run -d -v mes-donnees:/var/lib/mysql mysql # Inspecter un volume docker volume inspect mes-donnees # Supprimer les volumes orphelins docker volume prune
# Monter le dossier courant docker run -d -v $(pwd):/app node:18 # Syntaxe longue (plus explicite) docker run -d \ --mount type=bind,source=$(pwd)/src,target=/app/src \ node:18 # Volume en lecture seule docker run -v ./config:/app/config:ro nginx
Communication entre conteneurs
| Driver | Description |
|---|---|
bridge |
Réseau isolé par défaut (communication via IP) |
host |
Partage le réseau de l'hôte (pas d'isolation) |
none |
Aucun réseau |
overlay |
Communication multi-hôtes (Swarm) |
# Créer un réseau docker network create mon-reseau # Lancer des conteneurs sur ce réseau docker run -d --name db --network mon-reseau mysql docker run -d --name app --network mon-reseau node-app # Les conteneurs peuvent se joindre par leur nom # L'app peut accéder à MySQL via "db:3306"
# Port spécifique docker run -p 8080:80 nginx # Plusieurs ports docker run -p 80:80 -p 443:443 nginx # Port aléatoire sur l'hôte docker run -P nginx # Restreindre à localhost docker run -p 127.0.0.1:8080:80 nginx
Orchestrer plusieurs conteneurs
Définissez votre infrastructure dans un fichier YAML.
version: '3.8' services: web: image: nginx:alpine ports: - "8080:80" volumes: - ./html:/usr/share/nginx/html networks: - app-net db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: secret volumes: - db-data:/var/lib/mysql networks: - app-net volumes: db-data: networks: app-net:
# Démarrer toute la stack (détaché) docker compose up -d # Arrêter et supprimer les conteneurs docker compose down # Voir les logs de toute la stack docker compose logs -f # Reconstruire les images si Dockerfile a changé docker compose up -d --build
Environnements et dépendances
Attendre qu'un service soit réellement prêt (pas juste démarré).
services: web: depends_on: db: condition: service_healthy db: image: postgres healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5
APP_PORT=3000 DB_PASSWORD=secure_pass
services: tools: profiles: ["debug"] # Ne démarre que si --profile debug image: adminer web: ports: - "${APP_PORT}:80"
Au-delà du conteneur unique
| Feature | Docker Swarm | Kubernetes (K8s) |
|---|---|---|
| Complexité | Faible (Intégré à Docker) | Élevée (Courbe d'apprentissage) |
| Installation | docker swarm init |
Cluster complexe (Minikube, K3s) |
| Usage idéal | PME, Projets simples | Enterprise, Cloud Scale |
Production Ready
# Étape 1 : Build FROM node:18 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Étape 2 : Image finale légère FROM node:18-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 CMD ["node", "dist/server.js"]
USERdocker scoutFROM node:18-alpine # Créer un utilisateur non-root RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser WORKDIR /app COPY --chown=appuser:appgroup . . # Healthcheck HEALTHCHECK --interval=30s --timeout=3s \ CMD wget -q --spider http://localhost:3000/health || exit 1 CMD ["node", "server.js"]
# Supprimer tous les conteneurs arrêtés docker container prune # Supprimer les images orphelines docker image prune # Nettoyage complet (attention !) docker system prune -a --volumes # Voir l'espace disque utilisé docker system df
nginx:1.25) plutôt que latest.