Concepts clés
Architecture Docker
Théorie

Docker repose sur une architecture client-serveur. Le daemon Docker tourne en arrière-plan et gère les objets Docker (images, conteneurs, volumes, réseaux). Le client Docker communique avec le daemon via une API REST.

ConceptDescription
ImageModèle en lecture seule (template) contenant le système de fichiers et la configuration pour créer un conteneur. Construite depuis un Dockerfile.
ConteneurInstance en cours d'exécution d'une image. Isolé du système hôte, possède son propre système de fichiers (couche en écriture au-dessus de l'image).
DockerfileFichier texte décrivant les instructions pour construire une image, étape par étape.
VolumeMécanisme de persistance des données géré par Docker. Survit à la suppression du conteneur.
RéseauCouche d'isolation réseau permettant aux conteneurs de communiquer entre eux et avec l'extérieur.
RegistryDépôt de stockage et de distribution d'images (ex: Docker Hub, GitHub Container Registry).
Docker ComposeOutil pour définir et gérer des applications multi-conteneurs via un fichier YAML.
Cycle de vie d'un conteneur

Un conteneur passe par plusieurs états : created (créé mais pas démarré), running (en cours d'exécution), paused, stopped (arrêté mais les données persistent), removed (supprimé).

ÉtatCommandeDescription
createddocker createConteneur créé, non démarré
runningdocker start / runProcessus en cours d'exécution
pauseddocker pauseProcessus suspendu (SIGSTOP)
stoppeddocker stopProcessus arrêté (SIGTERM puis SIGKILL)
removeddocker rmConteneur supprimé définitivement
Images
Gérer les images docker image
Essentiel

Les images sont des templates immuables stockés en couches (layers). Chaque instruction du Dockerfile crée une nouvelle couche, ce qui permet la mise en cache et le partage entre images.

BASH
docker images                          # Lister les images locales
docker image ls                        # Équivalent moderne
docker image ls -a                     # Inclure les images intermédiaires
docker pull nginx                      # Télécharger l'image officielle nginx (tag :latest)
docker pull nginx:1.25-alpine          # Version spécifique avec tag
docker image inspect nginx             # Détails complets d'une image (JSON)
docker image history nginx             # Afficher les couches d'une image
docker image rm nginx                  # Supprimer une image
docker rmi nginx nginx:1.25-alpine     # Supprimer plusieurs images
docker image prune                     # Supprimer les images orphelines (dangling)
docker image prune -a                  # Supprimer toutes les images non utilisées
Construire une image docker build
Essentiel

Construit une image à partir d'un Dockerfile. Le contexte de build (dernier argument) est le dossier envoyé au daemon Docker. Utilisez .dockerignore pour en exclure des fichiers.

BASH
docker build .                         # Build depuis le dossier courant
docker build -t mon-app:1.0 .          # Nommer et tagger l'image
docker build -t mon-app:latest -f Dockerfile.prod .  # Dockerfile personnalisé
docker build --no-cache -t mon-app .   # Forcer la reconstruction sans cache
docker build --build-arg ENV=prod .    # Passer un argument de build

# Exemple complet : build d'une app Node.js
docker build -t mon-app-node:1.0 --build-arg NODE_ENV=production .
Tagger et pousser une image

Un tag identifie une version d'une image. Le format complet est registre/utilisateur/image:tag. Sans registre, Docker Hub est utilisé par défaut.

BASH
docker tag mon-app:1.0 monuser/mon-app:1.0     # Tagger pour Docker Hub
docker tag mon-app:1.0 mon-app:latest           # Ajouter le tag latest
docker push monuser/mon-app:1.0                 # Pousser vers Docker Hub
docker push monuser/mon-app:latest

# Avec GitHub Container Registry
docker tag mon-app:1.0 ghcr.io/monuser/mon-app:1.0
docker push ghcr.io/monuser/mon-app:1.0
Conteneurs
Créer et démarrer un conteneur docker run
Essentiel

docker run combine docker create + docker start. C'est la commande principale pour lancer un conteneur. Si l'image n'est pas présente localement, Docker la télécharge automatiquement.

BASH
docker run nginx                        # Lancer nginx (foreground, bloque le terminal)
docker run -d nginx                     # Mode détaché (arrière-plan)
docker run -d --name mon-nginx nginx    # Nommer le conteneur
docker run -d -p 8080:80 nginx         # Mapper port hôte:conteneur
docker run -d -p 8080:80 -p 443:443 nginx  # Plusieurs ports
docker run -it ubuntu bash              # Mode interactif avec terminal
docker run --rm ubuntu echo "hello"    # Supprimer le conteneur après exécution
docker run -d -e APP_ENV=prod nginx    # Définir une variable d'environnement
docker run -d --env-file .env nginx    # Charger les variables depuis un fichier
docker run -d -v /host/data:/app/data nginx  # Monter un dossier hôte (bind mount)
docker run -d -v mon-volume:/app/data nginx  # Monter un volume nommé
docker run -d --network mon-reseau nginx     # Connecter à un réseau
docker run -d --restart unless-stopped nginx # Redémarrage automatique

# Exemple complet : app Node.js
docker run -d \
  --name api-prod \
  -p 3000:3000 \
  -e NODE_ENV=production \
  -e DB_URL=mongodb://mongo:27017/mydb \
  --network app-network \
  --restart unless-stopped \
  mon-app-node:1.0
Options de docker run
OptionDescription
-dMode détaché (arrière-plan)
-itMode interactif + pseudo-terminal (pour bash, sh)
--rmSupprime le conteneur automatiquement à l'arrêt
--nameDonne un nom au conteneur (sinon généré aléatoirement)
-p hôte:conteneurMappe un port de l'hôte vers le conteneur
-PMappe automatiquement tous les ports EXPOSE
-e VAR=valeurDéfinit une variable d'environnement
--env-file fichierCharge les variables depuis un fichier
-v src:dstMonte un volume ou un bind mount
--networkConnecte à un réseau Docker
--restartno | always | on-failure | unless-stopped
--memoryLimite la mémoire (ex: --memory 512m)
--cpusLimite les CPU (ex: --cpus 1.5)
Gérer les conteneurs en cours d'exécution
Essentiel
BASH
docker ps                           # Lister les conteneurs en cours d'exécution
docker ps -a                        # Tous les conteneurs (y compris arrêtés)
docker ps -q                        # Seulement les IDs
docker start mon-nginx              # Démarrer un conteneur arrêté
docker stop mon-nginx               # Arrêter proprement (SIGTERM, puis SIGKILL)
docker stop -t 5 mon-nginx          # Timeout avant SIGKILL (5 secondes)
docker kill mon-nginx               # Arrêt forcé immédiat (SIGKILL)
docker restart mon-nginx            # Redémarrer
docker pause mon-nginx              # Suspendre les processus
docker unpause mon-nginx            # Reprendre
docker rm mon-nginx                 # Supprimer un conteneur arrêté
docker rm -f mon-nginx              # Forcer la suppression (même si en cours)
docker rm $(docker ps -aq)          # Supprimer tous les conteneurs arrêtés
Interagir avec un conteneur

Accédez aux logs, exécutez des commandes à l'intérieur d'un conteneur, ou copiez des fichiers entre l'hôte et le conteneur.

BASH
# Logs
docker logs mon-nginx               # Afficher les logs
docker logs -f mon-nginx            # Suivre les logs en temps réel (follow)
docker logs --tail 50 mon-nginx     # 50 dernières lignes
docker logs --since 1h mon-nginx    # Logs de la dernière heure

# Exécuter une commande dans un conteneur actif
docker exec mon-nginx ls /etc/nginx
docker exec -it mon-nginx bash      # Ouvrir un shell interactif
docker exec -it mon-nginx sh        # Si bash n'est pas disponible (alpine)
docker exec -e VAR=val mon-nginx env # Avec une variable d'environnement

# Copier des fichiers
docker cp mon-nginx:/etc/nginx/nginx.conf ./nginx.conf  # Conteneur → hôte
docker cp ./mon-fichier.conf mon-nginx:/etc/nginx/      # Hôte → conteneur

# Inspecter
docker inspect mon-nginx            # Toutes les infos (JSON)
docker inspect --format '{{.NetworkSettings.IPAddress}}' mon-nginx  # IP du conteneur
docker stats                        # CPU, mémoire, réseau en temps réel
docker stats mon-nginx              # Stats d'un seul conteneur
docker top mon-nginx                # Processus en cours dans le conteneur
docker port mon-nginx               # Mappings de ports
Dockerfile
Instructions Dockerfile
Essentiel

Un Dockerfile est un script décrivant les étapes de construction d'une image. Chaque instruction crée une nouvelle couche dans l'image.

InstructionDescription
FROMImage de base (obligatoire, en premier). Ex: FROM node:20-alpine
WORKDIRDéfinit le répertoire de travail pour les instructions suivantes
COPYCopie des fichiers du contexte de build vers l'image
ADDComme COPY mais supporte les URLs et l'extraction d'archives tar (préférer COPY)
RUNExécute une commande pendant la construction (crée une couche)
ENVDéfinit une variable d'environnement persistante dans l'image
ARGVariable disponible uniquement pendant le build (pas dans le conteneur final)
EXPOSEDocumente le port écouté (ne publie pas réellement le port)
CMDCommande par défaut au démarrage du conteneur (peut être remplacée)
ENTRYPOINTPoint d'entrée du conteneur (difficile à remplacer, CMD devient des arguments)
VOLUMEDéclare un point de montage pour un volume
USERDéfinit l'utilisateur pour les instructions suivantes et le conteneur
LABELAjoute des métadonnées à l'image (auteur, version, description)
HEALTHCHECKDéfinit une commande pour vérifier la santé du conteneur
Dockerfile — Application Node.js
Exemple

Exemple complet pour une application Node.js avec les bonnes pratiques : utilisateur non-root, couches optimisées, image légère.

DOCKERFILE
# Image de base légère
FROM node:20-alpine

# Métadonnées
LABEL maintainer="dev@exemple.fr"
LABEL version="1.0"

# Définir le répertoire de travail
WORKDIR /app

# Copier d'abord les fichiers de dépendances (optimise le cache)
COPY package*.json ./

# Installer les dépendances
RUN npm ci --only=production

# Copier le reste du code source
COPY . .

# Variable d'environnement
ENV NODE_ENV=production
ENV PORT=3000

# Créer un utilisateur non-root pour la sécurité
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# Documenter le port
EXPOSE 3000

# Vérification de santé
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
  CMD wget -qO- http://localhost:3000/health || exit 1

# Commande de démarrage
CMD ["node", "src/index.js"]
Dockerfile — Multi-stage build
Exemple

Les builds multi-étapes permettent de construire dans un environnement complet et de ne copier que le résultat final dans une image légère. Idéal pour les langages compilés (Go, Java) ou les frameworks frontend.

DOCKERFILE
# ===== ÉTAPE 1 : Build =====
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build          # Génère le dossier dist/

# ===== ÉTAPE 2 : Production =====
FROM nginx:1.25-alpine AS production

# Copier uniquement le résultat du build
COPY --from=builder /app/dist /usr/share/nginx/html

# Copier la configuration nginx personnalisée
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Fichier .dockerignore

Similaire à .gitignore, ce fichier exclut des fichiers et dossiers du contexte de build pour réduire la taille et éviter d'envoyer des données sensibles au daemon Docker.

TEXT
node_modules/
npm-debug.log
.git/
.gitignore
.env
.env.local
*.md
dist/
coverage/
.DS_Store
*.log
CMD vs ENTRYPOINT

Ces deux instructions définissent le comportement au démarrage du conteneur, mais de manière différente.

InstructionComportementRemplacement
CMD ["node","app.js"]Commande par défautdocker run image python app.py remplace complètement CMD
ENTRYPOINT ["node"]Exécutable fixedocker run image app.js — app.js est ajouté comme argument à node
ENTRYPOINT + CMDPoint d'entrée fixe avec arguments par défautCMD devient les arguments par défaut, remplaçables via docker run
DOCKERFILE
# Bonne pratique : ENTRYPOINT fixe l'exécutable, CMD les arguments par défaut
ENTRYPOINT ["node"]
CMD ["src/index.js"]

# docker run mon-app             → node src/index.js
# docker run mon-app src/cli.js  → node src/cli.js
Volumes
Types de montages
Théorie

Docker propose trois façons de persister et partager des données entre l'hôte et les conteneurs.

TypeSyntaxeDescription
Volume nommé-v mon-vol:/app/dataGéré par Docker, stocké dans /var/lib/docker/volumes/. Recommandé pour la production.
Bind mount-v /host/path:/app/dataLie un dossier de l'hôte. Utile en développement pour voir les modifications en temps réel.
tmpfs--tmpfs /app/tmpStockage en mémoire RAM uniquement. Non persistant, pour les données sensibles temporaires.
Commandes de gestion des volumes
Essentiel
BASH
docker volume ls                       # Lister les volumes
docker volume create mon-volume        # Créer un volume nommé
docker volume inspect mon-volume       # Détails d'un volume (emplacement, etc.)
docker volume rm mon-volume            # Supprimer un volume
docker volume prune                    # Supprimer les volumes non utilisés

# Utiliser un volume avec un conteneur
docker run -d \
  -v mon-volume:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  --name postgres-db \
  postgres:16-alpine

# Bind mount en développement (code source synchronisé)
docker run -d \
  -v $(pwd):/app \
  -v /app/node_modules \
  -p 3000:3000 \
  mon-app-node:dev

# Volume en lecture seule
docker run -d -v mon-volume:/app/data:ro nginx
Réseaux
Types de réseaux Docker
Théorie
DriverDescriptionUsage
bridgeRéseau privé isolé sur l'hôte. Les conteneurs se voient par nom (DNS interne).Défaut pour les conteneurs standalone
hostPartage le réseau de l'hôte directement. Aucune isolation réseau.Performance maximale (Linux uniquement)
noneAucune interface réseau. Conteneur complètement isolé.Sécurité maximale, batch jobs
overlayCommunication entre conteneurs sur plusieurs hôtes (Docker Swarm).Orchestration multi-hôtes
Commandes réseau
Essentiel

Dans un réseau bridge personnalisé, les conteneurs peuvent se joindre par leur nom (DNS automatique). Ce n'est pas le cas dans le réseau bridge par défaut.

BASH
docker network ls                              # Lister les réseaux
docker network create app-network              # Créer un réseau bridge
docker network create --driver bridge --subnet 172.20.0.0/16 app-network
docker network inspect app-network             # Détails du réseau
docker network rm app-network                  # Supprimer un réseau
docker network prune                           # Supprimer les réseaux inutilisés

# Connecter des conteneurs à un réseau
docker run -d --name api --network app-network mon-api
docker run -d --name db  --network app-network postgres:16-alpine

# L'API peut maintenant joindre la DB via le nom "db" :
# postgresql://db:5432/mydb

# Connecter/déconnecter un conteneur existant
docker network connect    app-network mon-nginx
docker network disconnect app-network mon-nginx

# Utiliser le réseau hôte (Linux)
docker run -d --network host nginx
Docker Compose
Structure d'un docker-compose.yml
Essentiel

Docker Compose permet de définir et gérer des applications multi-conteneurs dans un fichier YAML. Tous les services partagent automatiquement un réseau et peuvent se joindre par leur nom de service.

YAML
services:

  # Service API Node.js
  api:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        NODE_ENV: production
    image: mon-api:latest
    container_name: mon-api
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_URL=mongodb://mongo:27017/mydb
      - REDIS_URL=redis://redis:6379
    env_file:
      - .env
    depends_on:
      mongo:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./logs:/app/logs
    networks:
      - app-network
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  # Base de données MongoDB
  mongo:
    image: mongo:7-jammy
    container_name: mon-mongo
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: secret
    volumes:
      - mongo-data:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/init.js:ro
    networks:
      - app-network
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Cache Redis
  redis:
    image: redis:7-alpine
    container_name: mon-redis
    restart: unless-stopped
    volumes:
      - redis-data:/data
    networks:
      - app-network

volumes:
  mongo-data:
  redis-data:

networks:
  app-network:
    driver: bridge
Commandes Docker Compose
Essentiel
BASH
docker compose up                      # Démarrer tous les services (foreground)
docker compose up -d                   # Mode détaché (arrière-plan)
docker compose up --build              # Rebuild les images avant de démarrer
docker compose up -d --build           # Rebuild + démarrage en arrière-plan
docker compose up api                  # Démarrer uniquement le service "api"

docker compose down                    # Arrêter et supprimer les conteneurs + réseaux
docker compose down -v                 # + supprimer les volumes
docker compose down --rmi all          # + supprimer les images buildées

docker compose stop                    # Arrêter les conteneurs (sans les supprimer)
docker compose start                   # Redémarrer les conteneurs stoppés
docker compose restart                 # Redémarrer tous les services
docker compose restart api             # Redémarrer un service spécifique

docker compose ps                      # État des services
docker compose logs                    # Logs de tous les services
docker compose logs -f api             # Suivre les logs du service "api"
docker compose logs --tail 50 api

docker compose exec api bash           # Shell dans le service "api"
docker compose exec api node --version # Exécuter une commande

docker compose build                   # Construire les images sans démarrer
docker compose pull                    # Télécharger les dernières images
docker compose config                  # Valider et afficher la config résolue
docker compose top                     # Processus dans chaque service

# Scaler un service (plusieurs instances)
docker compose up -d --scale api=3
Surcharge avec plusieurs fichiers Compose

Il est courant d'avoir un fichier de base et des fichiers de surcharge selon l'environnement. Le fichier docker-compose.override.yml est automatiquement mergé avec docker-compose.yml.

BASH
# Utiliser plusieurs fichiers (mergés dans l'ordre)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# Fichiers courants
# docker-compose.yml          → config de base
# docker-compose.override.yml → dev (chargé auto)
# docker-compose.prod.yml     → production
YAML
# docker-compose.override.yml (développement)
services:
  api:
    build:
      target: development
    volumes:
      - .:/app                 # Code source synchronisé
      - /app/node_modules
    environment:
      - NODE_ENV=development
    command: npm run dev        # Remplace CMD du Dockerfile
Registry & Hub
Docker Hub et registries
Essentiel

Docker Hub est le registry public par défaut. Vous pouvez aussi utiliser des registries privés (GitHub Container Registry, GitLab Registry, AWS ECR, etc.).

BASH
# Authentification
docker login                           # Docker Hub (interactif)
docker login -u monuser                # Spécifier le nom d'utilisateur
docker login ghcr.io                   # GitHub Container Registry
docker logout                          # Se déconnecter

# Chercher des images sur Docker Hub
docker search nginx
docker search --filter is-official=true nginx

# Nommer et pousser une image
docker tag mon-app:1.0 monuser/mon-app:1.0
docker push monuser/mon-app:1.0
docker push monuser/mon-app:latest

# Télécharger une image spécifique
docker pull monuser/mon-app:1.0

# Sauvegarder/charger une image en fichier tar (sans registry)
docker save -o mon-app.tar mon-app:1.0
docker load -i mon-app.tar

# Exporter/importer un conteneur (système de fichiers uniquement)
docker export mon-conteneur -o snapshot.tar
docker import snapshot.tar mon-app:snapshot
Nettoyage
Libérer de l'espace disque
Essentiel

Docker peut accumuler beaucoup de données inutilisées (images, conteneurs arrêtés, volumes orphelins, cache de build). Ces commandes permettent de récupérer de l'espace disque.

BASH
# Nettoyage ciblé
docker container prune           # Supprimer tous les conteneurs arrêtés
docker image prune               # Supprimer les images dangling (sans tag)
docker image prune -a            # Supprimer toutes les images non utilisées
docker volume prune              # Supprimer les volumes non attachés
docker network prune             # Supprimer les réseaux inutilisés
docker builder prune             # Supprimer le cache de build

# Nettoyage global (tout en une commande)
docker system prune              # Conteneurs + réseaux + images dangling
docker system prune -a           # + toutes les images non utilisées
docker system prune -a --volumes # + volumes (ATTENTION : perte de données)

# Inspecter l'espace utilisé
docker system df                 # Résumé de l'espace disque Docker
docker system df -v              # Détails par objet
Bonnes pratiques
Optimiser les images Docker

Une image optimisée est plus rapide à construire, à télécharger et plus sécurisée. Voici les principales règles à suivre.

PratiqueDescription
Images de base légèresPréférer alpine ou slim (ex: node:20-alpine) plutôt que les images complètes
Minimiser les couchesChaîner les commandes RUN avec && pour n'en créer qu'une seule couche
Ordonner les instructionsPlacer les instructions qui changent rarement en premier (ex: dépendances avant le code source) pour bénéficier du cache
Multi-stage buildSéparer build et runtime pour exclure les outils de compilation de l'image finale
Utilisateur non-rootToujours créer et utiliser un utilisateur dédié avec USER pour la sécurité
.dockerignoreExclure node_modules, .git, .env, logs du contexte de build
Tags explicitesÉviter :latest en production, utiliser des tags de version précis
SecretsNe jamais inclure de secrets dans l'image, utiliser les variables d'environnement ou Docker secrets
Workflow de développement complet
Exemple
BASH
# === DÉVELOPPEMENT ===

# 1. Démarrer l'environnement de dev (avec hot-reload)
docker compose up -d

# 2. Voir les logs en temps réel
docker compose logs -f api

# 3. Ouvrir un shell dans le conteneur
docker compose exec api bash

# 4. Relancer uniquement un service après modification
docker compose restart api

# === MISE EN PRODUCTION ===

# 1. Build de l'image avec tag de version
docker build -t monuser/mon-app:2.1.0 -t monuser/mon-app:latest .

# 2. Tester l'image localement
docker run --rm -p 3000:3000 monuser/mon-app:2.1.0

# 3. Pousser vers le registry
docker push monuser/mon-app:2.1.0
docker push monuser/mon-app:latest

# 4. Déployer sur le serveur
docker compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 5. Vérifier le déploiement
docker compose ps
docker compose logs --tail 20 api

# 6. Nettoyer les anciennes images
docker image prune -f
Résumé des commandes essentielles
CommandeDescription
docker build -t app:1.0 .Construire une image depuis le dossier courant
docker run -d -p 80:80 app:1.0Lancer un conteneur en arrière-plan
docker psLister les conteneurs en cours d'exécution
docker logs -f nomSuivre les logs en temps réel
docker exec -it nom bashOuvrir un shell dans le conteneur
docker stop nomArrêter proprement un conteneur
docker rm nomSupprimer un conteneur
docker compose up -d --buildRebuild et démarrer tous les services
docker compose down -vArrêter et supprimer conteneurs + volumes
docker system prune -aNettoyage complet de Docker

Aucun résultat pour votre recherche.