Après nouvelles de Shocker d'hier , il semble que les applications d'un conteneur Docker ne doivent pas être exécutées en tant que root. J'ai essayé de mettre à jour mon Dockerfile
pour créer un utilisateur d'application, mais la modification des autorisations sur les fichiers d'application (tout en restant root) ne semble pas fonctionner. J'imagine que c'est parce que certaines autorisations LXC ne sont peut-être pas accordées à l'utilisateur root.
Voici mon Dockerfile:
# Node.js app Docker file
FROM dockerfile/nodejs
MAINTAINER Thom Nichols "[email protected]"
RUN useradd -ms /bin/bash node
ADD . /data
# This next line doesn't seem to have any effect:
RUN chown -R node /data
ENV HOME /home/node
USER node
RUN cd /data && npm install
EXPOSE 8888
WORKDIR /data
CMD ["npm", "start"]
Assez simple, mais quand je ls -l
tout est toujours la propriété de root:
[ node@ed7ae33e76e1:/data {docker-nonroot-user} ]$ ls -l /data
total 64K
-rw-r--r-- 1 root root 383 Jun 18 20:32 Dockerfile
-rw-r--r-- 1 root root 862 Jun 18 16:23 Gruntfile.js
-rw-r--r-- 1 root root 1.2K Jun 18 15:48 README.md
drwxr-xr-x 4 root root 4.0K May 30 14:24 assets/
-rw-r--r-- 1 root root 416 Jun 3 14:22 bower.json
-rw-r--r-- 1 root root 930 May 30 01:50 config.js
drwxr-xr-x 4 root root 4.0K Jun 18 16:08 lib/
drwxr-xr-x 42 root root 4.0K Jun 18 16:04 node_modules/
-rw-r--r-- 1 root root 2.0K Jun 18 16:04 package.json
-rw-r--r-- 1 root root 118 May 30 18:35 server.js
drwxr-xr-x 3 root root 4.0K May 30 02:17 static/
drwxr-xr-x 3 root root 4.0K Jun 18 20:13 test/
drwxr-xr-x 3 root root 4.0K Jun 3 17:38 views/
Mon fichier docker mis à jour fonctionne très bien grâce à la clarification de @ creak sur le fonctionnement des volumes. Une fois que les fichiers initiaux sont chown
ed, npm install
est exécuté en tant qu'utilisateur non root. Et grâce à un hook postinstall
, npm exécute bower install && grunt assets
qui prend en charge les étapes d’installation restantes et évite le besoin de npm install -g
tous les outils de nœud tels que bower, grunt ou coffeescript.
Celui-ci est un peu délicat, il est en fait dû à l'image à partir de laquelle vous partez.
Si vous regardez la source , vous remarquerez que /data/
est un volume. Ainsi, tout ce que vous ferez dans Dockerfile
sera ignoré et remplacé au moment de l’exécution par le volume monté à ce moment-là.
Vous pouvez chown à l'exécution en modifiant votre CMD en quelque chose comme CMD chown -R node /data && npm start
.
Consultez ce message: http://www.yegor256.com/2014/08/29/docker-non-root.html In rultor.com nous exécutons toutes les versions leurs propres conteneurs Docker. Et chaque fois avant d'exécuter les scripts à l'intérieur du conteneur, nous basculons vers un utilisateur non root. C'est ainsi:
adduser --disabled-password --gecos '' r
adduser r Sudo
echo '%Sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
su -m r -c /home/r/script.sh
r
est l'utilisateur que nous utilisons.
Mise à jour 2015-09-28
J'ai remarqué que ce message suscitait un peu d'attention. Un mot de conseil pour quiconque est potentiellement intéressé à faire quelque chose comme ça. J'essayais d'utiliser Python ou une autre langue comme enveloppe pour vos exécutions de script. Lors de l'exécution de scripts bash natifs, je rencontrais des problèmes lorsque j'essayais de transmettre divers arguments à mes conteneurs. Plus précisément, il y avait des problèmes avec l'interprétation/échappement de "et" caractères par le shell.
J'avais besoin de changer d'utilisateur pour une raison légèrement différente.
J'ai créé un image de menu fixe contenant une installation complète de ImageMagick et Ffmpeg avec le désir de pouvoir effectuer des transformations sur les images/vidéos de mon hôte. OS. Mon problème était qu’il s’agissait d’outils de ligne de commande. Il est donc légèrement plus délicat de les exécuter via docker, puis d’obtenir les résultats dans l’OS hôte. J'ai réussi à permettre cela en montant un volume de menu fixe. Cela semblait fonctionner correctement, sauf que la sortie image/vidéo sortait comme étant la propriété de root (c'est-à-dire l'utilisateur sous lequel le conteneur docker était exécuté) plutôt que l'utilisateur qui a exécuté la commande.
J'ai regardé l'approche que @ François Zaninotto a mentionnée dans son réponse (vous pouvez voir l'intégralité du script de création ici ). C’était vraiment cool, mais j’ai préféré l’option de créer un script bash Shell que je voudrais ensuite enregistrer sur mon chemin. J'ai repris certains concepts de l'approche Makefile (en particulier la création d'utilisateurs/de groupes), puis j'ai créé le script Shell.
Voici un exemple de mon --- dockermagick script shell:
#!/bin/bash
### VARIABLES
DOCKER_IMAGE='acleancoder/imagemagick-full:latest'
CONTAINER_USERNAME='dummy'
CONTAINER_GROUPNAME='dummy'
HOMEDIR='/home/'$CONTAINER_USERNAME
GROUP_ID=$(id -g)
USER_ID=$(id -u)
### FUNCTIONS
create_user_cmd()
{
echo \
groupadd -f -g $GROUP_ID $CONTAINER_GROUPNAME '&&' \
useradd -u $USER_ID -g $CONTAINER_GROUPNAME $CONTAINER_USERNAME '&&' \
mkdir --parent $HOMEDIR '&&' \
chown -R $CONTAINER_USERNAME:$CONTAINER_GROUPNAME $HOMEDIR
}
execute_as_cmd()
{
echo \
Sudo -u $CONTAINER_USERNAME HOME=$HOMEDIR
}
full_container_cmd()
{
echo "'$(create_user_cmd) && $(execute_as_cmd) $@'"
}
### MAIN
eval docker run \
--rm=true \
-a stdout \
-v $(pwd):$HOMEDIR \
-w $HOMEDIR \
$DOCKER_IMAGE \
/bin/bash -ci $(full_container_cmd $@)
Ce script est lié à l'image 'acleancoder/imagemagick-full', mais vous pouvez le modifier en modifiant la variable en haut du script.
Ce qu'il fait fondamentalement est:
Je peux maintenant exécuter les commandes ImageMagick/Ffmpeg sur les fichiers de mon système d'exploitation hôte. Par exemple, disons que je veux convertir une image MyImage.jpeg en un fichier PNG , je pourrais maintenant procéder comme suit:
$ cd ~/MyImages
$ ls
MyImage.jpeg
$ dockermagick convert MyImage.jpeg Foo.png
$ ls
Foo.png MyImage.jpeg
J'ai également attaché à la 'stdout' afin que je puisse exécuter la commande ImageMagick identifier pour obtenir des informations sur une image sur mon hôte, par exemple:
$ dockermagick identify MyImage.jpeg
MyImage.jpeg JPEG 640x426 640x426+0+0 8-bit DirectClass 78.6KB 0.000u 0:00.000
Il y a des dangers évidents à monter dans le répertoire courant et à permettre la transmission de toute définition de commande arbitraire pour exécution. Mais il y a aussi beaucoup de façons de rendre le script plus sûr. J'exécute ceci dans mon propre environnement personnel non productif, donc ce n'est pas une préoccupation majeure pour moi. Mais je vous recommande vivement de prendre en compte les dangers si vous choisissez de développer ce script. Cela vaut également la peine de mentionner que ce script ne prend pas en compte un hôte OS X. Le make file à qui je dérobe des idées/concepts en tient compte, vous pouvez donc étendre ce script pour le faire.
Une autre limitation à noter est que je ne peux me référer qu'aux fichiers se trouvant actuellement dans le chemin pour lequel j'exécute le script. En raison de la façon dont je monte les volumes, les éléments suivants ne fonctionneraient pas:
$ cd ~/MyImages
$ ls
MyImage.jpeg
$ dockermagick convert ~/DifferentDirectory/AnotherImage.jpeg Foo.png
$ ls
MyImage.jpeg
Il vaut mieux simplement aller dans le répertoire contenant l'image et l'exécuter directement. Bien sûr, je suis sûr qu'il existe des moyens de contourner cette limitation également, mais pour moi et mes besoins actuels, cela ira.
Note: Je réponds ici car, étant donné le titre générique, cette question apparaît dans Google lorsque vous recherchez une solution pour "Exécuter l'application dans Docker en tant qu'utilisateur non root. utilisateur". J'espère que cela aidera ceux qui sont coincés ici.
Avec Alpine Linux, vous pouvez créer un utilisateur système comme ceci:
RUN adduser -D -H -S -s /bin/false -u 1000 myuser
Tout ce qui se trouve dans Dockerfile
après que cette ligne a été exécutée avec myuser
.
myuser
utilisateur a:
C'est de la part de adduser --help
:
-h DIR Home directory
-g GECOS GECOS field
-s Shell Login Shell
-G GRP Add user to existing group
-S Create a system user
-D Don't assign a password
-H Don't create home directory
-u UID User id
-k SKEL Skeleton directory (/etc/skel)
Remarque : Cette réponse est donnée car beaucoup de personnes recherchant une utilisation non root se retrouveront ici. Attention, cela ne résout pas le problème qui a provoqué le problème, mais aborde le titre et clarifie une réponse donnée par @ yegor256, qui utilise un utilisateur non root dans le conteneur. Cette réponse explique comment faire cela pour un cas d'utilisation non-debian/non-ubuntu. Cela ne résout pas le problème des volumes.
Sur les systèmes Red Hat, tels que Fedora et CentOS, cela peut être effectué de la manière suivante:
RUN adduser user && \
echo "user ALL=(root) NOPASSWD:ALL" | tee -a /etc/sudoers.d/user && \
chmod 0440 /etc/sudoers.d/user
Dans votre fichier Docker, vous pouvez exécuter des commandes avec cet utilisateur en procédant comme suit:
RUN su - user -c "echo Hello $HOME"
Et la commande peut être exécutée en tant que:
CMD ["su","-","user","-c","/bin/bash"]
Un exemple de ceci peut être trouvé ici: https://github.com/gbraad/docker-dev/commit/644c51002f4b8e6fe5bb745638542a4c3d908b16