Docker Named Volume on another Partition on another hard drive - docker

I have a Docker container running on my PC. The main functionality of the container is to scrape data, and this accumulates 0.3GB/day. I'll only be needing this data for the last 30 days, and after this I plan to store it archived on Hard Disk Drives for historical purposes. However after few hours of trials and errors, I've failed to create a Docker Volume on another partition, and the _data folder always appears in the /var/lib/docker/volumes/<volume_name> folder, while the partition drive is always empty.
I also tried creating the volume with docker run -v , but it still creates the volume in the main volumes folder.
The operating system is Pop!_OS 20.04 LTS
I'll provide data about the partition:
I'll provide data about the partition:

In case of docker volumes, you don't have control over where docker saves it's volumes. all you can do is just to change docker root directory. so it's better to mount your new partition under a directory and then change docker root directory to this mount point. this way you can achieve what you want. also you should consider that by doing this, all of your docker data will be stored in this new partition.
for changing your docker root directory, you should first create a file named daemon.json in address below:
/etc/docker/daemon.json
and then add config below to it:
{
"data-root": "/path/to/new/directory"
}
then restart docker daemon:
systemctl restart docker
then you can run command below to check current docker root directory:
docker info

In case you are using docker volumes all your volumes data are stored in default location (/var/lib/docker) but you can change it in /etc/docker/daemon.json config file:
{
...
"data-root": "/your/path/here",
...
}
Restart docker service to apply changes.
Docker daemon configuration file documentation here.

Related

How does volume mount from container to host and vice versa work?

docker run -ti --rm -v DataVolume3:/var ubuntu
Lets say I have a volume DataVolume 3 which pulls the contents of /var in the ubuntu container
even after killing this ubuntu container the volume remains and I can use this volume DataVolume3 to mount it to other containers.
This means with the deletion of container the volume mounts are not deleted.
How does this work ?
Does that volume mount mean that it copies the contents of /var into some local directory because this does not look like a symbolic link ?
If I have the container running and I create a file in the container then the same file gets copied to the host path ?
How does this whole process of volume mount from container to host and host to container work ?
Volumes are used for persistent storage and the volumes persists independent of the lifecycle of the container.
We can go through a demo to understand it clearly.
First, let's create a container using the named volumes approach as:
docker run -ti --rm -v DataVolume3:/var ubuntu
This will create a docker volume named DataVolume3 and it can be viewed in the output of docker volume ls:
docker volume ls
DRIVER VOLUME NAME
local DataVolume3
Docker stores the information about these named volumes in the directory /var/lib/docker/volumes/ (*):
ls /var/lib/docker/volumes/
1617af4bce3a647a0b93ed980d64d97746878564b141f30b6110d0818bf32b76 DataVolume3
Next, let's write some data from the ubuntu container at the mounted path var:
echo "hello" > var/file1
root#2b67a89a0050:/# cat /var/file1
hello
We can see this data with cat even after deleting the container:
cat /var/lib/docker/volumes/DataVolume3/_data/file1
hello
Note: Although, we are able to access the volumes like shown above but it not a recommended practice to access volumes data like this.
Now, next time when another container uses the same volume then the data from the volume gets mounted at the container directory specified as part of -v flag.
(*) The location may vary based on OS as pointed by David and probably can be seen by the docker volume inspect command.
Docker has a concept of a named volume. By default the storage for this lives somewhere on your host system and you can't directly access it from outside Docker (*). A named volume has its own lifecycle, it can be independently docker volume rm'd, and if you start another container mounting the same volume, it will have the same persistent content.
The docker run -v option takes some unit of storage, either a named volume or a specific host directory, and mounts it (as in the mount(8) command) in a specific place in the container filesystem. This will hide what was originally in the image and replace it with the volume content.
As you note, if the thing you mount is an empty named volume, it will get populated from the image content at container initialization time. There are some really important caveats on this functionality:
Named volume initialization happens only if the volume is totally empty.
The contents of the named volume never automatically update.
If the volume isn't empty, the volume contents completely replace what's in the image, even if it's changed.
The initialization happens only on native Docker, and not for example in Kubernetes.
The initialization happens only on named volumes, and not for bind-mounted host directories.
With all of these caveats, I'd avoid relying on this functionality.
If you need to mount a volume into a container, assume it will be empty when your entrypoint or the main container command starts. If you need a particular directory layout or file structure there, an entrypoint script can create it; if you're expecting it to hold particular data, keep a copy of it somewhere else in your image and copy it in if it's not already there (or, perhaps, always).
(*) On native Linux you can find a filesystem location for it, but accessing this isn't a best practice. On other OSes this will be hidden inside a virtual machine or other opaque storage. If you need to directly access the data (or inject config files, or read log files) a docker run -v /host/path:/container/path bind mount is a better choice.
Volumes are part of neither the container nor the host. Well, technically everything resides in the host machine. But the docker directories are only accessible by users in "docker" group. The files in these directories are separately managed by docker.
"Volumes are stored in a part of the host filesystem which is managed by Docker (/var/lib/docker/volumes/ on Linux)."
Hence volumes are like the union of files under the docker container and the host itself. Any addition on either end will be added to the volume(/var/lib/docker/volumes), not hard copy, rather something like symbol link
As volumes can be shared across different containers, deleting a container does not cascade to the volumes associated with it.
To remove unused volumes:
docker volume prune .

