Reputation: 15760
I have a web application running in a Docker container. This application needs to access some files on our corporate file server (Windows Server with an Active Directory domain controller). The files I'm trying to access are image files created for our clients and the web application displays them as part of the client's portfolio.
On my development machine I have the appropriate folders mounted via entries in /etc/fstab
and the host mount points are mounted in the Docker container via the --volume
argument. This works perfectly.
Now I'm trying to put together a production container which will be run on a different server and which doesn't rely on the CIFS share being mounted on the host. So I tried to add the appropriate entries to the /etc/fstab
file in the container & mounting them with mount -a
. I get mount error(13): Permission denied
.
A little research online led me to this article about Docker security. If I'm reading this correctly, it appears that Docker explicitly denies the ability to mount filesystems within a container. I tried mounting the shares read-only, but this (unsurprisingly) also failed.
So, I have two questions:
Am I correct in understanding that Docker prevents any use of mount
inside containers?
Can anyone think of another way to accomplish this without mounting a CIFS share on the host and then mounting the host folder in the Docker container?
Upvotes: 79
Views: 175300
Reputation: 24483
Yes, Docker is preventing you from mounting a remote volume inside the container as a security measure. If you trust your images and the people who run them, then you can use the --privileged
flag with docker run
to disable these security measures.
Further, you can combine --cap-add
and --cap-drop
to give the container only the capabilities that it actually needs. (See documentation) The SYS_ADMIN
capability is the one that grants mount privileges.
Upvotes: 64
Reputation: 9843
Do not make your containers less secure by exposing many ports just to mount a share. Or by running it as --privileged
Here is how I solved this issue:
sudo mount -t cifs -o username=YourUserName,uid=$(id -u),gid=$(id -g) //SERVER/share ~/WinShare
Change the username, SERVER and WinShare here. This will ask your sudo password, then it will ask password for the remote share.
Let's assume you created WinShare
folder inside your home folder. After running this command you should be able to see all the shared folders and files in WinShare
folder. In addition to that since you use the uid
and gid
tags you will have write access without using sudo all the time.
-v
tag and share a volume between the server and the container.Let's say you ran it like the following.
docker run -d --name mycontainer -v /home/WinShare:/home 2d244422164
You should be able to access the windows share and modify it from your container now.
To test it just do:
docker exec -it yourRunningContainer /bin/bash
cd /Home
touch testdocfromcontainer.txt
You should see testdocfromcontainer.txt
in the windows share.
Upvotes: 6
Reputation: 628
You can use a Netshare docker volume plugin which allows to mount remote CIFS/Samba as volumes.
Upvotes: 4
Reputation: 27320
You could use the smbclient
command (part of the Samba package) to access the SMB/CIFS server from within the Docker container without mounting it, in the same way that you might use curl
to download or upload a file.
There is a question on StackExchange Unix that deals with this, but in short:
smbclient //server/share -c 'cd /path/to/file; put myfile'
For multiple files there is the -T
option which can create or extract .tar
archives, however this looks like it would be a two step process (one to create the .tar
and then another to extract it locally). I'm not sure whether you could use a pipe to do it in one step.
Upvotes: 18
Reputation: 15769
https://github.com/docker/docker/issues/22197
according to which adding
--cap-add SYS_ADMIN --cap-add DAC_READ_SEARCH
to the run options will make mount -t cifs operational.
I tried it out and:
mount -t cifs //<host>/<path> /<localpath> -o user=<user>,password=<user>
within the container then works
Upvotes: 34