Compose: Prise en charge de l'option --user dans "docker-compose up"

Créé le 9 juin 2015  ·  53Commentaires  ·  Source: docker/compose

Je dois passer l'option --user pour exécuter des conteneurs orchestrés sous mon propre UID. C'est principalement à cause des volumes d'hôtes montés, et j'aimerais que l'application dockerisée génère des fichiers qui m'appartiennent, pas la racine.

Avec docker-compose up , ce n'est pas possible, du moins pas directement. En ce moment, j'utilise une solution de contournement folle:

NAME=`compose run -d --user="$UID" someservicename`
docker rename $NAME ${NAME/_run/}

qui est sous-optimal, être doux.

areconfig

Commentaire le plus utile

Il y a presque un an, alors que j'essayais de résoudre ce problème, j'ai trouvé ce sujet. Comme aucune solution n'a été fournie à ce moment-là, j'ai créé un tas de scripts bash d'emballage pour exécuter votre docker-compose.

Au bout d'un an, c'est pareil. Je me demande combien de temps il faut pour résoudre un problème aussi simple pour un logiciel comme docker-compose qui n'est même pas un vrai fournisseur mais plutôt un wrapper.

$UID n'est pas exporté sur Linux par défaut, d'accord ? Cela nous empêche de créer un docker-compose universel - ce qui est une chose étrange en soi car ce logiciel est supposé être une solution frontale, n'est-ce pas ?

Si vous n'aimez pas perdre de temps sur des bagatelles - et je comprends cela - alors pourquoi ne nous laissez-vous pas simplement exécuter une commande hôte aléatoire avant d'exécuter un service, hein ? Nous pourrions simplement faire quelque chose comme ceci :

services:
  web:
     ...
     host_command: export UID

N'est-ce pas évident ?

Tous les 53 commentaires

