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

ModulesDocker Compose et optimisation pour la production04 - Appliquer les bonnes pratiques de sécurité Docker

Détails

  • 20 minutes
  • Avancé

Objectifs

  • Exécuter les processus applicatifs sous un utilisateur non-root
  • Restreindre les capacités du conteneur avec read_only et no-new-privileges
  • Exclure les fichiers sensibles du contexte de build avec .dockerignore
Module Docker Compose et optimisation pour la production

Exercice 04 : Appliquer les bonnes pratiques de sécurité Docker

🎯 Objectifs

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

  • ✅ Créer un utilisateur non-root dans un Dockerfile avec adduser/USER
  • ✅ Monter le système de fichiers en lecture seule avec read_only: true
  • ✅ Empêcher l'escalade de privilèges avec security_opt: no-new-privileges
  • ✅ Protéger les fichiers sensibles avec .dockerignore
  • ✅ Injecter des secrets via des variables d'environnement sans les exposer dans l'image

Durée estimée : 20 min | Difficulté : ⭐⭐⭐⭐☆


📖 Contexte

Par défaut, les processus dans un conteneur tournent en root. Si l'application est compromise, l'attaquant dispose de tous les droits dans le conteneur et peut potentiellement s'échapper vers l'hôte. Appliquer le principe du moindre privilège réduit considérablement la surface d'attaque.


📋 Énoncé

Sécurisez une application web Python Flask en appliquant les quatre couches de protection : utilisateur non-root, filesystem en lecture seule, restriction des privilèges système et exclusion des fichiers sensibles du contexte de build.


🧭 Déroulement

Tâche 1 : Créer un utilisateur non-root dans le Dockerfile

Dans votre Dockerfile, après avoir installé les dépendances, créez un utilisateur appuser (uid 1001) et basculez vers cet utilisateur avant le CMD.

Indice :

`dockerfile

RUN addgroup -S appgroup && adduser -S -G appgroup -u 1001 appuser

USER appuser

`

Sur des images Debian/Ubuntu, remplacez par addgroup --system et adduser --system.

Vérification : docker run --rm <image> whoami affiche appuser, pas root.


Tâche 2 : Configurer .dockerignore

Créez un .dockerignore qui exclut .env, *.key, *.pem, __pycache__, .git et node_modules du contexte de build.

Indice : Chaque ligne du .dockerignore est un pattern glob, comme un .gitignore.

Vérification : Créez un fichier .env avec SECRET=topsecret dans le dossier. Buildez l'image et vérifiez que docker run --rm <image> cat /app/.env échoue avec "No such file".


Tâche 3 : Restreindre le conteneur dans docker-compose.yml

Dans docker-compose.yml, ajoutez sur le service applicatif :

  • read_only: true pour monter le système de fichiers en lecture seule
  • security_opt: ["no-new-privileges:true"] pour bloquer l'escalade de privilèges

Ajoutez un volume tmpfs sur /tmp pour permettre les écritures temporaires nécessaires à l'application.

Indice : tmpfs: [/tmp] monte /tmp en mémoire, contournant le read_only pour ce seul répertoire.

Vérification : docker compose run app touch /etc/test échoue avec "Read-only file system".


Tâche 4 : Injecter les secrets par variable d'environnement

Définissez la variable DATABASE_URL comme variable d'environnement dans docker-compose.yml en la lisant depuis un fichier .env local (non commité). Ne codez jamais la valeur directement dans le YAML.

Indice : Docker Compose charge automatiquement le fichier .env du répertoire courant. Référencez la variable avec ${DATABASE_URL} dans le YAML.

Vérification : docker compose config affiche la valeur interpolée sans la stocker dans l'image.


🗂️ Mini-Projet

Complétez les points suivants :

  • docker run --rm <image> whoami retourne appuser
  • .env est absent de l'image (vérifiable avec docker run --rm <image> ls -la /app)
  • docker compose run app touch /etc/pwned échoue (read_only)
  • docker inspect <container> montre "Privileged": false et "ReadonlyRootfs": true
  • Aucun secret n'est codé en dur dans Dockerfile ni docker-compose.yml

Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement
  • Tâche 1 : Créer un utilisateur non-root dans le Dockerfile
  • Tâche 2 : Configurer .dockerignore
  • Tâche 3 : Restreindre le conteneur dans docker-compose.yml
  • Tâche 4 : Injecter les secrets par variable d'environnement
  • 🗂️ Mini-Projet