DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesSécuriser ses pipelines et applications (DevSecOps)03 - Sécuriser un Dockerfile contre les vulnérabilités

Détails

  • 20 minutes
  • Intermédiaire

Objectifs

  • Appliquer le principe du moindre privilège avec USER
  • Réduire la surface d'attaque avec le multi-stage build
  • Éviter les fuites de secrets dans les layers Docker
Module Sécuriser ses pipelines et applications (DevSecOps)

Exercice 03 : Sécuriser un Dockerfile contre les vulnérabilités

🎯 Objectifs

À la fin de cet exercice, vous serez capable de :

  • ✅ Éviter d'exécuter des conteneurs en root avec USER 1001
  • ✅ Éviter les secrets dans ARG/ENV au build
  • ✅ Utiliser le multi-stage build pour réduire la surface d'attaque
  • ✅ Utiliser COPY spécifique au lieu de COPY . .
  • ✅ Choisir une image de base minimale (alpine/distroless)

Durée estimée : 20 minutes

Difficulté : ⭐⭐⭐☆☆ (Intermédiaire)

Prérequis : Exercices 01 et 02 complétés, notions de Docker


📖 Contexte

Un Dockerfile mal écrit peut créer des vulnérabilités graves : exécution en root (compromet l'hôte si breakout), secrets exposés dans les layers (récupérables avec docker history), image volumineuse (plus de packages = plus de CVE). La sécurité d'un conteneur commence à la ligne 1 du Dockerfile.


📋 Énoncé

Analysez un Dockerfile volontairement mal écrit, identifiez les problèmes de sécurité, et réécrivez-le en appliquant les bonnes pratiques.


🧭 Déroulement de l'exercice

Tâche 1 : Analyser un Dockerfile vulnérable

Créez ce Dockerfile problématique et identifiez les 5 problèmes de sécurité :

dockerfile
FROM python:3.10
ARG API_KEY=sk-default-key
ENV SECRET_TOKEN=hardcoded_token_123
COPY . .
RUN pip install -r requirements.txt
RUN apt-get install -y curl wget vim
EXPOSE 8080
CMD ["python", "app.py"]

Indice : Les 5 problèmes sont : (1) image de base trop lourde, (2) ARG/ENV exposent des secrets dans les layers, (3) COPY . . copie potentiellement des fichiers sensibles (.env, .git), (4) installation de packages inutiles, (5) pas de USER - tourne en root.

Vérification : Vous listez les 5 problèmes et comprenez le risque de chacun. docker history mon-image montre les ARG/ENV dans les layers.


Tâche 2 : Ajouter USER pour éviter root

Corrigez d'abord le problème le plus critique : l'exécution en root.

Indice :

`dockerfile

FROM python:3.10-slim

>

# Créer un utilisateur non-privilégié

RUN groupadd -r appgroup && useradd -r -g appgroup appuser

>

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

>

COPY src/ ./src/

>

# Changer le propriétaire et switcher l'utilisateur

RUN chown -R appuser:appgroup /app

USER appuser

>

CMD ["python", "src/app.py"]

`

Vérification : docker run mon-image whoami retourne appuser, pas root.


Tâche 3 : Éviter les secrets dans les layers

Remplacez les ARG/ENV contenant des secrets par des variables passées au runtime :

Indice :

`dockerfile

# MAUVAIS : visible dans docker history et docker inspect

ARG API_KEY

ENV SECRET_TOKEN=$API_KEY

>

# BON : ne pas mettre de secrets dans le Dockerfile

# Les passer au docker run avec -e ou --env-file

`

>

Dans l'application :

`python

import os

api_key = os.environ.get("API_KEY") # Injecté au runtime

`

Vérification : docker history mon-image ne montre aucune valeur de secret. docker inspect mon-image ne contient pas de token.


Tâche 4 : Utiliser le multi-stage build

Créez un Dockerfile multi-stage pour une application Go ou Python qui sépare l'environnement de build de l'image finale :

Indice :

`dockerfile

# Stage 1 : Build

FROM python:3.12 AS builder

WORKDIR /build

COPY requirements.txt .

RUN pip install --user --no-cache-dir -r requirements.txt

>

# Stage 2 : Runtime (image minimale)

FROM python:3.12-slim AS runtime

WORKDIR /app

>

# Copier seulement les dépendances installées

COPY --from=builder /root/.local /root/.local

COPY src/ ./src/

>

RUN groupadd -r app && useradd -r -g app app

USER app

>

ENV PATH=/root/.local/bin:$PATH

CMD ["python", "src/app.py"]

`

Vérification : L'image finale ne contient pas pip, les outils de compilation, ni les fichiers temporaires du build. Taille réduite.


Tâche 5 : Utiliser .dockerignore

Créez un .dockerignore pour éviter de copier des fichiers sensibles :

Indice :

`

.git/

.env

.env.*

*.secret

__pycache__/

*.pyc

.pytest_cache/

node_modules/

.DS_Store

README.md

tests/

docs/

`

Vérification : Buildez l'image avec COPY . . et vérifiez que .env n'est pas dans le conteneur : docker run mon-image ls -la ne doit pas afficher .env.


🗂️ Mini-Projet

Réécrivez le Dockerfile vulnérable initial en Dockerfile sécurisé complet. Comparez les tailles avec docker images et les résultats de scan Trivy avant/après.

bash
# Comparer les tailles
docker images | grep mon-app

# Scanner avant
trivy image mon-app:vulnerable

# Scanner après
trivy image mon-app:secure

Checkpoints :

  • Le conteneur ne tourne pas en root (whoami = appuser)
  • Aucun secret dans docker history ni docker inspect
  • .dockerignore exclut .env et .git
  • L'image multi-stage est plus petite que l'image originale
  • Trivy trouve moins de vulnérabilités sur l'image sécurisée

Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement de l'exercice
  • Tâche 1 : Analyser un Dockerfile vulnérable
  • Tâche 2 : Ajouter USER pour éviter root
  • Tâche 3 : Éviter les secrets dans les layers
  • Tâche 4 : Utiliser le multi-stage build
  • Tâche 5 : Utiliser .dockerignore
  • 🗂️ Mini-Projet