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

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/

Related

How to delete the files generated in the docker container outside the container?

I need to compile some programs using files in a docker container. Once compiled, the container is no longer used.
Therefore I always use the following command. docker run --rm -v my_file:docker_file my_images my_command
But I find that there are always some problems.
For example, take a simple C language program that outputs "hello, world" as an example.
docker run -it --rm -v /home/cuiyujie/workspace/workGem5/gem5/hello.c:/home/cuiyujie/workspace/workGem5/gem5/hello.c -v /home/cuiyujie/workspace/workGem5/gem5/build:/home/cuiyujie/workspace/workGem5/gem5/build gerrie/gem5-bare-env
After entering the container, execute gcc hello.c -o hello, cp hello build.
I found outside the container that the hello file belongs to root.
-rwxr-xr-x 1 root root 16696 2月 23 10:23 hello*
I don't have permission to delete it. what should I do to make it become the permissions of the host user?
If you run your container as your own UID, files created in the host volumes will be owned by your UID. That comes with the disclaimer that your container needs to be designed to run as a user other than root (e.g. not need access to files owned by root inside the container). Here's an example of running as your uid/gid and full access to your home directory using bash on Linux (the $(id -u) expansion may not work in other environments):
docker container run \
-u "$(id -u):$(id -g)" -w "$(pwd)" \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/group:/etc/group:ro \
-v "$HOME:$HOME" \
<your_image>
You can use chown to change the ownership of a file. You'll need permission to run it with sudo though.
$ sudo chown $USER hello
If you also want to change the group of the file to your primary group, you can put a . after the user:
$ sudo chown $USER. hello

Docker Node-Red: Keep installed nodes outside container

I have to install a lot of missing node-red nodes to the container. Keeping the (named) container and running it with docker start works fine.
Now I want to keep the installed nodes in a separate external directory. If I mount /data do an external directory it basically works but doesn't help since the nodes are installed in ~/node_modules. If I try to mount ~/node_modules to an external directory, node-red can't start.
So what can I do to keep the nodes I installed independent of the executed container?
EDIT:
Meanwhile I did run the image as follows:
#!/bin/bash
sudo -E docker run -it --rm -p 1893:1880 -p 11893:11880
\ -e TZ=Europe/Berlin -e NPM_CONFIG_PREFIX=/data/node_modules/
\ -e NODE_PATH=/usr/src/node-red/node_modules:/data/node_modules:/data/node_modules/lib/node_modules
\ --log-driver none --mount type=bind,source="$(pwd)"/data,target=/data
\ --name myNodeRed nodered/node-red
but the additional installed nodes, that are in directory /data/node_modules/lib/node_modules are still not visible.
EDIT 2:
Meanwhile I tried to keep the container. So it became obvious, that nodes installed using npm install -g are fully ignored.
The default user for the Node-RED instance inside the container is not root (as is usual) so you need to make sure any volume you mount on to the /data location is writable by that user. You can do this by passing in the user id to the container to have it match the external user that has write permission to the mount point:
docker run -it --rm -v $(pwd)/data:/data -u $USER -e TZ=Europe/Berlin
\ -p 1893:1880 -p 11893:11880 --log-driver none
\ --name myNodeRed nodered/node-red
Node-RED nodes should not be installed with the -g option, you should use the build in Palette Manager or if you really need to use the command line, run npm install <node-name> in the /data directory inside the container (But you will need to restart the container for the newly installed nodes to be picked up, which is again why you should use the Palette Manager)

Jenkins wrong volume permissions

I have a virtual machine hosting Oracle Linux where I've installed Docker and created containers using a docker-compose file. I placed the jenkins volume under a shared folder but when starting the docker-compose up I got the following error for Jenkins :
jenkins | touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
jenkins | Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
jenkins exited with code 1
Here's the volumes declaration
volumes:
- "/media/sf_devops-workspaces/dev-tools/continuous-integration/jenkins:/var/jenkins_home"
The easy fix it to use the -u parameter. Keep in mind this will run as a root user (uid=0)
docker run -u 0 -d -p 8080:8080 -p 50000:50000 -v /data/jenkins:/var/jenkins_home jenkins/jenkins:lts
As haschibaschi stated your user in the container has different userid:groupid than the user on the host.
To get around this is to start the container without the (problematic) volume mapping, then run bash on the container:
docker run -p 8080:8080 -p 50000:50000 -it jenkins bin/bash
Once inside the container's shell run the id command and you'll get results like:
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)
Exit the container, go to the folder you are trying to map and run:
chown -R 1000:1000 .
With the permissions now matching, you should be able to run the original docker command with the volume mapping.
The problem is, that your user in the container has different userid:groupid as the user on the host.
you have two possibilities:
You can ensure that the user in the container has the same userid:groupid like the user on the host, which has access to the mounted volume. For this you have to adjust the user in the Dockerfile. Create a user in the dockerfile with the same userid:groupid and then switch to this user https://docs.docker.com/engine/reference/builder/#user
You can ensure that the user on the host has the same userid:groupid like the user in the container. For this, enter the container with docker exec -it <container-name> bash and show the user id id -u <username> group id id -G <username>. Change the permissions of the mounted volume to this userid:groupid.
You may be under SELinux. Running the container as privileged solved the issue for me:
sudo docker run --privileged -p 8080:8080 -p 50000:50000 -v /data/jenkins:/var/jenkins_home jenkins/jenkins:lts
From https://docs.docker.com/engine/reference/commandline/run/#full-container-capabilities---privileged:
The --privileged flag gives all capabilities to the container, and it also lifts all the limitations enforced by the device cgroup controller. In other words, the container can then do almost everything that the host can do. This flag exists to allow special use-cases, like running Docker within Docker.
As an update of #Kiem's response, using $UID to ensure container uses the same user id as the host, you can do this:
docker run -u $UID -d -p 8080:8080 -p 50000:50000 -v /data/jenkins:/var/jenkins_home jenkins/jenkins:lts
I had a similar issue with Minikube/Kubernetes just added
securityContext:
fsGroup: 1000
runAsUser: 0
under deployment -> spec -> template -> spec
This error solve using following commnad.
goto your jenkins data mount path : /media
Run following command :
cd /media
sudo chown -R ubuntu:ubuntu sf_devops-workspaces
restart jenkins docker container
docker-compose restart jenkins
Had a similar issue on MacOS, I had installed Jenkins using helm over a Minikube/Kubenetes after many intents I fixed it adding runAsUser: 0 (as root) in the values.yaml I use to deploy jenkins.
master:
usePodSecurityContext: true
runAsUser: 0
fsGroup: 0
Just be careful because that means that you will run all your commands as root.
use this command
$ chmod +757 /home/your-user/your-jenkins-data
first of all you can verify your current user using echo $USER command
and after that you can mention who is the user in the Dockerfile like bellow (in my case user is root)
screenshot
I had same issue it got resolved after disabling the SELINUX.
It's not recommended to disable the SELINUX so install custom semodule and enable it.
It works. Only changing the permissions won't work on CentOS 7.

