[{"data":1,"prerenderedAt":179},["ShallowReactive",2],{"seo-verification":3,"blog-docker-secrets-securite-vps-production-fr":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-docker-secrets-securite-vps-production-fr",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":30,"intro":33,"sections":34,"ctaTitle":118,"ctaBody":119,"ctaButton":120,"ctaUrl":121,"relatedPosts":122},369,"docker-secrets-securite-vps-production",{"fr":10,"en":12,"ar":13,"es":14},"docker-secrets-production-protecting-credentials-on-vps","اسرار-docker-في-الانتاج-حماية-بيانات-الاعتماد-على-vps","docker-secrets-produccion-proteger-credenciales-vps","Docker Secrets en production : protéger ses secrets sur VPS","Gérez vos secrets Docker en production sans les exposer dans docker-compose.yml. Docker Secrets sans Swarm, .env.vault et SOPS : méthode et comparatif.",7,0,false,"2026-09-20T00:00:00+00:00","2026-09-20T21:13:51+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Sécurité & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fdocker-secrets-securite-vps-production-poster.svg","Un docker-compose.yml avec des clés API en clair, c'est une fuite qui attend son scanner. Cet article explique comment éliminer ce risque sur un VPS root : Docker Secrets natif (sans Swarm depuis Compose v2.24), .env.vault et SOPS — chaque méthode avec ses commandes exactes et ses vraies limites.",[35,39,48,51,70,105,108,112,115],{"type":36,"title":37,"body":38},"h2","Le vrai risque : vos secrets voyagent dans vos images","En 2024, GitGuardian a détecté plus de 12,8 millions de secrets exposés dans des dépôts publics GitHub — un chiffre en hausse de 28 % par rapport à l'année précédente selon le **State of Secrets Sprawl 2025**. Les images Docker Hub en sont l'un des vecteurs les plus sous-estimés.\n\nLorsque vous écrivez `ARG API_KEY` dans un `Dockerfile` ou que vous passez `-e DB_PASSWORD=hunter2` au démarrage, ce secret ne reste pas confiné au runtime. Il peut se retrouver :\n\n- dans les **layers de l'image** buildée (inspectable avec `docker history --no-trunc`) ;\n- dans les **métadonnées** de l'image exportée sur Docker Hub (`docker inspect`) ;\n- dans votre fichier `.env` **commité par erreur** lors d'un `git add .` pressé.\n\nLes scanners automatiques (Trivy, Grype, GitGuardian) parcourent Docker Hub en continu. Un dépôt public avec un secret en clair est indexé en quelques minutes. La fenêtre d'exposition est quasi nulle.",{"type":40,"title":41,"items":42},"ul","5 erreurs de configuration qui exposent vos secrets",[43,44,45,46,47],"**Variables d'env en clair dans `docker-compose.yml`** — `environment: DB_PASSWORD: hunter2` est lisible par quiconque accède au fichier ou à l'image.","**Fichier `.env` commité** — `.gitignore` manqué une fois, et le secret est dans l'historique git pour toujours (même après `git rm`, accessible via `git log`).","**`ARG` passé au `build` puis copié dans l'image** — les `ARG` sont gravés dans les métadonnées de layer et lisibles par `docker history`.","**Secrets dans les logs** — une application qui logue ses variables d'environnement au démarrage (Spring Boot, Rails en debug, certains serveurs Node) imprime les credentials dans `docker logs`.","**Volumes bind-mount sur `\u002Froot` ou le répertoire du projet** — un fichier `.env` monté depuis l'hôte reste accessible à tout processus du conteneur avec les droits root.",{"type":36,"title":49,"body":50},"Prérequis","Pour suivre cet article, vous avez besoin de :\n\n- Un **VPS Linux** (Debian 12 ou Ubuntu 22.04+) avec accès root.\n- **Docker Engine ≥ 24** et **Docker Compose ≥ 2.24** (vérifier avec `docker compose version`).\n- Pour SOPS : `age` installé (paquet `age` sur Debian\u002FUbuntu, ou binaire depuis \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FFiloSottile\u002Fage\u002Freleases\">github.com\u002FFiloSottile\u002Fage\u003C\u002Fa>).\n- Pour .env.vault : Node.js ≥ 18 et le CLI `dotenvx` (`npm install -g @dotenvx\u002Fdotenvx`).\n\nAucun cluster Swarm n'est requis pour les méthodes présentées ici.",{"type":52,"title":53,"steps":54},"steps","Méthode 1 — Docker Secrets en Compose non-Swarm (pas à pas)",[55,58,61,64,67],{"title":56,"body":57},"Vérifier la version de Compose","Docker Secrets fonctionne sans Swarm depuis **Docker Compose v2.24.0** (release du 11 janvier 2024). Vérifiez :\n\n```bash\ndocker compose version\n# Docker Compose version v2.27.1\n```\n\nSi vous êtes en dessous de la v2.24, mettez Compose à jour avant de continuer (`apt-get install docker-compose-plugin` sur Debian\u002FUbuntu).",{"title":59,"body":60},"Créer les fichiers de secrets","Les secrets Docker Compose en mode non-Swarm sont des **fichiers sur l'hôte**, montés en tmpfs dans le conteneur. Créez-les hors du répertoire du projet :\n\n```bash\nmkdir -p \u002Fetc\u002Fmyapp\u002Fsecrets\necho -n 'motdepasse-db-solide' > \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password\necho -n 'cle-api-stripe-xxxxx' > \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fstripe_key\nchmod 600 \u002Fetc\u002Fmyapp\u002Fsecrets\u002F*\nchown root:root \u002Fetc\u002Fmyapp\u002Fsecrets\u002F*\n```\n\nLe `-n` de `echo` évite le saut de ligne final — certaines applications lisent le fichier en entier, saut de ligne compris, ce qui invalide la clé.",{"title":62,"body":63},"Déclarer les secrets dans docker-compose.yml","```bash\nservices:\n  app:\n    image: monapp:latest\n    secrets:\n      - db_password\n      - stripe_key\n    environment:\n      # on indique le CHEMIN, pas la valeur\n      DB_PASSWORD_FILE: \u002Frun\u002Fsecrets\u002Fdb_password\n      STRIPE_KEY_FILE: \u002Frun\u002Fsecrets\u002Fstripe_key\n\nsecrets:\n  db_password:\n    file: \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password\n  stripe_key:\n    file: \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fstripe_key\n```\n\nNotez l'usage de la convention `*_FILE` : votre application doit lire la variable `DB_PASSWORD_FILE`, ouvrir le fichier indiqué et en lire le contenu. Les images officielles PostgreSQL, MySQL, Redis et la plupart des images Bitnami **supportent nativement cette convention** — vérifiez la documentation de votre image.",{"title":65,"body":66},"Vérifier le montage dans le conteneur","Après `docker compose up -d`, inspectez le montage :\n\n```bash\ndocker compose exec app ls -la \u002Frun\u002Fsecrets\u002F\n# -r-------- 1 root root 20 Sep 20 08:12 db_password\n# -r-------- 1 root root 28 Sep 20 08:12 stripe_key\n\ndocker inspect monapp_app_1 | grep -A5 Mounts\n# \"Type\": \"tmpfs\",\n# \"Destination\": \"\u002Frun\u002Fsecrets\",\n```\n\nLe montage est de type **tmpfs** : le contenu vit en mémoire vive, jamais écrit sur le disque du conteneur. Il disparaît à l'arrêt du conteneur.",{"title":68,"body":69},"Ce que Docker Secrets ne fait PAS — à comprendre avant de continuer","Docker Secrets n'est pas un coffre-fort hermétique. Ce qu'il **ne protège pas** :\n\n- Le fichier source (`\u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password`) reste sur le **disque hôte** en clair — root sur la VM y accède toujours.\n- Tout **processus du conteneur** (PID 1 comme un sous-processus lancé par l'app) peut lire `\u002Frun\u002Fsecrets\u002F*`.\n- Une **variable d'environnement dérivée** du secret (`DB_PASSWORD=$(cat \u002Frun\u002Fsecrets\u002Fdb_password)` dans un entrypoint) remet le secret dans l'env, visible par `docker inspect`.\n\nDocker Secrets protège contre la fuite dans les layers d'image et dans `docker-compose.yml`. Il ne protège pas contre un processus compromis à l'intérieur du conteneur.",{"type":71,"title":72,"headers":73,"rows":78},"comparison","Docker Secrets vs .env.vault vs SOPS — quelle méthode pour quel contexte",[74,75,76,77],"Critère","Docker Secrets (Compose)",".env.vault (dotenvx)","SOPS + age",[79,83,87,91,95,100],[80,81,82,82],"Swarm requis","Non (depuis Compose v2.24)","Non",[84,85,86,86],"Secret stocké en clair sur l'hôte","Oui (fichier source)","Non (chiffré en dépôt)",[88,82,89,90],"KMS distant nécessaire","Non (clé symétrique locale possible)","Non (age fonctionne off-line)",[92,93,94,94],"Rotation sans redéploiement","Non (restart nécessaire)","Non (rebuild .env)",[96,97,98,99],"CI\u002FCD : injection dans le pipeline","Complexe (fichiers à provisionner)","Simple (variable `DOTENV_PRIVATE_KEY`)","Moyen (clé age en secret CI)",[101,102,103,104],"Courbe d'apprentissage","Faible (natif Compose)","Faible (CLI dotenvx)","Moyenne (syntaxe YAML + clés age\u002FGPG)",{"type":36,"title":106,"body":107},"Configuration complémentaire : rotation et chiffrement au repos","**Rotation des secrets Docker Compose.** Docker Compose non-Swarm ne supporte pas la rotation à chaud (contrairement à Swarm qui peut mettre à jour un secret sans couper le service). Pour changer un secret :\n\n```bash\n# 1. Écrire la nouvelle valeur\necho -n 'nouveau-motdepasse' > \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password\n# 2. Redémarrer le service concerné\ndocker compose restart app\n```\n\n**Chiffrer les fichiers sources avec age.** Si vous voulez chiffrer les fichiers sur l'hôte (contre un vol de snapshot ou une sauvegarde compromise), SOPS + age permet de stocker les fichiers chiffrés et de les déchiffrer au démarrage :\n\n```bash\n# Générer une clé age\nage-keygen -o \u002Froot\u002F.config\u002Fsops\u002Fage\u002Fkeys.txt\n# Chiffrer le fichier de secret\nsops --encrypt --age $(age-keygen -y \u002Froot\u002F.config\u002Fsops\u002Fage\u002Fkeys.txt) \\\n  \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password > \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password.enc\n# Dans le script de démarrage, déchiffrer avant docker compose up\nsops --decrypt \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password.enc > \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password\n```\n\n**Audit des accès.** Activez les logs Docker avec `journald` (`--log-driver=journald` dans `\u002Fetc\u002Fdocker\u002Fdaemon.json`) pour conserver une trace de qui a lancé quels conteneurs et quand.",{"type":109,"title":110,"body":111},"tip","Ce que Docker Secrets ne protège pas","Docker Secrets monte le secret en **tmpfs dans `\u002Frun\u002Fsecrets\u002F`** : c'est un filet de sécurité contre les fuites dans les images et les fichiers Compose, pas contre un processus compromis à l'intérieur du conteneur. Tout process qui tourne dans le conteneur — y compris un shell obtenu par RCE — peut lire `\u002Frun\u002Fsecrets\u002F*`. Et root sur l'hôte accède toujours au fichier source.\n\nSi votre modèle de menace inclut un conteneur compromis, la bonne réponse est un secret manager externe (HashiCorp Vault, AWS Secrets Manager, Infisical self-hosted) qui délivre les secrets par API avec authentification, sans jamais les écrire sur le disque du conteneur.",{"type":36,"title":113,"body":114},"Dépannage — erreurs courantes","**`unknown shorthand flag: 's' in -s`** lors de `docker compose up`\nVous utilisez l'ancienne commande `docker-compose` (v1, Python). Passez à `docker compose` (v2, plugin Go) avec `apt-get install docker-compose-plugin`.\n\n**`secrets are only supported when deploying to a swarm`**\nVotre version de Docker Compose est inférieure à la v2.24. Vérifiez avec `docker compose version` et mettez à jour.\n\n**Le conteneur démarre mais `\u002Frun\u002Fsecrets\u002Fdb_password` est vide**\nVérifiez que le fichier source existe et n'est pas vide : `cat \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password | wc -c`. Un fichier vide crée un montage tmpfs vide, sans erreur.\n\n**`permission denied` en lisant `\u002Frun\u002Fsecrets\u002F`**\nLes fichiers sont montés avec les permissions du fichier source. Si votre processus tourne sous un utilisateur non-root dans le conteneur, ajustez les permissions du fichier hôte : `chmod 640 \u002Fetc\u002Fmyapp\u002Fsecrets\u002Fdb_password` et vérifiez le GID du processus.\n\n**`docker inspect` montre encore la variable d'env en clair**\nVous avez déclaré le secret mais aussi passé la valeur dans `environment:`. Retirez l'entrée en valeur directe et n'utilisez que la convention `*_FILE` dans `environment:`.",{"type":36,"title":116,"body":117},"Vos secrets sous contrôle — et la suite","Docker Secrets en mode Compose non-Swarm élimine la principale cause de fuite : les credentials en clair dans les fichiers de configuration et les layers d'images. La méthode tient en cinq étapes, fonctionne sans infrastructure externe et s'intègre dans n'importe quel workflow existant.\n\nPour aller plus loin :\n\n- **Checklist de production** : \u003Ca href=\"\u002Fblog\u002Fdocker-compose-production-checklist\">les 10 points incontournables pour un docker-compose.yml prêt pour la prod\u003C\u002Fa>.\n- **Premiers pas Docker sur VPS** : \u003Ca href=\"\u002Fblog\u002Fdemarrer-avec-docker-vps\">démarrer avec Docker sur VPS\u003C\u002Fa> si vous êtes en train de construire votre premier environnement.\n- **Durcissement de l'OS** : \u003Ca href=\"\u002Fblog\u002Flinux-hardening-vps-checklist\">checklist de durcissement Linux\u003C\u002Fa> pour sécuriser la couche hôte sur laquelle Docker tourne.","Contrôlez votre stack, contrôlez vos secrets","Un VPS root avec accès Docker complet : vous décidez de la gestion des secrets, de la surface d'attaque, de chaque couche de votre infrastructure.","Déployer sur VPS Cloud","\u002Fvps-cloud",[123,142,163],{"id":124,"slug":125,"slugs":126,"title":130,"excerpt":131,"readTime":23,"views":18,"isPinned":19,"publishedAt":132,"updatedAt":133,"category":134,"categories":139,"featuredImage":30,"bgImage":31,"posterImage":141,"relatedSolution":30},229,"docker-compose-production-checklist",{"fr":125,"en":127,"ar":128,"es":129},"docker-compose-in-production-10-point-checklist","docker-compose-في-الإنتاج-قائمة-التحقق-من-10-نقاط","checklist-docker-compose-en-produccion","Docker Compose en production : checklist des 10 points","Checklist Docker Compose en production : 10 paramètres essentiels, gestion des secrets sans downtime, sauvegarde volumes sans corruption, CVE-2026-17106.","2026-08-06T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":135,"name":136,"slug":137,"color":138,"icon":137},3,"Déploiement","deploiement","bg-success\u002F10 text-success",[140],{"id":135,"name":136,"slug":137,"color":138,"icon":137},"\u002Fblog\u002Fcovers\u002Fdocker-compose-production-checklist-poster.svg",{"id":143,"slug":144,"slugs":145,"title":149,"excerpt":150,"readTime":135,"views":18,"isPinned":19,"publishedAt":151,"updatedAt":133,"category":152,"categories":158,"featuredImage":30,"bgImage":31,"posterImage":160,"relatedSolution":161},136,"demarrer-avec-docker-vps",{"fr":144,"en":146,"ar":147,"es":148},"installing-docker-on-a-vps-a-clean-base-for-your-apps","تثبيت-docker-على-vps-قاعدة-نظيفة-لتطبيقاتك","instalar-docker-en-un-vps","Installer Docker sur un VPS : base propre pour vos apps","Préparez un VPS Docker fiable : isolation, Compose, volumes, réseau et bonnes pratiques pour déployer sans bricolage.","2026-02-10T00:00:00+00:00",{"id":153,"name":154,"slug":155,"color":156,"icon":157},4,"Développement","developpement","bg-warning\u002F10 text-warning","dev",[159],{"id":153,"name":154,"slug":155,"color":156,"icon":157},"\u002Fblog\u002Fcovers\u002Fdemarrer-avec-docker-vps-poster.svg",{"categorySlug":157,"appSlug":162},"docker-starter",{"id":164,"slug":165,"slugs":166,"title":170,"excerpt":171,"readTime":172,"views":173,"isPinned":19,"publishedAt":174,"updatedAt":133,"category":175,"categories":176,"featuredImage":30,"bgImage":31,"posterImage":178,"relatedSolution":30},317,"linux-hardening-vps-checklist",{"fr":165,"en":167,"ar":168,"es":169},"linux-vps-hardening-checklist-for-agencies","قائمة-تصليب-خادم-لينكس-للوكالات-بعد-التسليم","hardening-linux-vps-checklist-para-agencias-tras-la-entrega","Durcissement Linux VPS : checklist agence après livraison","Checklist de durcissement Linux pour agences : auditd, sudo, SSH par clé, UFW, fail2ban et désactivation root — traçabilité et runbook par client.",11,1,"2026-08-30T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[177],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Flinux-hardening-vps-checklist-poster.svg",1789939107461]