I'm reading a document from Microsoft that states about Docker volumes
Volumes are stored within directories on the host filesystem. Docker
will mount and manage the volumes in the container. Once mounted,
these volumes are isolated from the host machine.
Multiple containers can simultaneously use the same volumes. Volumes
also don't get removed automatically when a container stops using the
volume.
In our example, we can create a directory on our container host and
mount this volume into the container when we create the tracking
portal container. When our tracking portal logs data, we can access
this information via the container host's filesystem. We'll have
access to this log file even if our container is removed.
I'm confused as I understand that the volumes are isolated from the host machine, but how can that be if we can access to the data via the host.
I'm less familiar with Docker on Windows, but I'm sure it's probably the same as Linux in this regard...
Docker volumes are "isolated on the host machine" by being in a particular location with particular permissions on the host's filesystem (i.e. via namespaces). Users/accounts with elevated permissions would still be granted access to those directories/files.
By contrast a bind mount can be made to (pretty much) any directory on the host's file system.
Related
I have seen the terms "bind mount" and "host volume" being used in various articles but none of them mention whether they are the same thing or not. But looking at their function, it looks like they are pretty much the same thing. Can anyone answer whether it is the same thing or not? If not, what is the difference?
Ref:
Docker Docs - Use bind mounts
https://blog.logrocket.com/docker-volumes-vs-bind-mounts/
They are different concepts.
As mentioned in bind mounts:
Bind mounts have been around since the early days of Docker. Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the host machine is mounted into a container. The file or directory is referenced by its absolute path on the host machine. By contrast, when you use a volume, a new directory is created within Docker’s storage directory on the host machine, and Docker manages that directory’s contents.
And as mentioned in volumes:
Volumes are the preferred mechanism for persisting data generated by
and used by Docker containers. While bind mounts are dependent on the
directory structure and OS of the host machine, volumes are completely
managed by Docker. Volumes have several advantages over bind mounts:
Volumes are easier to back up or migrate than bind mounts.
You can manage volumes using Docker CLI commands or the Docker API.
Volumes work on both Linux and Windows containers.
Volumes can be more safely shared among multiple containers.
Volume drivers let you store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
New volumes can have their content pre-populated by a container.
Volumes on Docker Desktop have much higher performance than bind mounts from Mac and Windows hosts.
A "bind mount" is when you let your container see and use a normal directory in a normal filesystem on your host. Changes made by programs running in the container will be visible in your host's filesystem.
A "volume" is a single file on your host that acts like a whole filesystem visible to the container. You can't normally see what's inside it from the host.
I was able to figure it out.
There are 3 types of storage in Docker.
1. Bind mounts-also known as host volumes.
2. Anonymous volumes.
3. Named volumes.
So bind mount = host volume. They are the same thing. "Host volume" must be a deprecating term though, as I cannot see it in Docker docs. But it can be seen in various articles published 1-2 years ago.
Examples for where it is referred to as "host volume":
https://docs.drone.io/pipeline/docker/syntax/volumes/host/
https://spin.atomicobject.com/2019/07/11/docker-volumes-explained/
This docs page here Manage data in Docker is quite helpful
Volumes are stored in a part of the host filesystem which is managed by Docker (/var/lib/docker/volumes/ on Linux). Non-Docker processes should not modify this part of the filesystem. Volumes are the best way to persist data in Docker.
Bind mounts may be stored anywhere on the host system. They may even be important system files or directories. Non-Docker processes on the Docker host or a Docker container can modify them at any time.
I already found a command line to get a path of the files corresponding to my CMS (Prestashop) that runs with Docker, i.e:
docker exec -it <mycontainer> bash
But, it brings me to:
root#4c3cae74d5b1:/var/www/html#
Which looks like a Linux path. So, do you know how to know where the files are situated on my Windows file system ?
Thanks a lot !
Aymeric
If you have not otherwise specified, the files are only inside the one container filesystem, not at all on your host filesystem. The files are in your Windows file system only if you have used bind mounts when running your container and mapped host files/directories to container volume mounts.
In general Docker files can exist in three places:
layered container filesystem (default)
volumes (persistent volumes in your Docker host, volumes can be shared between multiple containers running on the same host)
bind mounts (files or directories in your Docker host filesystem)
You did not provide the actual docker run command you have used to run your Prestashop. This would reveal what option your setup is. More info on Dockker volumes can be found here: https://docs.docker.com/storage/
Which ever way you have stored the volume, you can use docker cp command to copy data between your container and host operating system.
Technically of course also the container filesystems and volumes are stored on your host disk but are not meant to be accessible directly. It is not recommended to access them directly and different versions of Docker have different restrictions. Some info on where to find it on Docker for Windows can be found from answers to this question: Locating data volumes in Docker Desktop (Windows)
I have a service or three that needs access to the same SMB share. The service(s) is running inside a Docker container. I think my choices are:
Have the Docker container(s) where the service(s) is running mount the SMB share itself
Have the host of the Docker container(s) mount the SMB share and then share it with the Docker container(s) where the service(s) is running
Which is better from a best practices perspective (which should probably include security as a dimension)?
Am I missing an option?
Thanks!
In standard Docker, you should almost always mount the filesystem on the host and then use a bind mount to attach the mounted filesystem to a container.
Containers can't usually call mount(2), a typical image won't contain smbclient(1) or mount.cifs(8), and safely passing credentials into a container is tricky. It will be much easier to do the mount on the host, and you can use standard images against the mounted filesystem without having to customize them to add site-specific tools.
One way is to mount the SMB shares on the host system as normal, for example if you are on Linux using mount and fstab. Afterwards you can use docker volumes to add the SMB shares, on your host system to your containers as volumes.
Advantages of using docker volumes are explained in the docker documentation.
More information about docker volumes in the docker documentation,
https://docs.docker.com/storage/volumes/
I have two hosts that run docker service on each host.
Container from host A wanted to uses volume that created from host B.
Is this possible?
noops, both services should be on the same host but there is one thing you can do.
All reused data volumes are mounted on the same paths as in the source
service. Containers must be on the same host in order to share
volumes, so the containers of the new service will deploy to the same
nodes where the source service containers are deployed.
https://docs.docker.com/docker-cloud/apps/volumes/
Possible solution:
mount volume to a host directory
sync that directory between your nodes
You can use NFS to sync directories on all nodes, i have used it myself works fine
On the host side, should all the mount points be located in the same location? Or should they reflect the locations which are inside the containers?
For example, what is the best place to mount /var/jenkins_home on the host side in order to be consistent with its Unix filesystem?
/var/jenkins_home
/srv/jenkins_home
/opt/docker-volumes/jenkins/var/jenkins_home
Other location ?
It absolutely depends on you where you want to mount the volume on the host. Just don't map it to any system file locations.
In my opinion the volumes reflecting the locations inside the container is not a great idea since you will have many containers, and all will have similar file system structure, so you will never be able to isolate container writes.
With jenkins, since the official Jenkins docker image runs with user "jenkins", it will be not a bad idea for you to create jenkins user on the host and map /home/jenkins on the host to /var/jenkins_home on the container.
Rather than using explicit host:container mounts, consider using named volumes. This has several benefits:
They can be shared easily into other containers
They are host-agnostic (if you don't have the specific mount on that machine, it will fail)
They can be managed as first-class citizens in the Docker world (docker volume)
You don't have to worry about where to put them on your host ;)