Conteneurs & Déploiement

Docker & Déploiement

Docker encapsule votre application et son environnement dans une image qui s'exécute de la même manière partout. Les builds multi-étapes, la mise en cache et la CI/CD transforment le déploiement en une étape reproductible.

intermediate14 min readUpdated 15 sept. 2026
Dockerfile
dockerfile
// Dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Image
Un template en lecture seule
Conteneur
Une image en cours d'exécution
Fichier de build
Dockerfile
Couches
Mises en cache et réutilisées
Compose
Applications multi-services
Registry
Lieu de stockage des images

Pourquoi c'est important

Pourquoi les conteneurs ont gagné la bataille du déploiement

Cohérence partout

L'image inclut l'OS, le runtime et les dépendances, elle s'exécute donc de la même manière sur votre ordinateur, en CI et en production.

Isolé par défaut

Les conteneurs partagent le noyau de l'hôte mais isolent les processus, les systèmes de fichiers et les réseaux, ce qui limite le rayon d'impact en cas de problème.

Portable et scalable

La même image s'exécute sur n'importe quel hôte de conteneurs, ce qui rend le scaling et la migration entre clouds très simples.

Le tableau complet

Les trois concepts fondamentaux de Docker

L'image est le build, le conteneur est l'exécution, et le registry est le moyen de transporter les images entre les machines.

L'image

Build

Un template en lecture seule, composé de couches, construit à partir d'un Dockerfile.

Le conteneur

Run

Une instance exécutable d'une image avec son propre processus et système de fichiers.

Le registry

Distribuer

Un dépôt d'images que la CI et la production utilisent pour récupérer les builds.

Docker en un coup d'œil

Le cœur de Docker

Dockerfile

Instructions qui construisent une image couche par couche.

Couches et cache

Chaque instruction est une couche mise en cache, ainsi les étapes inchangées sont réutilisées.

Builds multi-étapes

Construisez dans une étape et n'expédiez que le résultat final dans une image réduite.

Compose

Définissez et lancez des applications multi-conteneurs, comme une app couplée à une base de données.

Registry

Poussez et récupérez des images depuis Docker Hub, GHCR ou un registry privé.

CI/CD

Construisez, testez et déployez automatiquement à chaque modification.

Un bref aperçu

Des VM aux conteneurs, puis à la CI/CD

  1. 2013

    Sortie de Docker

    Les conteneurs deviennent accessibles aux développeurs.

    13
  2. 2015

    Compose et orchestration

    Compose et Kubernetes rendent les déploiements multi-services pratiques.

    15
  3. 2017

    Builds multi-étapes

    Les images de production allégées deviennent la norme.

    17
  4. 2020

    Les conteneurs partout

    La CI/CD basée sur les conteneurs et les plateformes serverless de conteneurs se généralisent.

    20
  5. Aujourd'hui

    Le standard de déploiement

    La plupart des systèmes de production sont livrés sous forme d'images de conteneurs.

    Aujourd'hui

Le guide complet

Docker & Déploiement: Tout ce que vous devez savoir

Pourquoi les conteneurs ont gagné

Avant les conteneurs, déployer signifiait reproduire un environnement : la bonne version du runtime, les bonnes bibliothèques système, la bonne configuration. Le fameux « ça marche sur ma machine » était un problème réel, et les serveurs divergeaient progressivement des environnements de développement.

Docker a résolu ce problème en encapsulant l’application et son environnement dans une image unique. L’image s’exécute de manière identique sur un ordinateur portable, en CI et en production, car elle contient tout ce dont elle a besoin. Cette cohérence est la raison pour laquelle les conteneurs sont devenus la norme pour le déploiement, et pourquoi apprendre Docker est l’une des compétences les plus précieuses pour livrer des logiciels.

Images et conteneurs

Une image est un modèle en lecture seule construit à partir d’un Dockerfile, composé de couches mises en cache. Un conteneur est une instance exécutable d’une image, possédant sa propre couche accessible en écriture, son propre processus et son propre réseau. On construit une fois pour exécuter plusieurs fois.

docker build -t my-app:1.0 .
docker run -p 3000:3000 my-app:1.0
docker ps
docker logs <container>

Le flag -p mappe un port de l’hôte vers un port du conteneur. Les conteneurs sont éphémères par conception : vous pouvez les arrêter, les supprimer et les recréer librement car l’image constitue la source de vérité.

Le Dockerfile

Le Dockerfile est la recette de build. Chaque instruction crée une couche (layer).

# Dockerfile
FROM node:22-alpine
WORKDIR /app

# install dependencies first for better caching
COPY package*.json ./
RUN npm ci --omit=dev

# then copy source
COPY . .

ENV NODE_ENV=production
EXPOSE 3000
USER node
CMD ["node", "server.js"]

L’ordre est primordial. Copier les manifestes de dépendances et les installer avant de copier le code source permet de s’assurer qu’une modification du code n’invalide que la couche source (peu coûteuse) et non l’étape d’installation (coûteuse). npm ci garantit une installation reproductible, et USER node permet l’exécution avec un utilisateur non-root.

Mise en cache des couches

Docker met en cache chaque couche et la réutilise lorsque les entrées restent inchangées. C’est pourquoi l’ordre ci-dessus est délibéré : placez les éléments qui changent rarement en haut et ceux qui changent souvent en bas.

