cannot open directory - Stale file handle - docker

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

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

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

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?

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.

Can't Delete file created via Docker

I used a docker image to run a program on our school's server using this command.
docker run -t -i -v /target/new_directory 990210oliver/mycc.docker:v1 /bin/bash
After I ran it it created a firectory on my account called new_directory. Now I don't have permissions to delete or modify the files.
How do I remove this directory?
I also had this problem.
After:
docker run --name jenkins -p 8080:8080 -v $HOME/jenkins:/var/jenkins_home jenkins jenkins
I couldn't remove files in $HOME/jenkins.
Ricardo Branco's answer didn't work for me because chown gave me:
chown: changing ownership of '/var/jenkins_home': Operation not permitted
Solution:
exec /bin/bash into container as a root user:
docker exec -it --privileged --user root container_id /bin/bash
then:
cd /var/jenkins_home/ && rm -r * .*
I made #siulkilulki's answer into one line:
docker exec --privileged --user root <CONTAINER_ID> chown -R "$(id -u):$(id -g)" <TARGET_DIR>
Note that here the CONTAINER must be up.
Change the owner of all the files on the directory to your used ID within the container running as root, then exit the container and remove the directory.
docker run --rm -v /target/new_directory 990210oliver/mycc.docker:v1 chown -R $(id -un):$(id -un) /target/new_directory
exit
rm -rf $HOME/new_directory
I had the same problem. I am using ubuntu 18.04. I ran the following code and then I was able to delete files locally. I have app dir inside docker project dir
cd to your docker project dir
sudo chown -R $(whoami):$(whoami) app/
docker run -v {absolute path to dir with the file}:/to_delete -it ubuntu /bin/bash
Then just:
$ cd to_delete
$ rm -rf <file/dir>
Here is a solution that does not require --privileged.
Game Plan
Determine UIDs of all offending files created by previous docker runs. Use docker to find them, since in-container UID is not the same as host UID. An offending file is any file not owned by container user root which maps to the current user running docker.
Run a container using each discovered UID and delete the offending files (or chown them).
Code
# Assumes that current dir is the volume
# find files owned by docker internal uuids (not root) on the mounted volume:
BAD_FILE_UIDS=$(docker run --rm -v $(pwd):/build alpine sh -c 'find /build -mindepth 1 -not -user root | xargs stat -c "%u" | sort -u')
if [ -n "${BAD_FILE_UIDS}" ] ; then
for uuid in $BAD_FILE_UIDS ; do
echo "Cleaning up files owned by $uuid using docker"
docker run --rm -v $(pwd):/build --user $uuid:0 alpine find /build -mindepth 1 -user $uuid -delete
done
fi
You can change the -delete to -exec chown SOME_USER {} \; to chown.
The above works well for use in CI as post-build cleanup.
Try this:
docker stop $CONTAINER_NAME
docker rm -v $CONTAINER_NAME
I guess this should remove the mounted dir. If it doesn't, do this explicitly:
sudo rm -rf /target/new_directory

Docker user permission while mounting a directory

I am using the following Dockerfile to build Solr using Docker.
FROM solr:5.5
ENV SOLR_HOME=/opt/solr/server/solr/cores
RUN mkdir ${SOLR_HOME}
RUN chown -R solr:solr ${SOLR_HOME}
VOLUME ["${SOLR_HOME}"]
EXPOSE 8983
I try to run the following Docker command to mount a host directory to the container:
docker run --restart=always -d --name solr-demo \
--privileged=true -p 8983:8983 \
-v /data/solr_demo:/opt/solr/server/solr/cores \
solr-test:latest
I am also copying the required solr.xml file into the data/solr_demo. When I run the docker run command I get the following error:
stat: cannot stat ‘/opt/solr/server/solr/cores’: No such file or directory 42146d74b446ba4784fd197688e3210f294aad8755ae730cc559132720bcc35a
Error response from daemon: Container 42146d74b446ba4784fd197688e3210f294aad8755ae730cc559132720bcc35a is restarting, wait until the container is running
From your comment, it appears you're mounting a nonexistent directory for your volume. Try this command that mounts /data/solr_demo1 instead of /data/solr_demo as your volume.
docker run --restart=always -d --name solr-demo \
--privileged=true -p 8983:8983 \
-v /data/solr_demo1:/opt/solr/server/solr/cores \
solr-test:latest
If it is really an user problem (it remind me of some issue I add with apache in container), you should consider using Gosu. https://github.com/tianon/gosu
It will let you run and swap user correctly and have a nice mapping from your local users and users inside the container.
Hope it will be useful.

Resources