All that read are saying that we can create docker persistent storage via the VOLUME
control, e.g., here and here.
However, I have the following in my Dockerfile
:
VOLUME ["/home", "/root"]
but nothing was kept in there (I tried touch abc
, and when I exit and get back in again the file is not there).
I see that the official usage has no other special controls or treatments, yet it can provide persistent storage, even the apt-cacher-ng
service container is stopped.
How is that possible? I've checked out the following but still don't have a clue:
In conclusion, as explained here:
The first mechanism will create an implicit storage sandbox for the container that requested host-based persistence. ... The key thing to understand is that the data stored in the sandbox is not available to other containers, except the one that requested it.
How can I make persistent storage works? Why my changes are wiped each time, while the apt-cacher-ng
service container can maintain its persistent storage even it is stopped and restarted?
What is the "other special controls or treatments" that I failed to see here?
Explain with plain simple Dockerfile
(not docker-compose.yml
) please.
The problem is that the VOLUME instruction creates an external storage when the docker run is used without the "mount" option for that specific folder. In other words, every time you create a container for that image, docker will create a new volume with a random label but since you're not giving those volumes a name, the new containers cannot re-use the existing generated volumes.
e.g.
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
Given this Dockerfile, if you simply build and run this docker image using the following commands:
echo "There are currently $(docker volume ls | wc -l) volumes"
docker build -t my_volume_test:latest .
docker run --name another_test my_volume_test:latest
echo "There are currently $(docker volume ls | wc -l) volumes"
you'll see that the amount of volumes present on your machine has increased. That container is now using a volume to store the data but that specific volume does not have a name or label so it's only bound to that specific container. If you delete and recreate that container, docker will generate a new volume with a random name unless you manage to mount the volume you've created earlier.
If you want to make it easy, I suggest to first create the volume and mount it then. e.g.
docker rm -f another_test
docker volume create my-vol
docker run \
--name another_test \
--mount source=my-vol,target=/myvol \
my_volume_test:latest
# alternative
docker rm -f another_test
docker run \
--name another_test \
-v my-vol:/myvol \
my_volume_test:latest
In this case you can create and remove as many containers you want but they'll all use the same volume.
check the VOLUME reference and Use volumes for more info.