Comprendre Docker en l'utilisant. Des premiers conteneurs au multi-stage et au CI/CD. Accessible, progressif, avec des projets pratiques.
débutant
Docker est un outil qui permet d'empaqueter une application et tout ce dont elle a besoin (code, librairies, configuration) dans un conteneur. Ce conteneur tourne de la même maniere sur ton PC, sur le serveur de prod, ou chez n'importe quel hebergeur.
Pourquoi c'est utile ? Parce que le grand classique du dev, c'est "chez moi ca marche". Ton code tourne sur ta machine avec Node 20, mais le serveur a Node 18 et ca casse. Docker regle ca : tu embarques Node 20 dans le conteneur, et il tournera pareil partout.
SANS DOCKER AVEC DOCKER
Ta machine Serveur Une image Docker
Node 20 Node 18 contient Node 20
Lib X v1 Lib X v2 Lib X v1
Config A Config B Config A
│ │ │
▼ ▼ ▼
"Ca marche" "Ca casse" Conteneur identique
partout, tout le temps
Une machine virtuelle (VM) emule un systeme d'exploitation complet. Docker, lui, partage le noyau de l'OS hote et isole juste les processus. C'est beaucoup plus leger.
| Critere | Machine virtuelle | Conteneur Docker |
|---|---|---|
| OS embarque | Completement (guest OS) | Non, partage le noyau hote |
| Poids | Quelques Go | Quelques Mo a quelques centaines de Mo |
| démarrage | Quelques dizaines de secondes | Moins d'une seconde |
| Isolation | Forte (OS separe) | Process-level (suffisant la plupart du temps) |
| Overhead | Important | Faible, quasi natif |
débutant
Trois mots a retenir : image, conteneur, registre.
REGISTRE (Docker Hub) IMAGE (modele) CONTENEUR (instance qui tourne) ┌──────────────┐ docker pull ┌──────────────┐ docker run ┌──────────────┐ │ nginx:1.25 │ ──────────────▶ │ nginx:1.25 │ ─────────────▶ │ nginx:1.25 │ │ alpine:3.19 │ │ (en local) │ │ (en cours) │ │ node:20 │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ Depot distant Modele inerte Processus vivant (telechargeable) (ne tourne pas) (tourne, a un etat)
Une image est un modele inerte. C'est un systeme de fichiers en couches (layers) qui contient le code, les librairies et la configuration. Une image ne tourne pas, elle existe juste.
Un conteneur est une instance vivante d'une image. Quand tu fais docker run nginx, tu crees un conteneur a partir de l'image nginx. Un conteneur a un ID, un nom, un etat (running, stopped), des logs, etc.
Un registre est un depot d'images. Le plus connu est Docker Hub (hub.docker.com). On y telecharge des images avec docker pull et on y publie les siennes avec docker push.
Un Dockerfile est un fichier texte qui decrit comment construire une image. C'est la recette : "prends telle image de base, installe ca, copie ce fichier, lance cette commande".
Docker Compose est un outil qui permet de lancer plusieurs conteneurs ensemble avec un seul fichier YAML. On l'utilise pour les apps multi-services (ex: web + base de donnees).
débutant
L'installation depend de ton systeme. Docker est disponible sur Linux, macOS et Windows.
# Ubuntu / Debian
curl -fsSL https://get.docker.com | sh
# Ajouter ton user au groupe docker (evite sudo a chaque commande)
sudo usermod -aG docker $USER
# Recharger le groupe (ou fermer/rouvrir la session)
newgrp docker
# démarrer le service
sudo systemctl enable --now docker
# Verifier
docker --version
docker run hello-world
# Option 1 : Docker Desktop (interface graphique)
# télécharger sur https://docs.docker.com/desktop/install/mac-install/
# Puis glisser Docker.app dans Applications
# Option 2 : avec Homebrew
brew install --cask docker
# Lancer Docker.app une fois, puis verifier
docker --version
docker run hello-world
# 1. Activer WSL2 (recommande)
# Parametres > Applications > Fonctionnalites facultatives >
# Plus de fonctionnalites Windows > Sous-systeme Windows pour Linux
# 2. Installer Docker Desktop
# télécharger sur https://docs.docker.com/desktop/install/windows-install/
# 3. Pendant l'installation, cocher "Use WSL 2"
# 4. Lancer Docker Desktop, attendre que l'icone soit verte
# 5. Verifier dans PowerShell
docker --version
docker run hello-world
docker --version # Version du client
docker info # Infos detaillees sur le moteur
docker run hello-world # Premier conteneur de test
Si docker run hello-world affiche "Hello from Docker!", ton installation fonctionne.
débutant
docker run --name mon-nginx -p 8080:80 -d nginx:1.25
# └── nom du conteneur ┘ └ port hote:conteneur ┘ └ detach ┘ └ image:tag
Explication de chaque option :
| Option | Role |
|---|---|
--name mon-nginx |
Donne un nom lisible au conteneur (sinon Docker genere un nom aleatoire) |
-p 8080:80 |
Mappe le port 8080 de ta machine vers le port 80 du conteneur. Format hote:conteneur |
-d |
Detached : lance en arrière-plan. Sans cette option, le conteneur occupe le terminal |
-it |
Interactif + terminal. Pour un shell, par exemple docker run -it ubuntu bash |
--rm |
Supprime automatiquement le conteneur quand il s'arrete. Utile pour les tests temporaires |
-e VAR=valeur |
Injecte une variable d'environnement dans le conteneur |
-v /hote:/conteneur |
Monte un volume (fichier ou dossier) de la machine hote vers le conteneur |
# Lancer un serveur web Nginx en arrière-plan
docker run --name web -p 8080:80 -d nginx:1.25
# Ouvrir http://localhost:8080 dans ton navigateur
# Tu vois la page d'accueil de Nginx
# Voir les conteneurs en cours
docker ps
# arrêter le conteneur
docker stop web
# Le redémarrer
docker start web
# Le supprimer (il doit être arrete d'abord)
docker rm web
TA MACHINE (hote) CONTENEUR ┌──────────────────────────┐ ┌──────────────────────┐ │ Port 8080 ───────────────┼─────────│ Port 80 (Nginx) │ │ │ │ │ │ Navigateur → localhost:8080 ─────▶│ Sert la page HTML │ └──────────────────────────┘ └──────────────────────┘
# Lancer un shell bash dans Ubuntu (temporaire, supprime a la sortie)
docker run -it --rm ubuntu:24.04 bash
# Tu es maintenant dans le conteneur. Essaye :
apt update
apt install -y curl
curl http://localhost
exit # quitte ET supprime le conteneur (--rm)
-it combine deux flags : -i (interactive, garde l'entree standard ouverte) et -t (terminal, alloue un pseudo-TTY). Sans -it, tu ne peux pas interagir avec le shell.
débutant
# télécharger une image sans la lancer
docker pull python:3.12-slim
# Lister les images locales
docker images
# Supprimer une image
docker rmi python:3.12-slim
# Supprimer les images inutilisees
docker image prune
# Supprimer toutes les images non utilisees (attention)
docker image prune -a
Une image a un nom et un tag (version). Le tag par defaut est latest, mais il vaut mieux toujours specifier une version precise.
| Image | Tag | Taille approx. | Usage |
|---|---|---|---|
alpine |
3.19 |
~7 Mo | Base minimale, ideale pour les images legeres |
debian |
bookworm-slim |
~80 Mo | Base stable, plus de paquets qu'Alpine |
ubuntu |
24.04 |
~80 Mo | Base complete, populaire |
node |
20-alpine |
~50 Mo | Node.js sur Alpine, leger |
node |
20-slim |
~250 Mo | Node.js sur Debian slim, plus compatible |
python |
3.12-slim |
~130 Mo | Python leger |
nginx |
1.25-alpine |
~40 Mo | Serveur web leger |
postgres |
16-alpine |
~80 Mo | Base de donnees |
:latest en production. Ce tag pointe vers la derniere version, qui peut changer a tout moment. Toujours fixer une version precise (nginx:1.25, node:20-alpine) pour la reproductibilite.
Choisir sa base, c'est le premier choix d'un Dockerfile. Alpine est leger mais peut casser des paquets (musl au lieu de glibc). Debian slim est un bon compromis : compatible, pas trop lourd.
intermédiaire
Un Dockerfile est la recette de ton image. Chaque ligne cree une couche (layer) qui sera mise en cache par Docker.
Dans un dossier de projet, cree un fichier Dockerfile :
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
| Instruction | Role |
|---|---|
FROM |
Image de base. Toujours la première instruction |
WORKDIR |
Definit le dossier de travail dans le conteneur (cree s'il n'existe pas) |
COPY |
Copie des fichiers de la machine hote vers l'image |
RUN |
Execute une commande pendant la construction de l'image (installe des paquets, etc.) |
ENV |
Definit une variable d'environnement dans l'image |
ARG |
Variable disponible uniquement pendant le build (pas au runtime) |
EXPOSE |
Documente le port utilise par l'app (ne publie pas le port, c'est juste informatif) |
CMD |
Commande par defaut au lancement du conteneur. Un seul par Dockerfile |
ENTRYPOINT |
Commande fixe. Combine avec CMD pour des arguments par defaut modifiables |
# Construire une image nommee "mon-api" avec le tag "v1"
docker build -t mon-api:v1 .
# Le point final est important : c'est le "contexte de build"
# (le dossier envoye a Docker pour construire l'image)
# Lancer l'image construite
docker run -p 3000:3000 mon-api:v1
Cree un fichier .dockerignore a cote du Dockerfile pour eviter d'envoyer des fichiers inutiles au build :
node_modules
npm-debug.log
.git
.env
.DS_Store
*.md
test/
node_modules (100 Mo+), il sera envoye a chaque build. Le .dockerignore l'exclut et accelere le build.
Docker met en cache chaque layer. Si tu modifies un fichier, Docker reconstruit seulement les layers a partir du COPY concerne. C'est pour ca qu'on copie package.json avant le code : si le code change mais pas les dependances, le npm ci est pris dans le cache.
Dockerfile Cache ───────────────── ────────────────── FROM node:20-alpine ──▶ OK (cache) WORKDIR /app ──▶ OK (cache) COPY package.json ... ──▶ OK (cache) ← ne change pas souvent RUN npm ci ──▶ OK (cache) ← ne refait pas npm install COPY . . ──▶ REBUILD ← le code a change CMD ["node", ...] ──▶ REBUILD
débutant+
Un conteneur est ephemere : quand tu le supprimes, ses fichiers disparaissent. Pour garder des donnees (base de donnees, config, uploads), on utilise les volumes.
MACHINE HOTE CONTENEUR
┌──────────────────┐ ┌──────────────────┐
│ /var/lib/docker │ │ /app/data │
│ /volumes/ │ │ │
│ mon-volume │◄───────────│ (monte via -v) │
│ /data │ │ │
└──────────────────┘ └──────────────────┘
Donnees persistantes Donnees du conteneur
(survivent a la suppression)
| Type | Syntaxe | Quand l'utiliser |
|---|---|---|
| Volume nomme | -v mon-volume:/app/data |
Docker gere le stockage. Ideale pour les bases de donnees |
| Bind mount | -v /chemin/hote:/app/data |
Monte un dossier de ta machine. Ideale pour le dev (hot reload) |
# Volume nomme : Docker stocke les donnees pour toi
docker run -d --name db -v pg-data:/var/lib/postgresql/data postgres:16-alpine
# Bind mount : monte un dossier de ta machine
docker run -d --name web -p 8080:80 -v ./site:/usr/share/nginx/html nginx:1.25
# Lister les volumes
docker volume ls
# Voir les details d'un volume
docker volume inspect pg-data
# Supprimer un volume (les donnees sont perdues !)
docker volume rm pg-data
# Supprimer tous les volumes inutilises
docker volume prune
docker volume rm supprime definitivement les donnees. Ne jamais faire ca sur un volume de base de donnees en production sans backup.
intermédiaire
Par defaut, les conteneurs sont isoles. Pour les faire communiquer entre eux, on utilise les réseaux Docker.
| Type | Description | Usage |
|---|---|---|
| bridge | réseau virtuel sur la machine. DNS interne (les conteneurs se trouvent par nom) | Par defaut, ideal pour la plupart des apps |
| host | Le conteneur partage le réseau de la machine hote | Performances brutes, pas d'isolation réseau |
| none | Aucun réseau. Le conteneur est completement isole | Taches de calcul hors ligne |
# 1. créer un réseau
docker network create mon-réseau
# 2. Lancer une base de donnees sur ce réseau
docker run -d --name db --network mon-réseau \
-e POSTGRES_PASSWORD=secret \
postgres:16-alpine
# 3. Lancer une app qui peut joindre "db" par son nom
docker run -d --name api --network mon-réseau \
-p 3000:3000 \
-e DB_HOST=db \
-e DB_PORT=5432 \
mon-api:v1
# L'API peut se connecter a "db:5432" (DNS interne de Docker)
réseau "mon-réseau"
┌────────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ "db" │ │ "api" │ │
│ │ Postgres │◄────────│ Node │ │
│ │ :5432 │ DNS │ :3000 │ │
│ └──────────┘ interne└──────────┘ │
│ │
└────────────────────────────────────────────┘
│
▼ -p 3000:3000
PORT 3000 EXPOSE VERS L'HOTE
db dans l'exemple ci-dessus se resout automatiquement vers l'IP du conteneur "db".
intermédiaire
La regle d'or : ne jamais hardcoder une configuration dans l'image. Une variable d'environnement permet de configurer le conteneur au lancement.
# Variable unique
docker run -e PORT=3000 mon-api:v1
# Plusieurs variables
docker run -e PORT=3000 -e DB_HOST=db mon-api:v1
# Depuis un fichier .env
docker run --env-file .env mon-api:v1
FROM node:20-alpine
ENV NODE_ENV=production
ENV PORT=3000
# Ces valeurs sont des valeurs par defaut, surchargeables au runtime
| Critere | ARG | ENV |
|---|---|---|
| Disponible au build | Oui | Oui |
| Disponible au runtime | Non | Oui |
Surchargeable au docker run |
Non | Oui |
| Exemple | Version d'un paquet a installer | URL de base de donnees |
ENV et ARG sont visibles dans l'image avec docker inspect. Utilise les secrets Docker ou passe les variables au runtime via --env-file (et ne committe pas le .env).
intermédiaire
Docker Compose permet de decrire une application multi-conteneurs dans un seul fichier YAML. On lance tout avec une commande. On utilise docker compose (v2, integre a Docker) et non l'ancienne commande docker-compose (v1, separee et obsolete).
Cree un fichier compose.yaml :
services:
web:
image: nginx:1.25-alpine
ports:
- "8080:80"
volumes:
- ./site:/usr/share/nginx/html
api:
build: .
ports:
- "3000:3000"
environment:
- DB_HOST=db
- DB_PORT=5432
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_PASSWORD=secret
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
pg-data:
# Lancer tous les services (en arrière-plan)
docker compose up -d
# Lancer et construire les images en même temps
docker compose up -d --build
# Voir les services en cours
docker compose ps
# Voir les logs de tous les services
docker compose logs -f
# Voir les logs d'un service precis
docker compose logs -f api
# exécuter une commande dans un service
docker compose exec api sh
# arrêter et supprimer les conteneurs (volumes conserves)
docker compose down
# arrêter et supprimer aussi les volumes (attention !)
docker compose down -v
docker compose down -v supprime les volumes. Les donnees de la base seront perdues. Ne l'utilise qu'en dev ou si tu sais ce que tu fais.
depends_on controle l'ordre de démarrage, mais n'attend pas que le service soit pret. Si l'API demarre avant que Postgres ait fini son init, la connexion echouera. Solution : healthcheck (voir section 13) ou retry cote application.
intermédiaire
On construit une stack complete : frontend Nginx + API Node.js + PostgreSQL.
mon-app/
├── compose.yaml
├── frontend/
│ ├── index.html
│ └── Dockerfile
├── api/
│ ├── package.json
│ ├── server.js
│ └── Dockerfile
└── .env
api/server.js :
import express from 'express';
const app = express();
const PORT = process.env.PORT || 3000;
const DB_HOST = process.env.DB_HOST || 'localhost';
const DB_PORT = process.env.DB_PORT || 5432;
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', db: `${DB_HOST}:${DB_PORT}` });
});
app.listen(PORT, () => console.log(`API sur le port ${PORT}`));
api/Dockerfile :
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
frontend/Dockerfile :
FROM nginx:1.25-alpine
COPY index.html /usr/share/nginx/html/
EXPOSE 80
services:
frontend:
build: ./frontend
ports:
- "8080:80"
depends_on:
- api
api:
build: ./api
ports:
- "3000:3000"
environment:
- DB_HOST=db
- DB_PORT=5432
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=app
volumes:
- pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pg-data:
# Tout lancer
docker compose up -d --build
# Tester
curl http://localhost:3000/api/health
# Ouvrir http://localhost:8080 pour le frontend
# Tout arrêter
docker compose down
avancé
Un multi-stage build permet d'utiliser plusieurs images dans un seul Dockerfile. On construit dans une image complete, puis on copie seulement le resultat dans une image leger.
# Stage 1 : build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2 : production (image finale, leger)
FROM nginx:1.25-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Le premier stage installe tout et build. Le second stage prend juste le resultat (/app/dist) et le met dans Nginx. L'image finale ne contient pas Node.js, npm, ni les sources : elle est minuscule.
avancé
Un healthcheck permet a Docker de savoir si un conteneur est vraiment pret. Utile pour depends_on : sans healthcheck, l'API demarre avant que la DB soit prete.
FROM node:20-alpine
# ... app ...
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
services:
api:
build: .
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 10s
timeout: 3s
retries: 3
start_period: 10s
frontend:
build: ./frontend
depends_on:
api:
condition: service_healthy
Les options :
test : la commande a exécuter. Exit 0 = sain, autre = maladeinterval : intervalle entre deux checkstimeout : duree max du check avant de le considerer comme echecretries : nombre d'echecs consecutifs avant de marquer unhealthystart_period : temps de grace au démarrage (echecs ignores)intermédiaire
# Logs d'un conteneur
docker logs web
# Suivre les logs en temps reel
docker logs -f web
# Les 50 dernieres lignes
docker logs --tail 50 web
# Logs avec timestamp
docker logs -t web
# Logs depuis une date
docker logs --since 2026-01-01T00:00:00 web
# Entrer dans un conteneur en cours
docker exec -it web sh
# Infos detaillees sur un conteneur (IP, config, volumes, etc.)
docker inspect web
# Voir l'utilisation de ressources
docker stats
# Voir les processus dans un conteneur
docker top web
avancé
Par defaut, un conteneur tourne en root. C'est inutile et dangereux. Cree un utilisateur dedie :
FROM node:20-alpine
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY --chown=app:app . .
USER app
CMD ["node", "server.js"]
ENV API_KEY=xxx dans un Dockerfile est visible dans l'image finale avec docker inspect ou docker history. Les secrets se passent au runtime (--env-file, secrets Docker, ou gestionnaire de secrets).
# Docker Scout (integre a Docker Desktop)
docker scout cves mon-api:v1
# Voir l'historique des layers (detecte les secrets oublies)
docker history mon-api:v1
# Limiter la memoire et le CPU
docker run -d --name api --memory=512m --cpus=1 mon-api:v1
avancé
Chaque RUN cree un layer. Regrouper les commandes reduit le nombre de layers et la taille finale.
# Mal : 3 layers, 3 images intermediaires
RUN apt update
RUN apt install -y curl
RUN rm -rf /var/lib/apt/lists/*
# Bien : 1 layer, cleanup dans la même commande
RUN apt update && \
apt install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
node:20 fait ~1 Go. node:20-alpine fait ~50 Mo. Pour la prod, preferer Alpine ou Debian slim.
# Voir les layers et leur taille
docker history mon-api:v1
# Dive : outil externe pour analyser une image en detail
# https://github.com/wagoodman/dive
dive mon-api:v1
intermédiaire
services:
api:
build: .
ports:
- "3000:3000"
volumes:
- ./:/app # Monte le code source
- /app/node_modules # Evite que node_modules hote ecrase celui du conteneur
command: npx nodemon server.js
environment:
- NODE_ENV=development
Le code change sur ta machine, nodemon redetecte et relance. Le conteneur reste tourne.
/app/node_modules est une astuce classique : il cree un volume "fantome" qui protege le node_modules du conteneur contre l'ecrasement par le bind mount. Sans ca, le node_modules de l'hote (si il existe) remplacerait celui du conteneur.
avancé
# 1. Se connecter a Docker Hub
docker login
# 2. Tagger l'image avec ton nom d'utilisateur
docker tag mon-api:v1 tonuser/mon-api:v1
# 3. Pousser l'image
docker push tonuser/mon-api:v1
# 4. Quelqu'un d'autre peut la télécharger
docker pull tonuser/mon-api:v1
ghcr.io/tonuser/mon-api:v1docker run -d -p 5000:5000 registry:2avancé
Exemple de pipeline GitHub Actions qui build et push une image a chaque push sur main.
.github/workflows/docker.yml :
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build and push
run: |
docker build -t ghcr.io/${{ github.repository }}:latest .
docker push ghcr.io/${{ github.repository }}:latest
main, GitHub Actions construit l'image et la pousse sur GHCR. Tu peux ensuite la deployer n'importe ou avec docker pull.
intermédiaire
Docker accumule beaucoup de donnees : images, conteneurs arretes, volumes, cache de build. Il faut nettoyer regulierement.
# Voir l'espace utilise par Docker
docker system df
# Supprimer les conteneurs arretes
docker container prune
# Supprimer les images inutilisees
docker image prune
# Supprimer les volumes inutilises (attention aux donnees !)
docker volume prune
# Supprimer les réseaux inutilises
docker network prune
# Tout nettoyer d'un coup (conteneurs arretes, images, réseaux, cache)
docker system prune
# Version extrême : supprime aussi les volumes (donnees perdues !)
docker system prune -a --volumes
docker system prune -a --volumes supprime tout ce qui n'est pas utilise, y compris les volumes de bases de donnees. A n'utiliser qu'en dev, jamais sur un serveur en prod sans avoir backup les volumes importants.
intermédiaire
# Erreur : "port is already allocated"
# Solution : trouver ce qui occupe le port
# Linux/macOS :
lsof -i :8080
# Windows :
netstat -ano | findstr :8080
# Puis soit arrêter le processus, soit changer le port
docker run -p 8081:80 nginx
# Erreur : "permission denied while trying to connect to Docker daemon"
# Solution (Linux) : ajouter ton user au groupe docker
sudo usermod -aG docker $USER
newgrp docker
# Voir le code de sortie
docker ps -a
# Lire les logs du conteneur arrete
docker logs mon-conteneur
# Causes fréquentes :
# - CMD mal ecrit (pas de mode daemon)
# - App qui crash au démarrage (verifier les logs)
# - Variable d'environnement manquante
# Voir l'espace utilise
docker system df
# Nettoyer (prudent)
docker system prune
# Nettoyer le cache de build
docker builder prune
Sur macOS/Windows, Docker Desktop utilise un disque virtuel qui grossit. On peut le compresser via Docker Desktop > Settings > Resources > Disk image size > "Clean / Purge data".
avancé
node:20-alpine, pas node:latest).dockerignore pour exclure node_modules, .git, .envpackage.json avant le code pour profiter du cache de layersRUN avec && pour réduire les layersRUN (rm -rf /var/lib/apt/lists/*)USER app)--memory, --cpus)docker compose (v2) et non docker-compose (v1 obsolete)docker scout| Commande | Role |
|---|---|
docker run IMAGE | Lancer un conteneur |
docker ps | Conteneurs en cours |
docker ps -a | Tous les conteneurs (même arretes) |
docker stop NOM | arrêter un conteneur |
docker start NOM | démarrer un conteneur arrete |
docker restart NOM | redémarrer |
docker rm NOM | Supprimer un conteneur arrete |
docker rm -f NOM | Supprimer de force (en cours) |
docker logs NOM | Voir les logs |
docker logs -f NOM | Suivre les logs |
docker exec -it NOM sh | Entrer dans un conteneur |
docker inspect NOM | Infos detaillees |
docker stats | Consommation en temps reel |
| Commande | Role |
|---|---|
docker pull IMAGE | télécharger une image |
docker images | Lister les images locales |
docker build -t NOM . | Construire une image |
docker rmi IMAGE | Supprimer une image |
docker tag IMAGE NEW | Renommer / tagger |
docker push IMAGE | Publier sur un registre |
docker history IMAGE | Voir les layers |
| Commande | Role |
|---|---|
docker volume ls | Lister les volumes |
docker volume create NOM | créer un volume |
docker volume rm NOM | Supprimer un volume |
docker network ls | Lister les réseaux |
docker network create NOM | créer un réseau |
docker network rm NOM | Supprimer un réseau |
| Commande | Role |
|---|---|
docker compose up -d | Lancer en arrière-plan |
docker compose up --build | Reconstruire et lancer |
docker compose down | arrêter et supprimer |
docker compose down -v | Idem + supprimer les volumes |
docker compose logs -f | Suivre les logs |
docker compose exec SERVICE sh | Entrer dans un service |
docker compose ps | Services en cours |
| Commande | Role |
|---|---|
docker system df | Espace utilise |
docker system prune | Nettoyer le superflu |
docker system prune -a --volumes | Tout nettoyer (dangereux) |
docker image prune | Images inutilisees |
docker volume prune | Volumes inutilises |
docker builder prune | Cache de build |
Cree un dossier avec un index.html, un Dockerfile base sur Nginx, build et lance sur le port 8080.
Cree une API Node.js qui incremente un compteur dans Redis. Utilise Compose pour lancer les deux services avec un réseau et un volume.
Construis une stack avec frontend Nginx + API Node + PostgreSQL + Adminer. Ajoute des healthchecks, un multi-stage build pour l'API, un utilisateur non-root, et des limites de ressources.
Prends une de tes images existantes et reduis sa taille de 50% minimum en utilisant : base Alpine, multi-stage, regroupement de RUN, cleanup, .dockerignore. Verifie avec docker history.