Niveau 🔴 avancé
Durée estimée : 30 min · Prérequis : Un compose.yaml décortiqué
PUID/PGID, user:)Un conteneur qui écrit dans un bind mount, c'est un invité qui dépose des affaires dans un
casier de la maison qu'il visite. Le problème : l'étiquette qu'il colle sur ses affaires porte un
numéro (son UID, vu en M1) propre à son
système à lui — pas forcément le même numéro que celui utilisé pour identifier les habitants de
la maison. RĂ©sultat : la maison peut refuser de reconnaĂ®tre ces affaires comme appartenant Ă
quelqu'un d'autorisé, même si tout s'est bien passé du point de vue de l'invité.
Le problème, précisément. Les permissions Linux
reposent sur des identifiants numériques : un UID (User ID) pour l'utilisateur, un GID
(Group ID) pour le groupe. Un bind mount partage un dossier de la machine hĂ´te avec un
conteneur — mais le processus à l'intérieur du conteneur tourne avec l'UID défini par
l'image, pas avec celui de l'utilisateur de la machine hôte. Si ces deux UID diffèrent (très
frĂ©quent : l'utilisateur d'une machine Linux a typiquement l'UID 1000, mais l'UID utilisĂ© Ă
l'intérieur d'une image peut être tout autre chose selon comment elle a été construite), le
conteneur peut se retrouver incapable d'écrire dans le dossier partagé — ou, à l'inverse, y
écrire des fichiers que l'utilisateur de la machine hôte ne peut plus lire ou modifier sans
sudo.
Trois solutions courantes, avec des compromis différents :
setgid. Créer un groupe (par exempledocker-data), donner à l'utilisateur de la machine ce groupe en plus du sien, appliquer cechown -R utilisateur:docker-data /srv/docker), puissetgid sur ce dossier (chmod -R 2775). Ce bit fait que tout nouveauPUID/PGID. Certaines images (en particulier celles du mainteneuruser: du compose.yaml. Force directement l'UID:GID avec lequel leuser: "1000:1001"), sans dépendre d'un support explicite de l'image.⚠️ Un piège supplémentaire, au-delà des fichiers : les périphériques. Rendre un
périphérique matériel visible dans un conteneur (devices:dans le compose.yaml, par exemple
pour un GPU) ne suffit pas toujours à le rendre accessible. Le périphérique appartient
lui-même à un groupe système sur la machine hôte (souventrenderpour l'accélération vidéo).
Sans ajouter ce groupe au conteneur (group_add:), le processus interne peut voir le
périphérique sans avoir le droit de s'en servir — une distinction entre « UID pour les
fichiers » et « GID supplémentaire pour un périphérique », qui se règlent différemment.
🧪 Concrètement, sur notre exemple, deux cas réels distincts :
Cas 1 — la solution structurelle. Un groupe dédié
docker-data, avec le bitsetgid
appliquĂ© Ă/srv/docker/, a Ă©tĂ© retenu comme solution par dĂ©faut, après comparaison de
plusieurs approches possibles.Cas 2 — l'exception rencontrée en pratique. Deux services de supervision (l'un pour les
métriques, l'autre pour les tableaux de bord) se sont retrouvés en échec de démarrage répété
au premier déploiement, avec une erreur explicite de type « accès refusé » / « non
inscriptible » dans leurs journaux. Cause : ces images tournent, en interne, avec un UID
différent de celui attendu par la solution structurelle du groupe dédié, et ne supportent pas
PUID/PGID. Corrigé en forçant explicitementuser: "1000:1001"dans leurcompose.yaml.Cas 3 — le piège du périphérique. Un service d'accélération vidéo a eu besoin, en plus de
user:, d'ungroup_add:explicite vers le groupe système du périphérique GPU de la machine
—user:seul rendait le périphérique visible, mais pas utilisable.
Trois chemins mènent à une écriture réussie — le bit setgid sur le dossier, la directive
user: forcée, ou le support natif de PUID/PGID par l'image — et l'absence des trois mène
systématiquement à un refus d'accès.
id utilisateur
# Affiche l'UID et les GID de l'utilisateur de la machine hĂ´te
ls -la /srv/docker/mon-service
# Vérifie le propriétaire et le groupe du dossier partagé, et si le
# bit setgid est actif (un "s" Ă la place du "x" dans les droits du groupe)
docker exec mon-service id
# Affiche l'UID/GID avec lequel le PROCESSUS À L'INTÉRIEUR du conteneur
# tourne réellement -- à comparer avec celui du dossier hôte
sudo groupadd docker-data
sudo usermod -aG docker-data utilisateur
sudo chown -R utilisateur:docker-data /srv/docker
sudo chmod -R 2775 /srv/docker
# Met en place la solution structurelle : groupe dédié + bit setgid
docker exec mon-service touch /app/data/test-permission && \
ls -la /srv/docker/mon-service/test-permission
Le fichier créé depuis l'intérieur du conteneur doit apparaître, côté machine hôte, avec le bon
groupe (docker-data dans l'exemple ci-dessus) — la preuve que le bit setgid fonctionne comme
attendu.
| SymptĂ´me | Cause probable | Solution |
|---|---|---|
permission denied / is not writable au démarrage d'un conteneur |
UID interne à l'image différent de celui attendu par le dossier partagé | Comparer docker exec <conteneur> id avec ls -la du dossier hôte ; forcer user: si la solution structurelle ne suffit pas |
Un périphérique matériel visible (ls /dev dans le conteneur) mais inutilisable |
Groupe système du périphérique non ajouté au conteneur | Ajouter group_add: avec le GID du groupe propriétaire du périphérique sur l'hôte |
Fichiers créés par un conteneur illisibles depuis la machine hôte sans sudo |
Le fichier appartient à un UID/GID que l'utilisateur de la machine ne possède pas | Mettre en place un groupe dédié avec bit setgid, pour que tout nouveau fichier hérite du bon groupe automatiquement |
setgid est une solution structurelle qui couvre la majorité des casPUID/PGID (si l'image les supporte) ou user: forcé dans le compose.yaml sont lesdevices:) ne le rend pas forcément utilisable — ungroup_add: supplémentaire est parfois nécessaire.Parce que le processus à l'intérieur du conteneur tourne avec un UID propre à l'image, qui peut
différer de celui attendu (propriétaire ou groupe) par le dossier partagé sur la machine hôte.
Il fait que tout nouveau fichier créé dans ce dossier hérite automatiquement du groupe du
dossier parent, quel que soit l'UID du processus qui l'a créé — à condition que ce processus
appartienne Ă ce groupe.
Parce que rendre un périphérique visible (devices:) ne le rend pas automatiquement accessible
— il faut aussi ajouter le groupe système propriétaire de ce périphérique via group_add:.
Sur une machine avec Docker, lance un conteneur avec un bind mount vers un dossier vide de ton
choix (docker run -v /tmp/test:/data alpine touch /data/fichier), puis compare, avec ls -la,
le propriétaire du fichier créé côté machine hôte à ton propre UID (id). Explique l'écart
observé avec le vocabulaire de cette page.
UID ·
GID ·
setgid ·
PUID/PGID
Cette formation est proposée par Deladev, studio web de Loïc D. — création de sites et d'applications, accompagnement et formation sur mesure.
Les projets réalisés · Prestations et tarifs · Le blog tech · Me contacter
Écrite par Loïc D. avec l'assistance de Claude (Anthropic) — un travail à deux.
© 2026 Deladev — publiée sous licence CC BY-NC-ND 4.0. Vous pouvez la lire, y renvoyer par un lien, la partager et la citer en créditant la source. La revendre, l'utiliser dans une prestation ou une formation payante, la republier même partiellement ailleurs, en diffuser une version modifiée ou l'exploiter pour entraîner un modèle d'IA nécessitent une autorisation écrite — pour un usage interne en entreprise, c'est souvent oui, il suffit de demander.