Build. Ship. Run. Anywhere.
Docker permet d'emballer ton application avec tout son environnement (dépendances, config, OS minimal) dans une boîte portable appelée conteneur. Cette boîte tourne de façon identique sur n'importe quelle machine.
Sans Docker, ton programme c'est comme un jeu qui ne marche que sur ta machine — "ça marche chez moi !" Un conteneur Docker c'est comme une cartouche de jeu : elle contient tout le nécessaire pour tourner, peu importe la console. Tu la copies, elle marche partout, à l'identique.
La recette. Un snapshot figé, en lecture seule, qui décrit l'environnement complet.
→ Comme un ISO de jeu. Elle ne tourne pas toute seule.
L'instance en cours. C'est une image qu'on a lancée — elle tourne, consomme de la RAM.
→ Comme la partie en cours. Tu peux en lancer plusieurs depuis la même image.
C'est la confusion la plus fréquente chez les débutants Docker. Voici la différence :
Éteint le conteneur.
Comme éteindre ton PC — il n'est plus allumé, mais il existe encore. Tu peux le rallumer avec docker start.
docker stop mon_conteneur
# Conteneur éteint mais EXISTE encore
# Visible dans : docker ps -a
Supprime le conteneur.
Comme jeter le PC à la poubelle — il n'existe plus du tout. L'image reste, mais ce conteneur précis est parti.
docker rm mon_conteneur
# ⚠️ Doit être arrêté d'abord
docker rm -f mon_conteneur
# Force stop + rm en une commande
docker stop MON_CONT puis docker rm MON_CONT. Ou en une seule commande : docker rm -f MON_CONT.# Méthode rapide — script officiel Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# ⚠️ IMPORTANT — Ajouter ton user au groupe docker
# Sans ça, tu devras taper sudo avant CHAQUE commande docker
sudo usermod -aG docker $USER
newgrp docker # ou déconnecte / reconnecte ta session
# Vérifier que tout fonctionne
docker --version
docker run hello-world # si tu vois "Hello from Docker!" → ✅
hello-world télécharge une mini image et affiche un message. Si tu le vois, Docker est bien installé et fonctionnel.# Chercher une image sur Docker Hub (hub.docker.com)
docker search ubuntu
# Télécharger une image depuis Docker Hub
docker pull ubuntu # dernière version (latest)
docker pull ubuntu:22.04 # version précise (recommandé)
docker pull nginx:alpine # image légère basée Alpine
docker pull python:3.11-slim # Python allégé
# Lister toutes les images téléchargées en local
docker images
# Affiche : REPOSITORY | TAG | IMAGE ID | CREATED | SIZE
# Supprimer une image
docker rmi ubuntu # par nom
docker rmi a1b2c3d4e5f6 # par ID
# Supprimer toutes les images non utilisées
docker image prune # images orphelines seulement
docker image prune -a # toutes celles non utilisées
docker rm.docker run = télécharge l'image si absente + crée + démarre le conteneur en une commande.
# Lancer Ubuntu en mode interactif avec un terminal bash
docker run -it ubuntu bash
# -i = garde stdin ouvert (interactif)
# -t = alloue un terminal (TTY)
# → Tu te retrouves DANS le conteneur, comme un SSH
# Lancer en arrière-plan (detached, sans bloquer le terminal)
docker run -d nginx
# → retourne l'ID du conteneur, ton terminal reste libre
# Nommer son conteneur (TOUJOURS le faire !)
docker run --name mon_serveur -d nginx
# → plus facile que de retenir l'ID
# Exposer un port : -p PORT_MACHINE:PORT_CONTENEUR
docker run -p 8080:80 nginx
# → http://localhost:8080 → port 80 du conteneur nginx
# Monter un dossier local dans le conteneur
docker run -v $(pwd):/app -it ubuntu bash
# → ton dossier courant est visible dans /app du conteneur
# Auto-suppression après arrêt (parfait pour les tests)
docker run --rm ubuntu echo "test"
# → se lance, affiche "test", se supprime tout seul
# Tout combiné — cas réel
docker run -d --name web -p 8080:80 -v $(pwd):/usr/share/nginx/html nginx
# ── LISTER ─────────────────────────────────────────────
docker ps # conteneurs EN COURS seulement
docker ps -a # TOUS (en cours + arrêtés) ← le plus utile
# ── DÉMARRER / ARRÊTER ─────────────────────────────────
docker start mon_conteneur # rallumer un conteneur arrêté
docker stop mon_conteneur # éteindre proprement (attend l'arrêt)
docker kill mon_conteneur # forcer l'arrêt immédiat (urgent)
docker restart mon_conteneur # stop + start en une commande
# ── ENTRER DANS UN CONTENEUR EN VIE ────────────────────
docker exec -it mon_conteneur bash
# Ouvre un shell DANS le conteneur pendant qu'il tourne
# → comme faire SSH dans le conteneur
# → si bash n'existe pas (image alpine) : utilise sh
docker exec -it mon_conteneur sh
# Lancer une commande sans ouvrir de shell
docker exec mon_conteneur ls /app
# ── LOGS ET MONITORING ─────────────────────────────────
docker logs mon_conteneur # voir tous les logs
docker logs -f mon_conteneur # logs en temps réel (Ctrl+C pour quitter)
docker logs --tail 50 mon_conteneur # 50 dernières lignes seulement
docker stats # CPU/RAM de TOUS les conteneurs
docker inspect mon_conteneur # toutes les infos en JSON
# ── COPIER DES FICHIERS ────────────────────────────────
docker cp mon_conteneur:/app/fichier.txt . # conteneur → local
docker cp fichier.txt mon_conteneur:/app/ # local → conteneur
# ── SUPPRIMER ──────────────────────────────────────────
docker rm mon_conteneur # ⚠️ doit être arrêté
docker rm -f mon_conteneur # force stop + rm
docker rm $(docker ps -aq) # supprimer TOUS les arrêtés
# Dockerfile — chaque ligne est une instruction
# chaque instruction crée une "couche" (layer) dans l'image
FROM ubuntu:22.04
# OBLIGATOIRE en 1er — image de base sur laquelle on s'appuie
RUN apt-get update && apt-get install -y gcc make
# Exécute une commande AU MOMENT DU BUILD (construction de l'image)
# Chaque RUN = une nouvelle couche = met en cache séparément
WORKDIR /app
# Définit le dossier de travail par défaut
# Toutes les commandes suivantes s'exécutent depuis /app
COPY . /app
# Copie les fichiers locaux VERS l'image
# "." = tout le dossier courant → vers /app dans l'image
ENV PORT=8080
# Définit une variable d'environnement dans le conteneur
EXPOSE 8080
# Documente que le conteneur écoute sur ce port
# ⚠️ C'est seulement de la documentation — le port n'est pas ouvert
# Il faut quand même -p au docker run pour y accéder
CMD ["./mon_prog"]
# Commande lancée quand on fait "docker run"
# Peut être écrasée par l'utilisateur : docker run image AUTRE_CMD
CMD définit la commande par défaut — l'utilisateur peut la remplacer (docker run image bash). ENTRYPOINT est fixe, l'utilisateur ne peut pas la changer (seulement lui ajouter des arguments). Pour débuter, utilise CMD.# Dockerfile à la racine de ton projet
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
gcc \
make \
valgrind \
&& rm -rf /var/lib/apt/lists/*
# Le && rm nettoie le cache apt → image plus légère
WORKDIR /project
COPY . .
# Copie tout le dossier courant vers /project
RUN gcc -Wall -Werror -Wextra -pedantic main.c -o prog
CMD ["./prog"]
# Pour construire et tester ce Dockerfile :
docker build -t mon-projet . # construire l'image
docker run --rm mon-projet # lancer (se supprime après)
docker run --rm -it mon-projet bash # entrer dedans pour tester
Quand tu fais COPY . ., Docker copie tout ton dossier. Le .dockerignore te permet d'exclure les fichiers inutiles ou sensibles pour garder une image légère.
# .dockerignore — à créer à la racine du projet
.git # historique git inutile dans l'image
.gitignore
*.o # binaires compilés
*.a
a.out
.env # variables d'environnement / secrets ⚠️
*.log
node_modules/ # pour les projets Node.js
__pycache__/ # pour les projets Python
README.md
Dockerfile # pas besoin dans l'image
.dockerignore peut réduire la taille de ton image de plusieurs centaines de Mo. C'est une bonne pratique à toujours appliquer.# Construire depuis le dossier courant (Dockerfile présent)
docker build .
# Construire et nommer/tagger l'image
docker build -t mon-image .
docker build -t mon-image:1.0 . # avec version
docker build -t mon-image:latest . # latest = version par défaut
# Reconstruire sans cache (si quelque chose ne se met pas à jour)
docker build --no-cache -t mon-image .
# Voir le détail de chaque étape
docker build --progress=plain -t mon-image .
RUN apt-get install, il ne le refait pas. C'est pour ça que les builds suivants sont rapides. --no-cache force tout à refaire depuis zéro.Problème : quand tu supprimes un conteneur (docker rm), tout ce qui était dedans disparaît. Les volumes permettent de sauvegarder les données en dehors du conteneur.
# ── BIND MOUNT — utiliser un dossier local (développement) ──
# Ton dossier local ↔ visible dans le conteneur
docker run -v $(pwd):/app -it ubuntu bash
# Modifie un fichier dans /app → modifié sur ta machine aussi !
# Parfait en dev pour ne pas rebuild à chaque changement
# ── VOLUME DOCKER — géré par Docker (production) ────────────
docker volume create mes-donnees # créer
docker volume ls # lister
docker volume rm mes-donnees # supprimer
# Utiliser le volume dans un conteneur
docker run -v mes-donnees:/data -it ubuntu bash
# Les données dans /data survivent même si le conteneur est supprimé
✅ Parfait en développement — modifie en local, effet immédiat dans le conteneur.
✅ Parfait en production — données persistantes gérées par Docker, indépendantes du système.
docker login
# Entrer son username et mot de passe Docker Hub
docker tag mon-image:1.0 noham/mon-image:1.0
# Format : username/nom-image:version
docker push noham/mon-image:1.0
# L'image est maintenant sur hub.docker.com/r/noham/mon-image
docker pull noham/mon-image:1.0
docker run noham/mon-image:1.0
Au lieu de lancer plusieurs docker run à la main, Docker Compose te permet de tout définir dans un seul fichier docker-compose.yml et de tout lancer en une commande.
# docker-compose.yml — exemple app web + base de données
services:
web: # nom du service (tu choisis)
build: . # construire depuis le Dockerfile local
ports:
- "8080:5000" # port machine:port conteneur
volumes:
- ./app:/app # bind mount pour le dev
depends_on:
- db # attend que db soit prêt
db:
image: postgres:15 # image depuis Docker Hub
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secret
volumes:
pgdata: # volume nommé pour persister la DB
# Commandes Docker Compose
docker compose up # lancer tout (bloque le terminal)
docker compose up -d # lancer en arrière-plan
docker compose up --build # rebuild les images avant de lancer
docker compose down # arrêter et supprimer les conteneurs
docker compose down -v # + supprimer les volumes
docker compose ps # état des services
docker compose logs -f # logs de tous les services
docker compose exec web bash # shell dans le service 'web'
# Voir combien d'espace Docker utilise
docker system df
# Nettoyage sélectif
docker container prune # supprimer conteneurs arrêtés
docker image prune # supprimer images orphelines
docker image prune -a # supprimer toutes les images inutilisées
docker volume prune # supprimer volumes inutilisés
# Nettoyage total — tout d'un coup
docker system prune # conteneurs + images orphelines + réseaux
docker system prune -a # + toutes les images non utilisées
docker system prune -a supprime tout ce qui n'est pas en cours d'utilisation. Utile pour libérer de l'espace, mais tu devras re-pull les images dont tu as besoin.╔══════════════════════════════════════════════════════════════════╗
║ LES CONCEPTS EN UNE PHRASE ║
╚══════════════════════════════════════════════════════════════════╝
# Image = recette statique (sur disque, lecture seule)
# Conteneur = instance active d'une image (en mémoire, en vie)
# Dockerfile= script qui construit une image (RUN, COPY, CMD...)
# Volume = stockage persistant lié à un conteneur
╔══════════════════════════════════════════════════════════════════╗
║ STOP ≠ RM — NE JAMAIS CONFONDRE ║
╚══════════════════════════════════════════════════════════════════╝
# docker stop → éteint le conteneur (toujours récupérable)
# docker rm → supprime définitivement le conteneur
# docker rmi → supprime une IMAGE (pas un conteneur)
╔══════════════════════════════════════════════════════════════════╗
║ WORKFLOW TYPE DÉBUTANT ║
╚══════════════════════════════════════════════════════════════════╝
docker pull ubuntu # 1. récupérer une image
docker run -it --name test ubuntu bash # 2. créer + entrer dedans
# [... faire des trucs dans le conteneur ...]
# exit ← pour sortir du conteneur
docker start test # 3. rallumer si besoin
docker exec -it test bash # 4. re-entrer dedans
docker stop test # 5. éteindre
docker rm test # 6. supprimer quand fini
╔══════════════════════════════════════════════════════════════════╗
║ RÈGLES D'OR ║
╚══════════════════════════════════════════════════════════════════╝
# ✅ Toujours nommer tes conteneurs avec --name
# ✅ Utilise --rm pour les conteneurs de test (nettoyage auto)
# ✅ Ajoute un .dockerignore à chaque projet
# ✅ Préfère ubuntu:22.04 à ubuntu:latest (version stable)
# ✅ Utilise -d pour les serveurs, -it pour les shells
# ❌ Ne jamais stocker de mots de passe dans le Dockerfile
# ❌ Ne pas confondre docker stop (éteindre) et docker rm (supprimer)