24

I use following command to run a docker container, and map a directory from host(/root/database) to container(/tmp/install/database):

# docker run -it --name oracle_install -v /root/database:/tmp/install/database bofm/oracle12c:preinstall bash

But in container, I find I can't use ls to list contents in /tmp/install/database/ though I am root and have all privileges:

[root@77eb235aceac /]# cd /tmp/install/database/
[root@77eb235aceac database]# ls
ls: cannot open directory .: Permission denied
[root@77eb235aceac database]# id
uid=0(root) gid=0(root) groups=0(root)
[root@77eb235aceac database]# cd ..
[root@77eb235aceac install]# ls -alt
......
drwxr-xr-x. 7 root root  4096 Jul  7  2014 database

I check /root/database in host, and all things seem OK:

[root@localhost ~]# ls -lt
......
drwxr-xr-x.  7 root root       4096 Jul  7  2014 database

Why does docker container prompt "Permission denied"?

Update:
The root cause is related to SELinux. Actually, I met similar issue last year.

Community
  • 1
  • 1
Nan Xiao
  • 16,671
  • 18
  • 103
  • 164
  • 2
    Could try by adding `--privileged` to the `docker run` command and tell us if the permission is still denied. Also, could you perform (on the host) `# ls -lh /tmp/install/database` please? – Auzias Feb 25 '16 at 06:39
  • @Auzias: Yes, add `--privileged` works! Thanks! Could you write an answer and explain what is the difference of using this option or not though working as a root user in container? – Nan Xiao Feb 25 '16 at 06:54
  • @Auzias: I update in the `OP`, please check, thanks! – Nan Xiao Feb 25 '16 at 06:57
  • Not really yet as I'm unsure of the reason. could you perform (on the host) `# ls -lh /tmp/install/database` please? (you provided `ls -ldh /root/database` no the /tmp one). Also, is you `/tmp` on a specific device? – Auzias Feb 25 '16 at 06:57
  • @Auzias: There is no `/tmp/install/database` on host, it is in container. – Nan Xiao Feb 25 '16 at 06:59
  • Oh yeah, sorry! Indeed, not fully awoke. is your `/tmp` on a specific device? – Auzias Feb 25 '16 at 07:01
  • @Auzias: No. Just the same hard disk as other directories. I check the `docker run --help`, but the explanation seems a little simple. – Nan Xiao Feb 25 '16 at 07:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/104504/discussion-between-auzias-and-nan-xiao). – Auzias Feb 25 '16 at 07:08

5 Answers5

13

A permission denied within a container for a shared directory could be due to the fact that this shared directory is stored on a device. By default containers cannot access any devices. Adding the option $docker run --privileged allows the container to access all devices and performs Kernel calls. This is not considered as secure.

A cleaner way to share device is to use the option docker run --device=/dev/sdb (if /dev/sdb is the device you want to share).

From the man page:

  --device=[]
      Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)

  --privileged=true|false
      Give extended privileges to this container. The default is false.

      By default, Docker containers are “unprivileged” (=false) and cannot, for example, run a Docker daemon inside the Docker container. This is because by default  a  container is not allowed to access any devices. A “privileged” container is given access to all devices.

      When  the  operator  executes  docker run --privileged, Docker will enable access to all devices on the host as well as set some configuration in AppArmor to allow the container nearly all the same access to the host as processes running outside of a container on the host.
Auzias
  • 3,638
  • 14
  • 36
  • 1
    the root cause has been found: it is caused by `selinux`. Actually, I encountered similar issue about one year ago: [Why does docker prompt “Permission denied” when backing up the data volume?](http://stackoverflow.com/questions/30091681/why-does-docker-prompt-permission-denied-when-backing-up-the-data-volume). – Nan Xiao Feb 26 '16 at 01:54
3

I had a similar issue when sharing an nfs mount point as a volume using docker-compose. I was able to resolve the issue with:

    docker-compose up --force-recreate

Eventhough you found the issue, this may help someone else.

d g
  • 1,594
  • 13
  • 13
3

Another reason is a mismatch with the UID/GID. This often shows up as being able to modify a mount as root but not as the containers user

You can set the UID, so for an ubuntu container running as ubuntu you may need to append :uid=1000 (check with id -u) or set the UID locally depending on your use case.

uid=value and gid=value

Set the owner and group of the files in the filesystem (default: uid=gid=0)

There is a good blog about it here with this tmpfs example

docker run \
       --rm \
       --read-only \
       --tmpfs=/var/run/prosody:uid=100 \
       -it learning/tmpfs

http://www.dendeer.com/post/docker-tmpfs/

KCD
  • 9,873
  • 5
  • 66
  • 75
3

I got answer from a comment under: Why does docker container prompt Permission denied?

man docker-run gives the proper answer:

Labeling systems like SELinux require that proper labels are placed on volume content mounted into a container. Without a label, the security system might prevent the processes running inside the container from using the content. By default, Docker does not change the labels set by the OS.

To change a label in the container context, you can add either of two suffixes :z or :Z to the volume mount. These suffixes tell Docker to relabel file objects on the shared volumes. The z option tells Docker that two containers share the volume content. As a result, Docker labels the content with a shared content label. Shared volume labels allow all containers to read/write content. The Z option tells Docker to label the content with a private unshared label. Only the current container can use a private volume.

For example:

  docker run -it --name oracle_install -v /root/database:/tmp/install/database:z ...
B.Z.
  • 418
  • 5
  • 12
  • If "By default, Docker does not change the labels set by the OS", how can it then be that I can run a certain executable fine on the host, but when mounting the same executable to a Docker container, I get "Permission denied" when running it? (And specifying `:z` *does* fix it.) – sschuberth Oct 31 '21 at 09:41
  • 1
    @sschuberth selinux requires the process label matches the label of the file that it tries to access. Docker running in a different context from host processes, so it has different process label. That's why a process in the host can access an executable, but a process in docker container can't. :z would relabels the file to make sure that docker container can access the file too. – B.Z. Nov 02 '21 at 04:15
0

So I was trying to run a C file using Python os.system in the container but the I was getting the same error my fix was while creating the image add this line RUN chmod -R 777 app it worked for me