Docker mounting volume for editing source code

I have docker setup on my Windows system. The source code of the application is available at C:\Application\source location.
I want this information to be available within the docker container so that it is easy to make code changes during development without rebuilding the image.
This is what I tried
docker run -d -P -i -t -p 8083:8080 --name html-app -v /c/Application/source:/usr/src html-app-img:vnode
The image html-app is based on Node JS
Now when I do a docker exec -it html-app /bin/bash , it doesn't show the contents of C:\Application\source there.
I thought that should be available right?
In the Oracle Virtual box, I've shared the folder C:\Application
Is there anything else that I need to do to get this working?
In the Oracle Virtual box, I've shared the folder C:\Application
That is not enough. You need to modify your boot2docker image in order for the TinyCore Linux session to mount the shared path (only C:\Users\<yourlogin> is mounted by default as /c/Users/<yourLogin>)
See "Docker Compose Mount Window Folder"
Edit/create (as root) /mnt/sda1/var/lib/boot2docker/bootlocal.sh, (sda1 may be different for you)
Add:
mkdir -p <local_dir>
mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>
(the mount might need umask option as well)

How to run docker image as a non-root user?

I'm new to docker. When I run a docker images like ubuntu image by using the command,
sudo docker run -i -t ubuntu:14.04
By default, it is entering into the container as root like this.
I searched regarding this, but I couldn't get any of how to start a docker image as a non root user as I'm completely a starter for this topic.
It would be great if someone explains with an example of how to run a docker image as a non root user.
the docker run command has the -u parameter to allow you to specify a different user. In your case, and assuming you have a user named foo in your docker image, you could run:
sudo docker run -i -t -u foo ubuntu:14.04 /bin/bash
NOTE: The -u parameter is the equivalent of the USER instruction for Dockerfile.
This is admittedly hacky, but good for those quick little containers you start just to test something quickly:
#!/bin/bash
set -eu
NAME=$1
IMG=$2
#UID=$(id -u)
USER=$(id -un)
GID=$(id -g)
GROUP=$(id -gn)
docker run -d -v /tmp:/tmp -v "/home/$USER:/home/$USER" -h "$NAME" --name "$NAME" "$IMG" /bin/bash
docker exec "$NAME" /bin/bash -c "groupadd -g $GID $GROUP && useradd -M -s /bin/bash -g $GID -u $UID $USER"
Full version of the script I use here:
https://github.com/ericcurtin/staging/blob/master/d-run
udocker is a basic variant of docker which runs in user space:
udocker is a basic user tool to execute simple docker containers in user space without requiring root privileges. Enables download and execution of docker containers by non-privileged users in Linux systems where docker is not available. It can be used to pull and execute docker containers in Linux batch systems and interactive clusters that are managed by other entities such as grid infrastructures or externally managed batch or interactive systems.
It is not advisable to allow running docker without sudo as Docker has no auditing or logging built in, while sudo does.
If you want to give docker access to non-root users Red Hat recommends setting up sudo.
Add an entry like the following to /etc/sudoers.
dwalsh ALL=(ALL) NOPASSWD: /usr/bin/docker
Now, set up an alias in ~/.bashrc for running the docker command:
alias docker="sudo /usr/bin/docker"
Now when the user executes the docker command as non-root it will be allowed and get proper logging.
docker run -ti --privileged -v /:/host fedora chroot /host
Look at the journal or /var/log/messages.
journalctl -b | grep docker.*privileged
Aug 04 09:02:56 dhcp-10-19-62-196.boston.devel.redhat.com sudo[23422]: dwalsh : TTY=pts/3 ; PWD=/home/dwalsh/docker/src/github.com/docker/docker ; USER=root ; COMMAND=/usr/bin/docker run -ti --privileged -v /:/host fedora chroot /host

Resources