Change mountpoint of docker volume to a custom directory

I would like to have a Docker Volume that mounts to a container. This volume would need to be somewhere other than the default location of volumes, preferably somewhere on the Desktop. This is because I am running a web server and would like some directories to be editable by something like VSCode so I don't always have to go inside the container to edit a file. I am not going to be using Docker Compose and instead will be using a Docker File for the container. The functionality I'm going for is the following equivalent of Docker Compose, but in a Dockerfile or through docker run, whichever is easiest to accomplish:
volumes:
- <local-dir>:<container-dir>
This directory will need to be editable LIVE and using the Dockerfile ADD command will not suffice, because after building, the image gets put into a tar archive and cannot be accessed after that.
with this solution you can move even A live container to new partition:
Add a configuration file to tell the docker daemon what is the location of the data directory
Using your preferred text editor add a file named daemon.json under the directory /etc/docker. The file should have this content:
{
"data-root": "/path/to/your/docker"
}
Copy the current data directory to the new one
sudo rsync -aP /var/lib/docker/ /path/to/your/docker
Rename the old docker directory
sudo mv /var/lib/docker /var/lib/docker.old
Restart the docker daemon
sudo service docker start
resource: https://www.guguweb.com/2019/02/07/how-to-move-docker-data-directory-to-another-location-on-ubuntu/
You can mount a directory from your host inside your container when you launch the docker container, using -v or --volume
docker run -v /path/to/desktop/some-dir:/container-dir/path <docker-image>
Volumes specified in the Dockerfile, as you exemplified, will automatically create those volumes under /var/lib/docker/volumes/ every time a container is launched from that image, but it is NOT recommended have these volumes altered by non-Docker processes.

Move Docker /var/run/docker data to different directory

I followed the following tutorial to transfer and permanently move where docker saves data previously inside /usr/bin: https://linuxconfig.org/how-to-move-docker-s-default-var-lib-docker-to-another-directory-on-ubuntu-debian-linux
However upon restarting docker and rebuilding all containers, there seems to be activity in /var/run/docker/containerd/ which I was previously trying to work around. I was hoping to have all things docker saved in a specific directory not in /var/run along with my newly created docker directory to replace /usr/bin/docker
Note: df -h did in fact prove that I am out of space in the base directory where /usr/bin and /var/run exists. I am trying to navigate all docker items to a sub directory under /opt
How do I move all things Docker to a different directory?
(Answer) Found in documentation: https://docs.docker.com/config/daemon/systemd/#runtime-directory-and-storage-driver
As described in the Docker documentation, to set the docker daemon directory to <folder>:
Create /etc/docker/daemon.json with the following contents:
{
"data-root": "<folder>",
"storage-driver": "overlay2"
}
Restart the docker daemon.
Note that this will not move existing docker data over to the target folder - you will need to handle that (or start from scratch).

Where is the docker container data stored on the host machine?

In docker, where is the container data, apart from the mounted volume, is stored till the container is running.
So lets say /usr/local is volume mounted, so it would be shared between the host and the container. Where is everything else stored?
You should inspect your docker container
docker inspect [ID_CONTAINER]
and check for the fields MergedDir, LowerDir and UpperDir. Docker uses OverlayFS file system to store the data.
OverlayFS layers two directories on a single Linux host and presents them as a single directory. These directories are called layers and the unification process is referred to a a union mount. OverlayFS refers to the lower directory as lowerdir and the upper directory a upperdir. The unified view is exposed through its own directory called merged.
Check the doc here.
You can run the following command to get container written data
ll `podman inspect ContainerName --format "{{ .GraphDriver.Data.MergedDir }}"`

docker share volumes with glusterfs

I want to test docker in Swarm mode.
I've created 3 Ubuntu-server Virtual Machines.
On each VM I've installed docker.
The next step that I would like to accomplish is to share the /var/lib/docker/volumes folder among the 3 docker nodes.
The first solution I tried is to mount /var/lib/docker/volumes as a remote sshfs volume. I failed because when the docker service starts it executes the command chown on the /var/lib/docker/volumes and it fails.
Then I tried to use glusterfs, I succeded to configure gluster to share the same folder on the 3 nodes (now if I create a file in /var/lib/docker/volumes on the first node, I can see the new file also on the others 2 nodes).
Then I started docker on the first node without any problem. But If I try to start docker on the second node I got the error:
Error starting daemon: error while opening volume store metadata database: timeout
I assume that the error is because the first node acquire the lock on the file /var/lib/doceker/meradata.db
How can I solve this problem?
Is there an alternative to use glusterfs to share the docker volumes folder?
Thank you
You shouldn't share this directory at all. It will probably lead to data corruption. As you already have glusterfs configured you can mount gluster dir into container with -v /path/to/gluster/mount:/path/in/container flag added to docker run. Then files written to path in container will be shared among gluster nodes. Other option is to use some dedicated volumes driver for that. Try searching for 'docker volumes drivers' in your favorite search engine.

Resources