2
votes

Pourquoi un simple Dockerfile donne-t-il une "autorisation refusée"?

J'apprends à utiliser Docker avec ROS, et je suis surpris par ce message d'erreur:

Step 7/7 : RUN apt-get update
 ---> Running in 95c40d1faadc
Reading package lists...
E: List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)
The command '/bin/sh -c apt-get update' returned a non-zero code: 100

Donne ce message d'erreur

FROM ros:kinetic-robot-xenial

# create non-root user
ENV USERNAME ros
RUN adduser --ingroup sudo --disabled-password --gecos "" --shell /bin/bash --home /home/$USERNAME $USERNAME
RUN bash -c 'echo $USERNAME:ros | chpasswd'
ENV HOME /home/$USERNAME
USER $USERNAME

RUN apt-get update

p>


4 commentaires

Avez-vous essayé "RUN sudo apt ..."?


Curieusement, déplacer le RUN apt-get avant le ENV USERNAME fait disparaître CE problème. Mais je ne sais pas pourquoi.


Mettez dans un "RUN whoami" avant "RUN apt-get ..." pour les deux cas ...


La ligne USER $ USERNAME change l'utilisateur actuel. Après cette ligne, toutes les autres commandes sont exécutées avec les droits de l'utilisateur. Mettre la ligne apt-get RUN avant cette ligne entraîne son exécution en tant que root, ayant ainsi les autorisations appropriées


4 Réponses :


0
votes

Vous ajoutez l'utilisateur ros au groupe sudo mais vous essayez de apt-get update sans utiliser sudo. Par conséquent, vous exécutez la commande sans privilège et vous obtenez la permission refusée .

Utilisez ne lancez la commande (t):

FROM ros:kinetic-robot-xenial

RUN whoami
RUN apt-get update
# create non-root user
RUN apt-get install sudo
RUN echo "ros ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
ENV USERNAME ros 
RUN adduser --ingroup sudo --disabled-password --gecos "" --shell /bin/bash --home /home/$USERNAME $USERNAME
RUN bash -c 'echo $USERNAME:ros | chpasswd'
ENV HOME /home/$USERNAME
USER $USERNAME

RUN whoami
RUN sudo apt-get update

Dans l'ensemble cela n'a pas beaucoup de sens. Il est possible de préparer une image docker (par exemple, installer un logiciel, etc.) avec son utilisateur root. Si vous êtes préoccupé par la sécurité (ce qui est une bonne chose), laissez le contenu sudo et assurez-vous que le ou les processus qui s'exécutent lorsque l'image est exécutée (par exemple, le conteneur est créé) avec votre utilisateur non privilégié ... p >

Pensez également aux constructions en plusieurs étapes si vous souhaitez séparer la préparation de l'image de l'élément exécutable réel:

https://docs.docker.com/develop/develop-images/multistage-build/


0 commentaires

9
votes

apt-get doit généralement s'exécuter en tant que root, mais une fois que vous avez exécuté une commande USER , les commandes ne s'exécutent plus en tant que root.

Vous exécuterez fréquemment des commandes comme celle-ci au démarrage du Dockerfile: vous voulez profiter de la mise en cache de la couche Docker si vous le pouvez, et vous installerez généralement les dépendances dont le reste du Dockerfile a besoin. Aussi pour des raisons de mise en cache des couches, il est important d'exécuter apt-get update et d'autres étapes d'installation en une seule étape. Ainsi, votre Dockerfile ressemblera généralement à

FROM ros:kinetic-robot-xenial
# Still root
RUN apt-get update \
 && apt-get install ...
# Copy in application (still as root, won't be writable by other users)
COPY ...
CMD ["..."]
# Now as the last step create a user and default to running as it
RUN adduser ros
USER ros

Si vous en avez besoin, vous pouvez explicitement USER root pour revenir à la racine pour les commandes suivantes, mais c'est généralement plus faciles à lire et à maintenir les fichiers Docker avec moins de changement d'utilisateur.

Notez également que ni sudo ni les mots de passe utilisateur ne sont vraiment utiles dans Docker. Il est difficile d'exécuter sudo dans un script en général et beaucoup de choses dans Docker se produisent dans les scripts. Les conteneurs n'exécutent presque jamais des éléments tels que getty ou sshd qui pourraient potentiellement accepter les mots de passe des utilisateurs, et ils sont faciles à lire à partir de l ' historique du docker , il est donc inutile d'en définir un. Inversement, si vous êtes en mesure d'obtenir un shell dans un conteneur, vous pouvez toujours passer -u root à docker run ou docker exec code> commande pour obtenir un shell racine.


0 commentaires

1
votes

Essayez de mettre cette ligne à la fin de votre fichier docker

USER $ USERNAME (une fois que cette ligne apparaîtra dans dockerfile ... vous assumerez les autorisations de cet utilisateur ... qui dans ce cas n'a pas besoin d'installer quoi que ce soit) par défaut, vous êtes root


0 commentaires

0
votes

passez à l'utilisateur root en:

USER root

et chaque commande devrait fonctionner


0 commentaires