Docker mount CIFS in run command - docker

I want to mount a CIFS share for my docker container to use. This already worked by explicitly creating a docker volume like so:
docker volume create --driver local --opt type=cifs --opt o=vers=2.0,username=xxxx,password=xxxx --opt device=//servername/Documents Documents
docker run -i --rm -v Documents:/mnt busybox ls -l /mnt
however I want to prevent that I have to create explicit volumes. As it has worked similarly for NFS volumes I now want to mount the volume in the docker run command directly:
docker run -i --rm --mount type=volume,volume-driver=local,dst=/mnt,volume-opt=type=cifs,volume-opt=o=vers=2.0,volume-opt=o=username=xxxx,volume-opt=device=//servername/Documents busybox ls -l /mnt
Here I am getting 'permission denied' errors, which is obvious as I have not used the password. How can I specify the password? All my attempts writing something produced different error messages.
docker run -i --rm --mount type=volume,volume-driver=local,dst=/mnt,volume-opt=type=cifs,volume-opt=o=vers=2.0,volume-opt=o=username=xxxx,password=xxxx,volume-opt=device=//servername/Documents busybox ls -l /mnt
gives me unexpected key 'password' in 'password=xxxx'
docker run -i --rm --mount type=volume,volume-driver=local,dst=/mnt,volume-opt=type=cifs,volume-opt=o=vers=2.0,volume-opt=o=username=xxxx,volume-opt=o=password=xxxx,volume-opt=device=//servername/Documents busybox ls -l /mnt
gives me password=xxxx: invalid argument.
My feeling is I need to somehow escape the comma but do not know how.

Related

How to mount a samba directory in docker container from a windows host?

