Introduction
Démarrer un conteneur Docker est simple; l'opérer de manière sûre et reproductible l'est beaucoup moins. Docker secrets, env files, Docker Compose secrets, BuildKit secrets et les bonnes pratiques de configuration sont les briques clés pour limiter les fuites d'identifiants, améliorer la container security et réduire les surprises entre local, CI/CD et production.
Ce guide garde une approche pratique : pour chaque point, nous indiquons quoi configurer, quelle commande prouve que cela fonctionne, et ce qui se passe quand la configuration est absente ou erronée. Vous pourrez ainsi tester localement, documenter vos choix, et appliquer le même motif dans un environnement proche de la production.
Vue d'ensemble du workflow
Un workflow robuste suit trois étapes courtes :
- Identifier la ressource et le changement pertinent (secret de base de données, URL d'API, volume de données, réseau).
- Appliquer la configuration minimale.
- Vérifier l'état observé avec des docker commands, puis noter les symptômes en cas d'échec.
Commandes utiles au quotidien :
- Inspecter l'exécution :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" - Lire les erreurs récentes :
docker logs <container> --tail 100 - Inspecter la configuration :
docker inspect <container>(montages, réseaux, variables d'environnement, healthcheck) - Avec Docker Compose :
docker compose ps,docker compose logs -f <service>,docker compose exec <service> sh
Stockage des données :
- Volume nommé (ex.
app_data:/var/lib/app) : géré par Docker, réutilisable lors des rebuilds. - Bind mount (ex.
./data:/var/lib/app) : direct vers l'hôte, pratique en local mais sensible aux permissions, à la portabilité et aux sauvegardes.
Test de redémarrage (persistance) :
- Démarrer le service et générer une donnée test. 2) Stopper et recréer le conteneur. 3) Vérifier que l'application retrouve la donnée. Si elle a disparu, l'écriture s'est probablement faite dans le filesystem éphémère du conteneur plutôt que dans un volume ou un montage.
Plan pilote local
Objectif : prouver localement que vos secrets ne fuient pas et que votre application démarre avec la bonne configuration.
1) Env files : configuration non sensible
Utilisez un .env local pour les valeurs non sensibles (ports, flags). Ne commitez pas de secrets.
Exemple .env :
APP_PORT=8080
APP_ENV=development
# Pas de mot de passe ici
Docker Compose (extrait) :
services:
app:
image: app: dev
ports:
- "${APP_PORT}:8080"
environment:
- NODE_ENV=${APP_ENV}
Vérifiez la configuration résolue :
docker compose config
Échec typique : variable non définie. Symptôme : Compose échoue à interpoler ${APP_ENV}. Correction : définir la variable dans .env ou dans l'environnement du shell.
2) Secrets à l'exécution : fichiers montés en lecture seule
En local (hors Swarm), un moyen simple et sûr est de monter un fichier secret en lecture seule, puis de le lire dans l'application à l'exécution.
Préparez le secret :
echo "super-secret-token" > .secrets/api_token
chmod 600 .secrets/api_token
Compose (montage RO) :
services:
app:
image: app: dev
volumes:
- type: bind
source: ./.secrets/api_token
target: /run/secrets/api_token
read_only: true
environment:
- API_TOKEN_FILE=/run/secrets/api_token
Dans l'application, lisez le fichier pointé par API_TOKEN_FILE. Avantage : le secret n'est pas dans l'image, ni dans docker inspect en clair (contrairement à une variable d'environnement). Symptôme d'échec : fichier manquant (ENOENT) si le chemin cible n'est pas correct ou si le montage est absent. Vérifiez avec :
docker inspect <container> --format '{{ json .Mounts }}'
3) Docker Compose secrets (mode Swarm)
Les Docker Compose secrets s'intègrent nativement avec le mode Swarm. Pour un projet local classique, préférez un fichier monté ou des gestionnaires de secrets externes. En mode Swarm, vous pouvez définir :
secrets:
db_password:
file: ./secrets/db_password.txt
services:
app:
image: app: dev
secrets:
- db_password
Le secret sera exposé sous /run/secrets/db_password. Échec typique : utiliser secrets: sans Swarm actif; le secret ne sera pas géré comme attendu. Vérifiez l'activation de Swarm et l'attachement du secret via docker service ps et docker service inspect si vous déployez en services Swarm.
4) BuildKit secrets : éviter les fuites au build
N'utilisez pas ARG ou ENV pour injecter des identifiants durant le build : ces valeurs se retrouvent dans l'historique des couches et dans docker history.
Mauvaise pratique (extrait Dockerfile) :
ARG NPM_TOKEN
RUN npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN && npm ci
Bonne pratique avec BuildKit secrets :
# syntax=docker/dockerfile:1.6
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN --mount=type=secret, id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) \
&& npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN \
&& npm ci --ignore-scripts
COPY . .
CMD ["npm", "start"]
Commande de build :
DOCKER_BUILDKIT=1 docker build \
--secret id=npm_token, src=.secrets/npm_token \
-t app: dev .
Vérification : le token ne doit pas apparaître dans l'historique :
docker history --no-trunc app: dev | grep -i token || echo "OK: pas de fuite apparente"
Symptôme d'échec : BuildKit désactivé ou --secret absent ; le build échoue (fichier manquant) ou, pire, vous revenez à une méthode qui divulgue l'identifiant.
5) Exécution et persistance : checklist rapide
- Volumes nommés pour les données applicatives :
- Compose :
volumes:
app_data:
services:
app:
volumes:
- app_data:/var/lib/app
- Test de redémarrage :
docker compose up -d
docker compose exec app sh -lc 'echo 123 > /var/lib/app/ping'
docker compose down && docker compose up -d
docker compose exec app sh -lc 'cat /var/lib/app/ping'
- Réseaux et ports : confirmez les mappings et la connectivité avec
docker compose psetdocker exec -it <ctr> sh -lc "nc -zvw3 host port".
- Journaux et troubleshooting :
- D démarrage raté :
docker compose logs -f app - Montages absents :
docker inspect <ctr> --format '{{ json .Mounts }}' - Variables non résolues :
docker compose config
6) Production pitfalls (pièges courants)
- Secrets dans l'image : éviter
ENV/ARGpour des identifiants; préférez BuildKit secrets. .envcommitté avec credentials : bannir; fournissez un.env.examplesans secrets et stockez les valeurs sensibles dans un gestionnaire externe ou un coffre.- Tags d'image flous (
latest) : source d'incohérences entre environnements. Pointez un tag immuable pour les déploiements. - Bind mounts non portables : chemins hôte différents, permissions incohérentes. En production, préférez des volumes ou un stockage géré.
- Droits de fichiers secrets : limitez les permissions (
chmod 600) et montez en lecture seule. - Différences local/CI : explicitez les hypothèses (réseaux, limites CPU/mémoire,
ulimits) et validez avecdocker inspect.
Conclusion
Docker secrets, env files et des pratiques de configuration sûres fonctionnent au mieux quand l'équipe considère la configuration comme un objet testable, pas un copier-coller. Gardez des exemples petits, exécutez les commandes localement, et confirmez le comportement attendu avant d'ajouter des services ou de l'automatisation. Documentez les commandes pour construire, lancer, inspecter, arrêter et recréer un service, puis confrontez vos choix aux bonnes pratiques Docker security, Docker Compose et Dockerfile best practices. Un workflow fiable rend la panne visible (journaux accessibles), conserve les données (volumes testés), et rapproche suffisamment le local de la production pour attraper tôt les erreurs de configuration.