Using docker command (to host) in docker container with non-root user as Jenkinsfile agent
A simple solution
Actually, I believe your first idea for a solution can be achieved easily with docker and without the need to run any Jenkins slave as root.
Consider this command:
docker run --rm -it -v /etc/passwd:/etc/passwd:ro -v /etc/shadow:/etc/shadow:ro -v /etc/group:/etc/group:ro debian:10 /bin/su linux-fan -c /bin/bash
This creates a new container and maps the users from the host into the container. Then, inside that container it drops immediately to user linux-fan
which (only) needs to be defined on the outward system.
Whether you run this command as root
or as any user in the docker
group does not make a difference (note that the comments are very right about docker
group = root access!)
Also, mapping things inside the container this way (already when doing so with the docker socket...) is really giving up most of the isolation that a container provides. It would thus be sensible to consider running whichever command requires access to the host's Docker daemon to run directly on the host or in a less-isolated environment like a chroot
? Of course, the simplicity of invoking Docker may still outweigh the lack of isolation here.
An alternative solution
A solution without host-access could easily work around this: Using docker-in-docker i.e. running a new docker daemon inside the build container instead of accessing the host isolates them from each other such that the host's user and group IDs do not matter.
We use the following solution successfully for over 6 months:
- run
docker
indocker
: use the docker command from your container, and not from the host to avoid dependency hell where you have to mount half of your host system. - make sure that your default user inside your bulid container can run docker (add jenkins user to docker group)
- just mount the docker.sock with permissions for everyone:
-v /var/run/docker.sock:/var/run/docker.sock:rw