I am learning to use Docker with ROS, and I am surprised by this error message:
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
Gives this error message
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
apt-get
generally needs to run as root, but once you've run aUSER
command, commands don't run as root any more.You'll frequently run commands like this at the start of the Dockerfile: you want to take advantage of Docker layer caching if you can, and you'll usually be installing dependencies the rest of the Dockerfile needs. Also for layer-caching reasons, it's important to run
apt-get update
and other installation steps in a single step. So your Dockerfile would typically look likeIf you need to, you can explicitly
USER root
to switch back to root for subsequent commands, but it's usually easier to read and maintain Dockerfiles with less user switching.Also note that neither
sudo
nor user passwords are really useful in Docker. It's hard to runsudo
in a script just in general and a lot of Docker things happen in scripts. Containers also almost never run things likegetty
orsshd
that could potentially accept user passwords, and they're trivial to read back fromdocker history
, so there's no point in setting one. Conversely, if you're in a position to get a shell in a container, you can always pass-u root
to thedocker run
ordocker exec
command to get a root shell.Try putting this line at the end of your dockerfile
USER $USERNAME (once this line appears in dockerfile...u will assume this users permissions...which in this case does not have to install anything) by default you are root
You add the user
ros
to the groupsudo
but you try toapt-get update
without making use of sudo. Therefore you run the command unprivileged and you get thepermission denied
.Use do run the command (t):
All in all that does not make much sense. It is OK to prepare a docker image (eg. install software etc.) with its root user. If you are concerned about security (which is a good thing) leave the sudo stuff and make sure that the process(es) that run when the image is executed (eg the container is created) with your unprivileged user...
Also consider multi stage builds if you want to separate the preparation of the image from the actual runnable thing:
https://docs.docker.com/develop/develop-images/multistage-build/