Aller au contenu

Docker Production Pattern

Contexte

Docker est largement utilisé pour déployer des applications backend modernes. Il permet d'encapsuler une application et ses dépendances dans un conteneur portable.

Cependant, un conteneur utilisé en production doit être construit différemment d'un conteneur de développement.

Les objectifs principaux sont :

  • sécurité
  • reproductibilité
  • performance
  • isolation

Une mauvaise configuration peut exposer le système à des vulnérabilités ou compliquer la maintenance.


Principe

Le pattern "Docker Production" consiste à construire des images conteneurisées :

  • minimalistes
  • sécurisées
  • reproductibles

Cela implique plusieurs bonnes pratiques.


Multi-stage Build

Les images Docker doivent être construites en plusieurs étapes.

Objectif :

  • séparer la phase de build
  • produire une image finale minimale

Exemple :

FROM maven:3.9-eclipse-temurin-21 AS build

WORKDIR /app
COPY . .
RUN mvn package

FROM eclipse-temurin:21-jre

COPY --from=build /app/target/app.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

Avantages

  • image plus petite
  • moins de dépendances
  • surface d’attaque réduite

Utilisateur non-root

Les conteneurs ne doivent pas s'exécuter avec l'utilisateur root.

Exemple :

RUN useradd -u 10001 appuser
USER appuser

Avantages

  • limite les privilèges
  • réduit les risques en cas de compromission

Filesystem en lecture seule

En production, le filesystem du conteneur peut être configuré en lecture seule.

Exemple dans docker-compose :

read_only: true

Cela empêche l'écriture de fichiers malveillants dans le conteneur.


Répertoires temporaires (tmpfs)

Les répertoires temporaires peuvent être placés en mémoire.

Exemple :

tmpfs:

/tmp

Avantages

  • améliore les performances
  • empêche la persistance de fichiers

Réseau Docker

Les services internes doivent communiquer via un réseau Docker interne.

Exemple :

networks:
backend-network

Les bases de données et brokers ne doivent pas être exposés publiquement.


Gestion des variables d’environnement

Les configurations doivent être injectées via des variables d’environnement.

Exemple :

SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=postgres://...

Cela permet :

  • de séparer configuration et code
  • d’adapter facilement les environnements

Healthchecks

Les conteneurs doivent exposer un mécanisme de vérification de santé.

Exemple :

healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]

Les orchestrateurs peuvent utiliser ces informations pour redémarrer les conteneurs.


Logs

Les applications doivent écrire leurs logs sur la sortie standard.

Exemple :

stdout
stderr

Cela permet aux systèmes d’orchestration de collecter les logs.


Avantages

Cette approche apporte :

  • sécurité renforcée
  • images plus petites
  • déploiements reproductibles
  • meilleure observabilité

Limites

La configuration peut devenir plus complexe.

Certaines applications doivent être adaptées pour fonctionner avec un filesystem en lecture seule.


Conclusion

Docker est un outil puissant pour déployer des applications backend modernes.

En appliquant ces bonnes pratiques, il est possible de construire des conteneurs sécurisés, portables et adaptés à la production.


Voir aussi