Docker kind of always had a USER
command to run a process as a specific user, but in general a lot of things had to run as ROOT.
I have seen a lot of images that use an ENTRYPOINT
with gosu
to de-elevate the process to run.
I'm still a bit confused about the need for gosu
. Shouldn't USER be enough?
I know quite a bit has changed in terms of security with Docker 1.10, but I'm still not clear about the recommended way to run a process in a docker container.
Can someone explain when I would use gosu
vs. USER
?
Thanks
EDIT:
The Docker best practice guide is not very clear: It says if the process can run without priviledges, use USER
, if you need sudo, you might want to use gosu
. That is confusing because one can install all sorts of things as ROOT in the Dockerfile
, then create a user and give it proper privileges, then finally switch to that user and run the CMD
as that user. So why would we need sudo or gosu
then?
The gosu utility is often used in scripts called from ENTRYPOINT instructions inside Dockerfiles for official images. It's a very simple utility, similar to sudo, that runs a given instruction as a given user. The difference is that gosu avoids sudo's "strange and often annoying TTY and signal-forwarding behavior".
The ENTRYPOINT instruction looks almost similar to the CMD instruction. However, the main highlighting difference between them is that it will not ignore any of the parameters that you have specified in the Docker run command (CLI parameters).
The Docker daemon always runs as the root user. If you don't want to preface the docker command with sudo , create a Unix group called docker and add users to it.
&& apk add bash tells Docker to install bash into the image. apk stands for Alpine Linux package manager. If you're using a Linux base image in a flavor other than Alpine, then you'd install packages with RUN apt-get instead of apk.
Dockerfiles are for creating images. I see gosu as more useful as part of a container initialization when you can no longer change users between run commands in your Dockerfile.
After the image is created, something like gosu allows you to drop root permissions at the end of your entrypoint inside of a container. You may initially need root access to do some initialization steps (fixing uid's, host mounted volume permissions, etc). Then once initialized, you run the final service without root privileges and as pid 1 to handle signals cleanly.
Edit: Here's a simple example of using gosu in an image for docker and jenkins: https://github.com/bmitch3020/jenkins-docker
The entrypoint.sh looks up the gid of the /var/lib/docker.sock file and updates the gid of the docker user inside the container to match. This allows the image to be ported to other docker hosts where the gid on the host may differ. Changing the group requires root access inside the container. Had I used USER jenkins
in the dockerfile, I would be stuck with the gid of the docker group as defined in the image which wouldn't work if it doesn't match that of the docker host it's running on. But root access can be dropped when running the app which is where gosu comes in.
At the end of the script, the exec call prevents the shell from forking gosu, and instead it replaces pid 1 with that process. Gosu in turn does the same, switching the uid and then exec'ing the jenkins process so that it takes over as pid 1. This allows signals to be handled correctly which would otherwise be ignored by a shell as pid 1.
I am using gosu and entrypoint.sh because I want the user in the container to have the same UID as the user that created the container.
Docker Volumes and Permissions.
The purpose of the container I am creating is for development. I need to build for linux but I still want all the connivence of local (OS X) editing, tools, etc. My keeping the UIDs the same inside and outside the container it keeps the file ownership a lot more sane and prevents some errors (container user cannot edit files in mounted volume, etc)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With