Dockerfile

Section INF (All)

Dockerfile

Comprendre la structure d’un Dockerfile
Connaître les principales instructions
Savoir rédiger un Dockerfile simple
Découvrir les bonnes pratiques

Qu’est-ce qu’un Dockerfile ?

  • Un fichier texte qui décrit comment construire une image
  • Chaque ligne est une instruction
  • Chaque instruction crée une couche (layer)
  • Résultat : une image personnalisée, reproductible et portable

Instructions principales

  • FROM : image de base
  • RUN : exécuter une commande
  • COPY (préféré) ou ADD : ajouter des fichiers dans l’image

  • WORKDIR : définir le répertoire de travail
  • CMD : valeurs par défaut (commande ou arguments)
  • ENTRYPOINT : programme lancé au démarrage du conteneur

Exemple minimal

# Dockerfile
FROM ubuntu:24.04
RUN apt-get update  && apt-get install -y  curl \
&& rm -rf /var/lib/apt/lists/*
CMD ["bash"]

Cycle de vie d’un conteneur

Le conteneur est un processus.

Le conteneur s’arrête quand le premier processus (PID 1) s’arrête.

Ce PID 1 peut lancer des processus enfants (workers).

docker stop envoie SIGTERM, puis SIGKILL si l’arrêt dépasse ~10 s (délai configurable).

SIGTERM

En C#, qu’est-ce que Main ?

ENTRYPOINT

Point d’entrée du conteneur.

  • Programme lancé au démarrage du conteneur.
  • Les arguments passés à docker run remplacent CMD et complètent ENTRYPOINT.

Fixer le comportement par défaut du conteneur.

Exemple

ENTRYPOINT ["ping"]
docker run monimage "www.etml.ch"
# -> ping www.etml.ch

Forme exec vs forme shell

  • Exec (recommandé) : ENTRYPOINT ["ping", "-c", "4", "1.1.1.1"]
  • Shell : ENTRYPOINT ping -c 4 1.1.1.1 (passe par sh -c, à éviter ici)

CMD

Définit des valeurs par défaut (commande ou arguments).

Peut être remplacé en ligne de commande (docker run ... <args>).

CMD ["echo", "Hello World"] # Forme exec
CMD "echo Hello World" # Forme shell

⚠️ Priviléger la forme exec.

Ecrasement de CMD :

docker run --rm imgHello:1.0 echo "Bonjour !"
# -> affiche "Bonjour !"

Rappel du dockerfile de imgHello:1.0 :

CMD ["echo", "Hello World"] 

Si … docker run --rm imgHello:1.0

-> affiche “Hello World”

Si … docker run --rm imgHello:1.0 "Bonjour !"

Erreur, le conteneur va chercher à lancer sh -c “Bonjour !”

En pratique

Souvent combinés

ENTRYPOINT ["ping"]
CMD ["127.0.0.1", "-c", "4"]

Si je lance docker run monimage

Commande finale : ping 127.0.0.1 -c 4

Si je lance docker run monimage google.com

google.com remplace CMDping google.com

Si je lance docker run monimage bash

bash devient l’argument de ping. Echec.
Pour un shell : docker run --entrypoint bash monimage.

Bonnes pratiques Dockerfile

Utiliser des images officielles fiables.

Grouper les commandes RUN pour réduire les couches.

Nettoyer après installation (dans la même couche) :
rm -rf /var/lib/apt/lists/*

Préférer COPY.
ADD seulement pour l’extraction automatique d’une archive locale .tar.

Utiliser des images légères (alpine, debian-slim)
> Attention aux différences de libc selon les binaires.

Versionner (:1.0, :1.1), éviter :latest.

Ajouter un .dockerignore pour réduire le contexte.

.dockerignore

# Réduire le contexte de build
node_modules/
dist/
build/
coverage/
.git/
.gitignore
.DS_Store
*.log
.env

Objectif: des builds plus rapides, images plus petites, moins de secrets accidentels.

Utilisateur non-root

  • Créer un utilisateur dédié et éviter root quand c’est possible.
  • Copier les fichiers avec les bons propriétaires.

RUN adduser -D -u 10001 app
WORKDIR /app
COPY --chown=app:app . .
USER app

Santé du conteneur

HEALTHCHECK pour l’observabilité:

HEALTHCHECK --interval=30s --timeout=3s --retries=3   CMD \n
wget -qO- http://localhost:3000/health || exit 1

Réseaux & ports

  • EXPOSE 3000 : documentation du port, pas une publication.
  • Publication effective à l’exécution: -p 3000:3000.

Multi-stage builds

  • Construire l’image en plusieurs étapes.
  • Ne garder que l’essentiel dans l’image finale.

# Étape 1 : construction de l’app
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build    # produit /app/dist

# Étape 2 : image finale
FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/index.js"]

Conclusion

  • Le Dockerfile est une recette pour construire des images.
  • Chaque instruction = une couche.
  • ENTRYPOINT lance le programme, CMD fournit des valeurs par défaut.

  • Les bonnes pratiques réduisent la taille et améliorent la sécurité.
  • Les multi-stage builds permettent des images optimisées.