I'm using docker v20.10.17 in a windows system. I'd like to run a container (jupyterhub/jupyterhub) and mount a directory into it to share data (for all users with write permission inside the container system).
The shared directory is from another NAS (//192.168.1.5/folder/shared_data), which can be opened properly from the host system. I followed the Create CIFS/Samba volumes instruction here to create a samba volume first:
PS C:\Users\Administrator> docker volume create \
--driver local \
--opt type=cifs \
--opt device=//192.168.1.5/folder/shared_data \
--opt o=addr=192.168.1.5,username=myusername,password=mypassword,file_mode=0777,dir_mode=0777 \
--name cif-volume
Which successfully created a volume named cif-volume. Then:
PS C:\Users\Administrator>docker run --rm -it -p 18000:8000 \
--name jhubcontainer \
--cap-add SYS_ADMIN \
--cap-add DAC_READ_SEARCH \
--privileged \
-v cif-volume:/etc/skel/shared_data jupyterhub-image
And I got error message like this:
docker: Error response from daemon: failed to mount local volume: mount //192.168.1.5/folder/shared_data:/var/lib/docker/volumes/cif-volume/_data, data: username=myusername,password=mypassword,file_mode=0777,dir_mode=0777: operation not supported.
See 'docker run --help'.
Need help with this.
Update 2022/11/03 with updated message:
I tried to update my command based on the help of Slava Kuravsky, but still got errors. Within the previous question, I used a pseudo address and username. I'll paste the exact command I used with the real address and username, without any modifications.
PS C:\Users\Administrator> docker volume create --driver local --opt type=cifs --opt device="//172.16.90.50/public/shared_data" --opt o=addr=172.16.90.50,username=212,password=ziyuan,file_mode=0777,dir_mode=0777,vers=2.0 --name cif-volume
cif-volume
PS C:\Users\Administrator> docker run -it --rm -p 18000:8000 --name jhubcontainer -v cif-volume:/etc/skel/shared_data jupyterhub-20221021-mountsmb
docker: Error response from daemon: failed to mount local volume: mount //172.16.90.50/public/shared_data:/var/lib/docker/volumes/cif-volume/_data, data: addr=172.16.90.50,username=212,password=ziyuan,file_mode=0777,dir_mode=0777,vers=2.0: invalid argument.
See 'docker run --help'.
PS C:\Users\Administrator>
The docker image is "jupyterhub/jupyterhub", and "jupyterhub-20221021-mountsmb" is a backup after installed some other python packages and configures.
To make sure the address is accessable, I tried:
PS C:\Users\Administrator> net use m: \\172.16.90.50\public\shared /user:212 ziyuan
命令成功完成。
The printout "命令成功完成" means "Command succeed". And I can see my mounted driver "M:" in explorer
Add the cifs version to the volume options: vers=2.0
docker volume create \
--driver local \
--opt type=cifs \
--opt device=//192.168.1.5/folder/shared_data \
--opt o=addr=192.168.1.5,username=myusername,password=mypassword,file_mode=0777,dir_mode=0777,vers=2.0 \
--name cif-volume
Worked for me without any additional privileges and capabilities
docker run -it --rm --name cifs -v cif-volume:/mnt ubuntu:latest ls /mnt

delete docker volume does not remvoe the local file

I run a docker container of nginx with the following: docker container run -d --name nginx3 -p 85:80 -v $(pwd):/usr/share/nginx/html nginx , then when I add files in the container volume (/usr/share/nginx/html) they are also added locally on the $pwd folder.
But when I remove the container, image, and volume with docker rm -vf $(docker ps -aq) && docker rmi -f $(docker images -aq) && docker volume prune the files on my local $pwd folder are still there.. why were they not deleted when I removed the volume?
That's because docker volume prune delete the docker volumes and not the mounted volumes from the host.
If you define a volume with docker volume create nginx_volume and then use
docker container run -d --name nginx3 -p 85:80 -v nginx_volume:/usr/share/nginx/html nginx
the volume will be deleted
You are not using a docker volume, you are using a bind mount. This was not that clear with the -v syntax, that's why docker recommends the new --mount syntax for new users:
This creates a bind mount from the host OS. Docker is not owner of it and therefore not deleting the folder if you unmount the binding.
docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
Further reading
This creates a docker volume, which is managed by docker. And therefore all volume-commands can be applied:
docker run -d \
--name devtest \
--mount source=myvol2,target=/app \
nginx:latest
Further reading

invalid argument for "--mount" flag: unexpected key 'addr'

I want to use docker nfs volume.
What I have tried:
1. Create a volume first then use it, it's OK
docker volume create --driver local --opt type=nfs --opt o=nfsvers=4,addr=10.192.244.109 --opt device=:/var/lib/lava/dispatcher/tmp my1
docker run -it --rm --name nfs-test -v my1:/data alpine sh
2. Directly use volume when docker run, it's also OK
docker run -it --rm --name nfs-test --mount type=volume,volume-driver=local,dst=/data,volume-opt=type=nfs,volume-opt=device=:/var/lib/lava/dispatcher/tmp,"volume-opt=o=addr=10.192.244.109" alpine sh
The problem happens when I want to specify nfsvers=4 in docker run:
# docker run -it --rm --name nfs-test --mount type=volume,volume-driver=local,dst=/data,volume-opt=type=nfs,volume-opt=device=:/var/lib/lava/dispatcher/tmp,"volume-opt=o=nfsvers=4,addr=10.192.244.109" alpine sh
invalid argument "type=volume,volume-driver=local,dst=/data,volume-opt=type=nfs,volume-opt=device=:/var/lib/lava/dispatcher/tmp,volume-opt=o=nfsvers=4,addr=10.192.244.109" for "--mount" flag: unexpected key 'addr' in 'addr=10.192.244.109'
See 'docker run --help'.
You could see Item1 shows we could specify nfs version when use nfs volume, while Item2 shows we could directly use nfs volume within docker run without pre-create a volume.
But, how I could specify nfs version when directly use docker run? What's the correct format here?
This works for me:
--mount 'type=volume,dst=/data,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/lib/lava/dispatcher/tmp,"volume-opt=o=addr=10.192.244.109,rw,nfsvers=4"'
Seems like the argument parser is picky with the quotes.
It is parsed as an extra argument then.
Alternately you can use
..,volume-opt=o=nfsvers=4,volume-opt=o=addr=10.192.244.109

How to mount gluster volume to host folder in docker?

I have ran my docker container like this:
docker run -v /sys/fs/cgroup:/sys/fs/cgroup -v /opt/doc:/opt/doc \
--privileged=true --net=host -itd --name=gluster gluster-docker
then I mount a volume to a folder in container:
mount -t glusterfs 192.168.1.100:/documents /opt/doc
When I write data to the /opt/doc of my real server, the data won't be rsync to the /opt/doc of the container.
Is there any idea to rsync data between container and server after I have mounted the folder ?
gluster-docker: https://github.com/gluster/gluster-containers
Finally, I found --mount in docker-ce 17.06.
mount --bind /data/fff /data/fff
mount --make-shared /data/fff
docker run -v /sys/fs/cgroup:/sys/fs/cgroup -v /opt/doc:/opt/doc \
--privileged=true --net=host --mount \
type=bind,source=/data/fff,target=/data/fff,bind-propagation=rshared \
-itd --name=gluster gluster-docker
then I mount a volume to the folder in container:
mount -t glusterfs 192.168.1.100:/documents /data/fff
OK.
https://docs.docker.com/engine/admin/volumes/bind-mounts/
https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt

what is 'z' flag in docker container's volumes-from option?

While going through the docker docs, I came across volumes-from (https://docs.docker.com/engine/reference/commandline/run/) option for docker run command.
I didn't understand the differences between ro, rw, and z option provided as-
$ docker run --volumes-from ba8c0c54f0f2:ro -i -t ubuntu pwd
In the above command the ro option is replaced with z. I will be thankful if anyone explores on differences of using these options.
Two suffixes :z or :Z can be added to the volume mount. These suffixes tell Docker to relabel file objects on the shared volumes. The 'z' option tells Docker that the volume content will be shared between containers. Docker will label the content with a shared content label. Shared volumes labels allow all containers to read/write content. The 'Z' option tells Docker to label the content with a private unshared label.
https://github.com/rhatdan/docker/blob/e6473011583967df4aa5a62f173fb421cae2bb1e/docs/sources/reference/commandline/cli.md
If you use selinux you can add the z or Z options to modify the selinux label of the host file or directory being mounted into the container. This affects the file or directory on the host machine itself and can have consequences outside of the scope of Docker.
The z option indicates that the bind mount content is shared among multiple containers.
The Z option indicates that the bind mount content is private and unshared.
Use extreme caution with these options. Bind-mounting a system directory such as /home or /usr with the Z option renders your host machine inoperable and you may need to relabel the host machine files by hand.
$ docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:z \
nginx:latest
https://docs.docker.com/storage/bind-mounts/#configure-bind-propagation
From tests here in my machine, -z lets you share content from one container with another. Suppose this image:
FROM alpine
RUN mkdir -p /var/www/html \
&& echo "foo" > /var/www/html/index.html
Let's build it and tag as test-z:
$ docker build . -t test-z
Now create and run test-z container with the name testing-z, mapping the volume test-vol to /var/www/html and adding the z modifier
$ docker run \
--name testing-z \
--volume test-vol:/var/www/html:z \
-d test-z tail -f /dev/null
The contents of /var/www/html from testing-z can be accessed from others containers by using the --volumes-from flag, like below:
$ docker run --rm --volumes-from testing-z -it nginx sh
# cat /var/www/html/index.html
foo
Obs.: I'm running Docker version 19.03.5-ce, build 633a0ea838
docker run --volumes-from a64f10cd5f0e:z -i -t rhel6 bin/bash
I have tested it, i have mounted in one container and from that container to another newly container. IT goes with rw option
I've done the following observation:
# docker run --rm -ti -v /host/path/to/flyway/scripts:/flyway/sql:z --entrypoint '' flyway/flyway ls -l /flyway/sql
total 0
# docker run --rm -ti -v /host/path/to/flyway/scripts:/flyway/sql --entrypoint '' flyway/flyway ls -l /flyway/sql
ls: cannot open directory '/flyway/sql': Permission denied
So, in this case, the container works only if :z is set. On this host, SELinux is installed. If this is not the case, the :z doesn't have a recognizable effect to me.
Alternatively to :z, one could use chcon on the host folder to change this permission:
# chcon -t svirt_sandbox_file_t /host/path/to/flyway/scripts
# docker run --rm -ti -v /host/path/to/flyway/scripts:/flyway/sql:z --entrypoint '' flyway/flyway ls -l /flyway/sql
total 0
# docker run --rm -ti -v /host/path/to/flyway/scripts:/flyway/sql --entrypoint '' flyway/flyway ls -l /flyway/sql
total 0

Resources