How to specify both uid and username on `docker run` command? - docker

To start a docker container with the current user I can call docker run with the --user parameter like
docker run --user $(id -u):$(id -g) myimage
However that leaves the user inside the container without a name which inhibits the execution of some programs. For example it is not possible to mount a directory via fuse as a user without a name.
So what is the preferred approach to specify the UID and the username for a docker run command?
The only workaround I have found so far is to bind-mount /etc/password into the container:
docker run -v /etc/passwd:/etc/passwd:ro --user $(id -u):$(id -g) myimage
but that looks rather ugly to me. Isn't there a better way to do this?

Related

cannot open directory - Stale file handle

I am trying to mount a folder when running a docker image
docker run -it -v ${PWD}:/logs myimage:latest bash
but when I list the mounted directory inside the container the following error occurs:
bash-4.4$ ls /logs
ls: cannot open directory '/logs': Stale file handle
What is missing here?
probably a permission is needed to read/write that folder, try to define a user as the the host user which probably has the permission. --user $(id -u):$(id -g)
docker run -it -v ${PWD}:/logs --user $(id -u):$(id -g) myimage:latest bash

docker all files belong to root

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

Docker: Map external to internal user (howto apply '--user', howte execute .bashrc)?

Running a docker image with a command line such as:
> docker run -it -v $OutsideDir:$InsideDir -u $(id -u):$(id -g) c0ffeebaba bash
I am able to work on my data as the current user on the host from inside the docker container. However, asking inside the container 'whoami' gives the response that the UID is unknown.
So the shell is executed on a user without a home-directory. How
can I get some initialization being done for that user? Is there a way to map the user id and group id of an external user to a specific user name from inside? Can this be done dynamically, so that it would work for any user, specified through the '--user' flag as shown above?
My first approach would have been to use 'CMD' in the Dockerfile such as
CMD ["source", "/home/the_user/.bashrc" ]
But, that does not work.
A relatively simple solution would be to wrap the docker run in a script, mapping in the /etc/passwd and /etc/group files from the host onto the container, as well as the user's home directory, so something like:
#!/bin/bash -p
# command starts with mapping passwd and group files
cmd=(docker run -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro)
# add home directory:
myhome=$(getent passwd $(id -nu) | awk -F: '{print $6}')
cmd+=(-v $myhome:$myhome)
# add userid and groupid mappings:
cmd+=(-u $(id -u):$(id -g))
# then pass through any other arguments:
cmd+=("$#")
"${cmd[#]}"
This can be run as:
./runit.sh -it --rm alpine id
or, for a shell (alpine doesn't have bash by default):
./runit.sh -it --rm centos bash --login
You can throw in a -w $HOME to get it to start in the user's home directory, etc.

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).

Define Docker commands aliases

I several of my projects I am using docker and docker-compose.
It's great, but now many command I am using are very long, like
docker run --rm -it -v $(pwd):/app -u $(id -u):$(id -g) php:7.1 php vendor/bin/phpunit
I would like to use just something like
docker phpunit
providing details in docker-compose or some other configuration file.
Is there a way to define aliases of these commands on a per project basis?
I don't want to use global aliases since such commands can vary for every project.
You could simply add a bash script docker.sh to each one of your projects:
#!/usr/bin/env bash
docker run --rm -it -v $(pwd):/app -u $(id -u):$(id -g) php:7.1 php vendor/bin/phpunit
and run it with ./docker.sh. This is a easy way to customize it considering each particularity and have the command under your version control.

Resources