docker all files belong to root - docker

I recently started using docker on Ubuntu 16.04.
The problem I encounter is that everytime I run any script inside docker, all new files (which docker creates) have the root:root permissions.
I have read that this is a common issue, but I cannot find a proper solution for this problem (ideally the files created by docker would have my 'local machine' user's permissions.
Is there any way to achieve this? Or should I run chown / chmod after each docker creates new files?

Just use the --user flag. If you know your UID and UID you can use it directly:
docker run --user 1000:1001 image
Or you can let your shell to evaluate it:
docker run --user $(id -u):$(id -g) image

Related

Userid and Group id in docker run command

When do we need to add -u $(id -u):$(id -g) in docker run command?
I see that it is user id and group ip mapping but I want to understand this better.
One reason you'd want to run the container under the same UID and GID as your user is so that any files created by the container in the host file system will be owned by you.
Take for instance this command, that creates a file called test.txt in the current directory on the host
docker run --rm -v $(pwd):/app ubuntu touch /app/test.txt
In the host file system, that file will be owned by root.
By running the container with the same UID and GID as your user, the file will be owned by you instead
docker run --rm -v $(pwd):/app -u $(id -u):$(id -g) ubuntu touch /app/test2.txt
Brief docker background
Docker starts containers as a root user. The root user has almost full privileged access to the state of the container. Any processes running as that user inherit those permissions.
When do we need user and group?
It follows that if there’s a bug in one of those processes, it might damage the container. There are ways to limit the damage, but the most effective way to prevent these types of issues is not to use the root user. So we use the group and user.
RUN groupadd -r -g 2200 example && useradd -rM -g example -u 2200 example
Docker supports isolating the USR namespace. By default, user and group IDs inside a container are equivalent to the same IDs on the host machine. When the user namespace is enabled, user and group IDs in the container are remapped to IDs that do not exist on the host.
Hope this helps you!

Docker run changes the permission of the folder on the host machine

I have a path in my host /Users/bhav/workspace. I am the owner of it as well.
I run docker command as follows (as root user)
docker run -t -d -u root -w /Users/bhav/workspace -v /Users/bhav/workspace:/Users/bhav/workspacerw,z -v /Users/bhav/workspace#tmp:/Users/bhav/workspace#tmp:rw,z 7ff0d5f7b0ce
After i exit my container,
the permission of my workspace folder has changed to 'root'.
How to avoid/rectify this.
When you do -u root in your docker run, you are telling the container to run as root.
Instead, try -u $(id -u):$(id -g) to have the container run as your user.
Unfortunately this might not work if your image is not setup to run as different users, but often it will work (and if it's your own image, you can adjust things accordingly).
Longer version: https://pythonspeed.com/articles/containers-filesystem-data-processing/

docker how to handle permissions for jupyter notebook - 3 approaches that do not work

What is the best practice for handling uid/gid and permissions with jupyter notebooks in docker?
When one of the jupyter+python Dockerfiles in jupyter/docker-stack is run, a notebook gets saved with uid/gid 1000:100. This will fail if a mounted host folder is not writable by "other", which is an ugly approach.
The notebook image can be run specifying the NB_UID and NB_GID, like this:
docker run -p 8888:8888 -it --rm \
-e NB_UID=$(id -u) \
-e NB_GID=$(id -g) \
-e GRANT_SUDO=yes \
--user root \
--mount type=bind,source="$(pwd)",target=/home/jovyan/work \
myimage
In this case, the uid/gid of joyvan in the container match my uid/gid, so there is no permissions problem writing to a mounted folder. However, now jovyan (the container user) cannot access /opt/conda, which is owned by 1000:100 and is not readable by other. So all the add-on packages cannot be loaded!
We could also run docker build with --build-arg myuid=$(id -u) --build-arg mygid=$(id -g)
I believe this would result in both /home/jovyan and /opt/conda being owned by the same uid:gid as me, everything good. However, the resulting image can be used only by me. If I give it to my collaborators (who has a different UID), it will not work.
So it seems that every possibility is blocked or a poor choice. File permissions in docker are difficult.
Can anyone share the best approach for this problem?
The best practise with Jupyter Notebook is to use your own user id and group id so the new files you create will have correct ownership. Then use --group-add users to add yourself to users group to get access to the required folders (e.g. /opt/conda).
The full command would be:
docker run -it --rm --user $(id -u):$(id -g) --group-add users -v "$(pwd)":/home/jovyan -p 8888:8888 jupyter/scipy-notebook
I encountered the same problem and found a good solution which is referred from here.
COPY --chown=1000:100 hostfolder/* /home/$NB_USER/work/
Note that environment or argument expansion in command options is not implemented yet, thus following line would cause build error failed to build: unable to convert uid/gid chown string to host mapping: can't find uid for user $NB_UID: no such user: $NB_UID
# COPY --chown=$NB_USER:$NB_GID hostfolder/* /home/$NB_USER/work/
Therefore, need to hard code the user(jovyan) and group name(users) or id(1000:100).

Mounted folder created as root instead of current user in Docker

trying to mount a volume to my container from the docker run command.
It seems like the folder is always created as root instead of the container user. This makes it so that I'm lacking rights on the folder(cant create or write files for logging).
Doing some testing using this command:
docker run -it --entrypoint /bin/bash -v $PWD/logs:/home/jboss/myhub/logs:rw myImage:latest
If i now do the command: ls -ld /logs i get the result: drwxr-xr-x 2 root root 4096 Jun 12 13:01 logs/
Here we can see that only the owner has write-rights. And root is the owner.
I would expect(I want) jboss to be the owner of this folder. Or at least that all users have read/write rights given the :rw option in the -v parameter
What am I not understanding here? How can i get it to work like I want?
At the moment, this is a recurring issue with no simple answer.
There are two common approaches I hear of.
First involves chowning the directory before using it.
RUN mkdir -p /home/jboss/myhub/logs ; chown -R jboss:jboss /home/jboss/myhub/logs
USER jboss
In case you need to access the files from your host system with a different user, you can chmod files that your app created inside the container with your jboss user.
$ chmod -R +rw /home/jboss/myhub/logs
The second approach, involves creating the files with appropriate chmod in Dockerfile (or in your host system) before running your application.
$ touch /home/jboss/myhub/logs/app-log.txt
$ touch /home/jboss/myhub/logs/error-log.txt
$ chmod 766 /home/jboss/myhub/logs/app-log.txt
$ chmod 766 /home/jboss/myhub/logs/error-log.txt
There certainly are more ways to achieve this, but I haven't yet heard of any more "native" solutions.
I'd like to find out an easier/more practical approach.
#trust512 has identified the problem correctly and also correctly stated that there are no universally agreed upon "good solutions" to the problem. #trust512 has provided 2 kludgy solutions.
My solutions is not better - just an alternative.
Mount the parent of the volume you are interested in.
For example '/home/user' should be owned by user, but if I create a volume
docker volume create myhome
and mount it like
docker container run --mount type=volume,source=myhome,destination=/home/user ...
then /home/user will be owned by root.
However, if I do it like
docker volume create myhome &&
docker container run --mount type=volume,source=myhome,destination=/home alpine:3.4 mkdir /home/user &&
docker container run --mount type=volume,source=myhome,destination=/home alpine:3.4 chown 1000:1000 /home/user
then when I run
docker container run --mount type=volume,source=myhome,destination=/home ...
then /home/user will have the appropriate owner.

Why did my Docker Container did not work when the container UID is missing on the host?

I have created a docker image for running a wildfly server. In the docker image I define a separate user called 'imixs'. This user is running the service (wildfly server) inside the container.
As I have seen in several examples I created my service user with UID 1000.
RUN groupadd -r imixs -g 1000 && useradd -u 1000 -r -g imixs -m -d /home/imixs -s /sbin/nologin -c "imixs user" imixs && \
chmod 755 /opt
Now I have the situation, that on a Host, where this UID is missing, the container can not be executed correctly, because the service (wildfly) claims about missing write permissions.
Is it recommended to start the container in this case with the option -u to run the container with a different user from the host system?
docker run ... -u myuser ....
How can I tell docker-compose to run the containers with a different user from the host system?
Is it in general recommended to create images with users others then root?
My dokerfile can be seen here: https://hub.docker.com/r/imixs/wildfly/~/dockerfile/
I think I must withdraw my own question. I solved this behavior after upgrading from docker version 1.6 to the current release 1.13.0 and upgrading docker-compose form 1.5 to 1.10.0.
Maybe there was something wrong in general with my old installation and reinstalling fixed this problem.
In any case I can confirm that there is no read/write permission issue if the container runs a service with a non-privileged-user, not defined by the host system.
To answer my own questions:
Yes it is recommended to run services in a container with a non-privileged-user other than root (uid 0)
I still did not know if docker-compose can change the user to be used to run a specific container
No it is not recommended to create images running with root user

Resources