The post “Handling Permissions with Docker Volumes” explains clearly the problem: when you run a docker container bound to a directory, all files are accessed/written with the UID of the docker user.
For instance, let us bind our
~/temp directory to the
/data directory inside the container, and create the file
/data/test inside the container with:
docker run -it -v ~/temp:/data ubuntu:16.04 "touch" "/data/test"
ls -lhF ~/temp gives:
-rw-r--r-- 1 root root 0 set 4 19:23 test
because the command touch has been run with UID 0 inside the container. Usually, I want to run a container with my UID, so that running a container is undistinguishable from running any other program. The first element of the solution is the gosu package that must be installed via the Dockerfile command:
RUN apt-get update && apt-get install -y gosu.
The second element is a trivial script gosu.sh that computes the UID and GID of the owner of the /data directory inside the container and runs the program with that UID/GID. The
gosu.sh for our HapCHAT program is:
#!/bin/bash # Add local user # with the same owner as /data USER_ID=$(stat -c %u /data) GROUP_ID=$(stat -c %g /data) echo "Starting with UID:GID $USER_ID:$GROUP_ID" groupadd -g "$GROUP_ID" group useradd --shell /bin/bash -u "$USER_ID" -g group -o -c "" -m user export HOME=/ chown --recursive "$USER_ID":"$GROUP_ID" /HapCHAT exec gosu user "[email protected]"
Copying and running that file is achieved with the following snippet of the Dockerfile
COPY gosu.sh /usr/local/bin/gosu.sh ENTRYPOINT ["/usr/local/bin/gosu.sh"] CMD ["/usr/bin/snakemake"]
We can run a docker container with the unprivileged permissions of our users with a simple script and a change to the Dockerfile. You can find the files at https://github.com/AlgoLab/HapCHAT/tree/master/docker