# cached unless package files change
COPY package*.json ./
RUN npm ci

# invalidated on every source change
COPY . .

Un fichier .dockerignore est également important. Sans lui, node_modules, .git et les fichiers de build sont copiés dans le contexte de build, ce qui ralentit la compilation et peut entraîner la fuite de fichiers dans l’image.

node_modules
.git
dist
.env

Builds multi-étapes (Multi-stage builds)

Un build multi-étape permet de compiler dans une image et de n’expédier que le résultat final dans une autre.

# Dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

L’image finale ne contient que les fichiers statiques compilés et un serveur web, et non le runtime Node, le code source ou les outils de build. Le résultat est plus léger, plus rapide à télécharger et présente une surface d’attaque beaucoup plus réduite. Pour une application serveur, l’étape finale serait une image Node légère contenant uniquement les dépendances de production.

Compose pour les applications multi-services

Les applications réelles nécessitent généralement plus d’un processus. Compose permet de les définir ensemble.

# docker-compose.yml
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://db:5432/app
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data:

depends_on contrôle l’ordre de démarrage, volumes permet de persister les données lors du redémarrage des conteneurs, et les services communiquent entre eux via leur nom sur le réseau partagé. Compose est idéal pour le développement local et les déploiements simples sur un seul hôte.

Registres et CI/CD

Les images transitent par un registre tel que Docker Hub, GitHub Container Registry ou un registre privé. Un pipeline typique se compose ainsi :

  1. Installation des dépendances et exécution des tests.
  2. Build de l’image et marquage (tag) avec le SHA du commit.
  3. Push de l’image vers le registre.
  4. Déploiement du nouveau tag vers l’environnement cible.
docker build -t ghcr.io/me/app:$GIT_SHA .
docker push ghcr.io/me/app:$GIT_SHA

Comme l’image est immuable et taguée par commit, les rollbacks consistent simplement à déployer un tag précédent. C’est le cœur d’un processus de déploiement fiable : build unique, promotion du même artefact à travers les environnements, et aucun rebuild pour la production.

Pratiques de production

  • Health checks. Exposez un endpoint que la plateforme peut interroger pour savoir si le container est prêt.
  • Utilisateur non-root. Exécutez l’application avec un utilisateur disposant des privilèges minimums nécessaires.
  • Système de fichiers en lecture seule dans la mesure du possible, avec des volumes d’écriture explicites.
  • Graceful shutdown. Gérez SIGTERM pour terminer le traitement des requêtes en cours.
  • Limites de ressources. Définissez le CPU et la mémoire pour éviter qu’un container ne monopolise les ressources des autres.
  • Épinglez les versions des images de base pour garantir des builds reproductibles.
  • Secrets au runtime, ne les intégrez jamais directement dans l’image.
  • Images de base légères comme Alpine ou distroless pour réduire les vulnérabilités.

Bonnes pratiques

  • Ordonnez les instructions du Dockerfile de la moins fréquente à la plus fréquente en termes de modification.
  • Utilisez des builds multi-étapes (multi-stage builds) et n’expédiez que le strict nécessaire.
  • Ajoutez un .dockerignore pour node_modules, .git, dist et .env.
  • Exécutez le processus en tant qu’utilisateur non-root.
  • Marquez (taggez) les images par le SHA du commit, et pas seulement par latest.
  • Construisez l’image une seule fois et faites-la progresser à travers les différents environnements.
  • Gérez SIGTERM pour permettre un arrêt progressif (graceful shutdown).

Erreurs courantes

  • Copier node_modules dans l’image.
  • Exécuter en tant que root.
  • Intégrer des secrets dans l’image ou commiter .env.
  • Utiliser latest comme seul tag et perdre la reproductibilité.
  • Reconstruire l’image différemment pour chaque environnement.
  • Ignorer .dockerignore et créer des builds énormes et lents.

Et après ?

Les containers rendent le déploiement prévisible, et les compétences acquises s’appliquent aussi bien pour un déploiement sur une VM, Kubernetes ou une plateforme de containers serverless. Consolidez vos bases sur le runtime avec le guide Node.js, gérez vos dépendances avec npm, exposez votre application via HTTP et sécurisez-la grâce à la Web Security. Ensuite, containerisez une petite application et déployez-la de bout en bout.

Construction de l'image

Un build multi-étapes exclut les outils de build de l'image finale, ce qui la rend plus légère et réduit la surface d'attaque.

Préférer
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
Éviter
FROM node:22
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/server.js"]
# ships dev deps, source
# and build tools

Exécution en tant qu'utilisateur

Exécutez le conteneur avec un utilisateur non-root pour qu'une compromission ne puisse pas facilement s'étendre à l'hôte.

Préférer
FROM node:22-alpine
WORKDIR /app
COPY --chown=node:node . .
USER node
CMD ["node", "server.js"]
Éviter
FROM node:22-alpine
WORKDIR /app
COPY . .
# runs as root by default
CMD ["node", "server.js"]

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre Docker & Deployment ?

Notre tutoriel interactif vous guide à travers Docker & Deployment pas à pas — avec des quiz et du vrai code que vous pouvez exécuter dans le navigateur.