Je ne suis pas sûr de comprendre, docker-compose run --user est une option, et le docker-compose.yml prend en charge la clé user (http://docs.docker.com/compose/yml/ #working95dir-entrypoint-user-hostname-domainname-mem95limit-privileged-restart-stdin95open-tty-cpu95shares).

Je suppose que nous aurions besoin de prendre en charge la résolution des variables d'environnement dans le champ user afin que vous puissiez le définir sur $UID , n'est-ce pas ? #1377

Salut. Ouais, l'expansion $UID ferait l'affaire dans ce cas. Pourtant, l'option --user pour la commande docker-compose up (pas seulement pour docker-compose run ) serait utile pour démarrer l'ensemble du projet en tant qu'utilisateur particulier.

Le but est de permettre de spécifier l'utilisateur sans toucher à yml.

démarrer l'ensemble du projet en tant qu'utilisateur particulier

Il ne m'est jamais venu à l'esprit que les gens pourraient vouloir faire cela. Pourriez-vous préciser le cas d'utilisation ?

Peu importe, j'ai fait défiler vers le haut. Ai-je raison de penser que vous êtes sous Linux ? Lors de l'utilisation de boot2docker, il crée des fichiers avec des autorisations raisonnables.

Je me demande s'il existe un moyen de configurer le démon Docker pour le faire pour chaque volume qu'il monte.

Oui, sous Linux.

J'utilise compose pour exécuter des tests sur CI en montant le volume de l'hôte (oui, je sais). Sans cette option, certains fichiers sont créés avec un "mauvais" propriétaire, c'est-à-dire root:root

Je sais que je pourrais utiliser un conteneur de données uniquement et inspecter/copier des fichiers à partir de celui-ci, mais un volume hôte est beaucoup plus pratique et nécessite moins de scripts.

up --user pourrait être dangereux si certains conteneurs/services spécifient déjà un utilisateur.

@mrzechonek Je ne pense pas que modifier un conteneur à cause de son environnement soit une bonne pratique.

@josephpage ouais, ça pourrait l'être. L'expansion de $UID ferait cependant l'affaire.

À peu près la seule chose dont j'ai besoin, ce sont les autorisations appropriées sur les volumes hôtes. Je ne connais aucun autre moyen d'y parvenir, à part exécuter le processus de conteneur en tant que $UID ...

Je préférerais en fait que cette fonctionnalité soit présente dans le Damon lui-même, comme l'a dit @aanand . Ou peut-être une option pour monter un volume dans un tel mode (un pilote de stockage peut-être ?).

@mrzechonek , avez-vous trouvé une solution de contournement ?

Non, pas vraiment. En ce moment, nous faisons docker-compose run --user puis renommons/réétiquetons le conteneur pour faire croire à compose qu'il a été lancé par la commande up , de sorte que stop et ps fonctionnerait.

1377 est en master et sera dans la version 1.5.0, vous pourrez donc faire user: $UID dans docker-compose.yml . Si vous êtes à l'aise avec master, vous pouvez l'essayer maintenant, sinon une version RC devrait arriver dans les prochaines semaines.

Je vais fermer ce problème car la fonctionnalité elle-même est implémentée dans le cadre de # 1377

puis renommez/réétiquetez le conteneur pour faire croire à la composition qu'il a été démarré par la commande up

Ce n'est en fait pas la première fois que j'en entends parler (bien que dans ce cas, je suppose que ce n'est que temporaire). J'ai un correctif proposé pour cela dans # 2042

Merci, #1377 corrige ça bien.

@mrzechonek Pourriez-vous préciser comment cela a résolu votre problème ? J'ai exactement le même cas d'utilisation : "J'aimerais que l'application dockerisée génère des fichiers qui m'appartiennent, pas la racine"

J'ai essayé d'ajouter user: $UID au conteneur web et quand j'utilise docker-compose run web touch foo j'obtiens ce qui suit :

WARNING: The UID variable is not set. Defaulting to a blank string.

Le fichier foo est créé, mais il appartient toujours à root .

J'ai utilisé user: $USER , mais $UID fonctionne aussi. Je ne sais pas pourquoi votre configuration se plaint de variables manquantes :(

Ayant exactement le même problème que @michaelmior.

Lorsque j'utilise $USER à la place, j'obtiens System error: Unable to find user Max . Ce qui est logique car il s'agit d'un utilisateur hôte.

Qu'est-ce qui pourrait empêcher $UID d'être disponible lors de l'exécution de docker-compose ?

Bonjour, même problème ici.
Je suis sur Fedora 23 et la variable UID n'est pas propagée lorsque j'appelle la commande env sur l'hôte.

solution de contournement:
faites d'abord un export UID sur l'hôte, puis appelez votre docker-compose

Ce serait bien si docker-compose venait de mettre $UID disposition sans qu'il soit nécessaire de l'exporter. Finit par être passe-partout.

Si UID n'est pas exporté, il n'y a aucun moyen pour composer de l'obtenir, donc je pense que ce que vous demandez est impossible.

Donc, composez simplement car une application en cours d'exécution n'a aucun moyen de déduire l'utilisateur sous lequel elle s'exécute ?

Bien sûr, il pourrait lire la variable d'environnement $USER , mais vous pouvez également le faire à partir du fichier Compose ! Si la variable n'est pas exportée, elle ne sera pas disponible pour les processus enfants. La solution vraiment simple semble être simplement de l'exporter.

Je pense plutôt que si l'UID n'est pas déclaré, alors l'exécutable pourrait regarder l'uid de qui l'a exécuté et le rendre disponible en tant que tel.

Encore une fois, pensez au passe-partout et aux étapes faciles à ignorer. La plupart des gens veulent une configuration où la seule étape est docker-compose up . Pourquoi ajouter une petite exigence variable que 99 % des gens vont tous définir exactement de la même manière.

Existe-t-il une ressource intéressante qui énonce d'autres pièges similaires entre les hôtes Mac et Linux ?

De plus, forcer l'utilisateur n'est pas vraiment ce que nous voulons sous Linux, nous voulons le comportement de Mac, où même lorsque vous exécutez en tant que root dans le conteneur, les nouveaux fichiers sur les volumes hôtes ont des autorisations utiles :(

En fait, j'étais simplement confus quant à la raison pour laquelle mon comportement Mac était meilleur que mon comportement Linux, et cela n'a strictement rien à voir avec ce problème. J'ai lancé un problème sur Dinghy pour rechercher des solutions pour une expérience agréable sur Linux.

@mrzechonek pouvez-vous partager comment vous utilisez la directive user: pour vous assurer que les autorisations de fichier sont correctes sur l'hôte et le conteneur ?

J'ajoute simplement user: $UID dans le fichier .yml . C'est sur Linux, Gentoo et Ubuntu 12.04.

@mrzechonek merci. Votre conteneur fait-il alors de la magie à l'exécution ? Autant que je sache, user: reflète l'instruction Dockerfile. Mais cela signifie simplement que les commandes à l'intérieur du conteneur s'exécutent en tant que user: $UID . Je ne comprends pas comment cela aide avec les autorisations de volume =/.

@mrzechonek : C'est différent. Nous voulons une fonctionnalité pour contrôler l'utilisateur auquel le conteneur agit, à l'extérieur du système hôte, quel que soit l'utilisateur configuré à l'intérieur du conteneur lui-même.

Pensez : _" root dans le conteneur écrit en tant qu'utilisateur myuser sur l'hôte"_.

Dans notre cas d'utilisation, c'est à peu près toujours le même utilisateur qui construit le conteneur et l'exécute, il n'y a donc aucun problème.

Si, toutefois, vous souhaitez mapper les utilisateurs de conteneurs aux utilisateurs hôtes "de manière dynamique", je pense que la seule façon de procéder est de prendre en charge les espaces de noms d'utilisateurs LXC dans le démon docker lui-même, fonctionnalité qui n'est pas implémentée (encore? autant que je connaître?).

Je ne pense pas que ce soit quelque chose que docker-compose puisse faire.

On dirait que j'ai raté quelques versions : https://integratedcode.us/2015/10/13/user-namespaces-have-arrived-in-docker/

Désolé, je n'utilise plus Docker, du moins pas activement dans le projet en cours.

Merci @mrzechonek. En fin de compte, j'essaie de faire ce que @gkop essaie de faire - avoir les fichiers générés par le conteneur sur les volumes montés sur l'hôte appartenant au démarreur de conteneur. C'est ainsi que cela fonctionne sur OS X avec la dernière version bêta de Docker 1.12 (comment ?) et c'est ainsi que j'aimerais le voir également sur Linux.

@mrzechonek - Certaines applications nécessitent qu'elles soient exécutées en tant qu'utilisateur particulier, ou exigent que l'utilisateur qu'elles exécutent en tant que carte à un vrai dans le système. Dans ces cas, il est plus facile de le laisser en tant que root et de faire le mappage sur la tête du conteneur.

(c'est au lieu de beaucoup de hacks laids pour mapper le schéma utilisateur du système en cours d'exécution sur le conteneur juste pour que tout s'aligne)

@dmitrym0 Je pense que sous OSX, vous exécutez boot2docker dans une virtualisation OSX native (https://github.com/mist64/xhyve/), puis des conteneurs sont créés dans cette machine virtuelle. Cela signifie que c'est vraiment la machine virtuelle qui fait tout le mappage des utilisateurs, pas le démon docker. Le root du conteneur est toujours le root de l'hôte.

$UID n'est pas défini par défaut sur les hôtes Ubuntu 16.04. Il serait trivial pour docker-compose d'acquérir l'identifiant de l'utilisateur en l'exécutant et en l'injectant néanmoins. Beaucoup moins de code passe-partout et d'environnement configurés pour les utilisateurs de composition de développement d'applications, ce qui est logique puisque la composition concerne tout docker UX.

+1 pour docker-compose up --user ou utilisateur exécutant ....

Existe-t-il des solutions ou des nouvelles sur ce problème?

Non, et j'ai ouvert cette fonctionnalité contre le moteur docker il y a un certain temps : https://github.com/docker/docker/issues/22415

Je pense qu'il s'agit d'un problème d'impact beaucoup plus important qu'on ne le reconnaît actuellement. Pouvoir modifier quel utilisateur le conteneur touche au système de fichiers sans avoir à informer le conteneur lui-même des systèmes d'autorisations ouvrirait pas mal de portes.

Si c'est quelque chose qui vous intéresse, je vous suggère de partager et de voter pour le ticket que j'ai lié.

cela fonctionne pour moi : user: "1000:1000"

@jovanialferez FYI si vous le codez en dur comme ça, vous rencontrerez des problèmes si d'autres personnes sont impliquées dans le projet dont l'UID et le GID ne sont pas définis sur 1000. Je pense qu'OSX commence à numéroter les utilisateurs réguliers à 500, et tout Linux installer avec plusieurs utilisateurs se retrouverait avec un UID supérieur à 1000.

@jovanialferez qui ne fonctionnera que sur Linux.

c'est noté. merci @nfm @luispabon

Je suis récemment passé de Mac à Linux et je viens d'être touché par cela, je ne comprends pas vraiment comment cela n'est pas encore résolu

Mentionner à nouveau ce problème pour que les nouveaux arrivants le voient : https://github.com/moby/moby/issues/22415

Nous avons vraiment besoin de pouvoir mapper en externe les processus Docker vers un utilisateur spécifique. Accent mis sur l'extérieur . Ne choisissez pas l'UID/GID du processus dans le conteneur. Mais mappez le processus de conteneur sur un UID/GID local depuis l'extérieur.

Oui en effet. L'affectation de l'uid/gid de l'utilisateur actuel dans le conteneur ne fonctionne que sous Linux. Cela ressemble à un problème de docker.

Nous rencontrons un problème un peu plus ésotérique sous Windows. Nous utilisons une instance locale OrientDB, qui écrit les fichiers dans le système de fichiers de l'hôte, et sous Windows, cela ne semble pas le faire. Oh ... peut-être est-ce parce que le volume hôte n'est pas un volume de bloc?

Il y a presque un an, alors que j'essayais de résoudre ce problème, j'ai trouvé ce sujet. Comme aucune solution n'a été fournie à ce moment-là, j'ai créé un tas de scripts bash d'emballage pour exécuter votre docker-compose.

Au bout d'un an, c'est pareil. Je me demande combien de temps il faut pour résoudre un problème aussi simple pour un logiciel comme docker-compose qui n'est même pas un vrai fournisseur mais plutôt un wrapper.

$UID n'est pas exporté sur Linux par défaut, d'accord ? Cela nous empêche de créer un docker-compose universel - ce qui est une chose étrange en soi car ce logiciel est supposé être une solution frontale, n'est-ce pas ?

Si vous n'aimez pas perdre de temps sur des bagatelles - et je comprends cela - alors pourquoi ne nous laissez-vous pas simplement exécuter une commande hôte aléatoire avant d'exécuter un service, hein ? Nous pourrions simplement faire quelque chose comme ceci :

services:
  web:
     ...
     host_command: export UID

N'est-ce pas évident ?

+1

Ce problème n'a pas assez de likes et de +1 et pour moi, c'est un problème négligé mais nécessaire et demandé par de nombreux utilisateurs, y compris moi-même.

Je suis ici pour donner mon +1 aussi parce que ça me touche. Actuellement, je ne veux pas que mes conteneurs s'exécutent en tant que root -encore- je veux qu'ils partagent un volume dans l'hôte qui est accessible en écriture par mon utilisateur. Cela ne peut pas être fait si je ne définis pas l'utilisateur et l'expansion serait le moyen le plus naturel de le faire au lieu de user: 1000:1000 car, comme indiqué précédemment, cela provoquera des conflits avec les utilisateurs d'un autre environnement. $UID, même s'il n'est pas exporté, s'avère être une meilleure solution car il est basé sur l'environnement que sur docker-expose.

Juste mes 2 centimes. Alors, quelqu'un a-t-il trouvé un moyen de le faire de toute façon?

@darkguy2008 - Assurez-vous de mettre celui-ci en avant : https://github.com/moby/moby/issues/22415

Je soupçonne qu'une fonctionnalité sera nécessaire dans le docker lui-même avant que la composition puisse être construite dessus.

Je ne suis pas sûr de comprendre, docker-compose run --user est une option, et le docker-compose.yml prend en charge la clé user (http://docs.docker.com/compose/yml/ #working95dir-entrypoint-user-hostname-domainname-mem95limit-privileged-restart-stdin95open-tty-cpu95shares).

Je suppose que nous aurions besoin de prendre en charge la résolution des variables d'environnement dans le champ user afin que vous puissiez le définir sur $UID , n'est-ce pas ? #1377

Le lien est rompu.

J'ai trouvé que l'ajout d'une variable obligatoire aidait comme solution de contournement :

version: "3"
services:
  testapp:
    image: ubuntu:20.04
    entrypoint: /bin/bash -c "cd $PWD && touch tmp"
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}
    volumes:
      - $PWD:$PWD

Afficherait :

ERROR: Missing mandatory value for "user" option in service "testapp": "Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"

En précisant que le fichier doit être exécuté comme ceci :

CURRENT_UID=$(id -u):$(id -g) docker-compose up

J'ai trouvé que l'ajout d'une variable obligatoire aidait comme solution de contournement :

version: "3"
services:
  testapp:
    image: ubuntu:20.04
    entrypoint: /bin/bash -c "cd $PWD && touch tmp"
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}
    volumes:
      - $PWD:$PWD

Afficherait :

ERROR: Missing mandatory value for "user" option in service "testapp": "Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"

En précisant que le fichier doit être exécuté comme ceci :

CURRENT_UID=$(id -u):$(id -g) docker-compose up

Le problème est que mes services nécessitent un accès root pour démarrer. Par exemple:

app-php-fpm  | [14-Jun-2020 00:15:12] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
app-php-fpm  | [14-Jun-2020 00:15:12] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
app-redis    | 1:M 14 Jun 2020 00:15:12.710 * Ready to accept connections
app-php-fpm  | [14-Jun-2020 00:15:12] ERROR: Unable to create the PID file (/run/php-fpm.pid).: Permission denied (13)
app-php-fpm  | [14-Jun-2020 00:15:12] ERROR: FPM initialization failed
app-webserver exited with code 1
app-mysql exited with code 1
app-php-fpm exited with code 78
Cette page vous a été utile?
0 / 5 - 0 notes