// Outils du dev

Docker pour débutants : le guide complet

« Ça marche sur ma machine. » Cette phrase, Docker l’a rendue obsolète. En empaquetant une application avec tout ce dont elle a besoin pour tourner, Docker garantit qu’elle se comporte de la même façon sur votre poste, sur celui d’un collègue et en production. Ce guide part de zéro : les concepts, les premières commandes, l’écriture d’un Dockerfile, la persistance des données avec les volumes, et l’orchestration de plusieurs services avec Docker Compose.

Pourquoi Docker ? Le problème qu’il résout

Installer un projet, c’est souvent installer la bonne version d’un langage, une base de données, des dépendances système, et prier pour que tout s’accorde. Docker enferme tout cela dans un conteneur : une unité isolée, légère et reproductible.

Contrairement à une machine virtuelle, un conteneur ne virtualise pas un système d’exploitation complet. Il partage le noyau de l’hôte et n’embarque que ce qui est nécessaire à l’application. Résultat : des démarrages en quelques secondes et une empreinte réduite.

Images vs conteneurs : la distinction clé

C’est le concept à bien intégrer avant tout le reste :

  • Une image est un modèle en lecture seule : le plan de construction de votre application (le système de base, les dépendances, votre code). Comparez-la à une classe en programmation.
  • Un conteneur est une instance en cours d’exécution d’une image. Comme un objet créé à partir d’une classe, on peut en lancer plusieurs à partir de la même image.

On récupère ou on construit une image, puis on lance des conteneurs à partir d’elle.

Vos premières commandes

Après avoir installé Docker Desktop (ou le moteur Docker sous Linux — voyez notre guide pour débuter sous Linux), vérifiez que tout fonctionne :

# Vérifier la version installée
docker --version

# Lancer un conteneur de test
docker run hello-world

Quelques commandes fondamentales pour manipuler images et conteneurs :

# Télécharger une image depuis le registre Docker Hub
docker pull nginx

# Lancer un conteneur à partir d'une image
docker run nginx

# Lancer en arrière-plan (-d) et rediriger un port (-p hôte:conteneur)
docker run -d -p 8080:80 nginx

# Lister les conteneurs en cours d'exécution
docker ps

# Lister TOUS les conteneurs, y compris arrêtés
docker ps -a

# Arrêter puis supprimer un conteneur
docker stop <id_ou_nom>
docker rm <id_ou_nom>

# Lister les images locales
docker images

Avec docker run -d -p 8080:80 nginx, ouvrez http://localhost:8080 dans votre navigateur : un serveur web tourne dans un conteneur, sans rien avoir installé sur votre système.

Écrire un Dockerfile

Pour empaqueter votre propre application, on décrit sa construction dans un fichier nommé Dockerfile. Voici un exemple pour une petite application Node.js :

# Partir d'une image de base officielle
FROM node:20-alpine

# Définir le dossier de travail dans le conteneur
WORKDIR /app

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

# Installer les dépendances
RUN npm install

# Copier le reste du code
COPY . .

# Documenter le port utilisé par l'application
EXPOSE 3000

# Commande lancée au démarrage du conteneur
CMD ["node", "server.js"]

Chaque instruction crée une couche (layer). Copier package.json avant le reste du code est une optimisation classique : tant que vos dépendances ne changent pas, Docker réutilise la couche npm install en cache et reconstruit plus vite.

Construire et lancer son image

# Construire l'image et lui donner un nom (tag) avec -t
docker build -t mon-app .

# Lancer un conteneur à partir de son image
docker run -d -p 3000:3000 mon-app

# Consulter les logs d'un conteneur
docker logs <id_ou_nom>

# Ouvrir un terminal dans un conteneur en cours d'exécution
docker exec -it <id_ou_nom> sh

Le . final de docker build désigne le contexte de build : le dossier courant, envoyé à Docker. Pensez à y ajouter un fichier .dockerignore (sur le modèle de .gitignore) pour exclure node_modules, les fichiers temporaires et les secrets.

Les volumes : conserver ses données

Par défaut, tout ce qu’un conteneur écrit disparaît quand on le supprime. Pour une base de données ou des fichiers uploadés, c’est inacceptable. Les volumes rendent les données persistantes en les stockant hors du conteneur.

# Créer un volume nommé
docker volume create mes-donnees

# Monter un volume dans un conteneur
docker run -d -v mes-donnees:/var/lib/mysql mysql

# Monter un dossier local (bind mount) : pratique en développement
docker run -d -v $(pwd):/app mon-app

Le bind mount ($(pwd):/app) relie un dossier de votre machine au conteneur : vos modifications de code sont visibles immédiatement, sans reconstruire l’image. Idéal pendant le développement.

Docker Compose : orchestrer plusieurs services

Une vraie application combine souvent plusieurs conteneurs : un serveur web, une base de données, un cache… Les lancer un par un avec de longues commandes devient vite pénible. Docker Compose décrit toute la pile dans un seul fichier docker-compose.yml :

services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: motdepasse
    volumes:
      - donnees-db:/var/lib/postgresql/data

volumes:
  donnees-db:

On pilote ensuite l’ensemble avec quelques commandes :

# Construire et lancer toute la pile en arrière-plan
docker compose up -d

# Voir les logs de tous les services
docker compose logs -f

# Arrêter et supprimer les conteneurs (les volumes sont conservés)
docker compose down

En une commande, votre application et sa base de données démarrent ensemble, connectées sur un réseau interne. C’est là que Docker révèle toute sa valeur au quotidien.

Garder un environnement propre

Les images et conteneurs inutilisés s’accumulent et consomment de l’espace disque. Un nettoyage régulier fait du bien :

# Supprimer les conteneurs arrêtés, réseaux et images inutilisés
docker system prune

# Ajouter les volumes non utilisés (attention : destructif)
docker system prune --volumes

Et maintenant ?

Vous disposez du socle : différencier image et conteneur, écrire un Dockerfile, gérer la persistance et orchestrer avec Compose. La suite naturelle consiste à intégrer Docker à votre déploiement — construire une image dans un pipeline CI puis la pousser vers un hébergeur. Pour choisir où faire tourner tout cela, notre comparatif du meilleur hébergeur web pour développeurs fait le tour des options.

À lire ensuite