Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerfile, persist data with VOLUME

Please bear with me as I learn my way around docker. I'm using v1.11.1

I am making a Dockerfile and would like to specify that a folder of the container should be persisted, this should only be persisted per user (computer running the container). I originally thought that including:

VOLUME /path/to/dir/to/persist

would be enough, but when I start my container with docker run -t -i myimage:latest bash and manually add files in then exit I expect to be able to find my files again. But when I run the image again (as per above) the added files are no longer there.

I've read around but answers seem either outdated in regards to the use of VOLUMES, or suggest things I would rather not do, which is:

  • I don't want to use -v in the run command
  • I would rather not make a volume container (seems like overkill for my one tiny folder)

What is it that I'm doing wrong? Any help would be greatly appreciated.

Cheers guys.

Update: I can persist data using a named volume ie: docker run -v name:/path/to/persist -t -i myimage:latest bash But building with a Dockerfile that contains VOLUME name:/path/to/persist does not work.

like image 589
Pomme.Verte Avatar asked Jan 06 '23 10:01

Pomme.Verte


1 Answers

What is not very obvious is that you are creating a brand new container every time you do a "docker run". Each new container would then have a fresh volume.

So your data is being persisted, but you're not reading the data from the container you wrote it to.

Example to illustrate the problem

Sample Dockerfile

FROM ubuntu
VOLUME /data

built as normal

$ docker build . -t myimage
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu
 ---> bd3d4369aebc
Step 2 : VOLUME /data
 ---> Running in db84d80841de
 ---> 7c94335543b8

Now run it twice

$ docker run -ti myimage echo hello world
$ docker run -ti myimage echo hello world

And take a look at the volumes

$ docker volume ls
DRIVER              VOLUME NAME
local               078820609d31f814cd5704cf419c3f579af30672411c476c4972a4aad3a3916c
local               cad0604d02467a02f2148a77992b1429bb655dba8137351d392b77a25f30192b

The "docker rm" command has a special "-v" option that will cleanup any volumes associated with containers.

$ docker rm -v $(docker ps -qa)

How to use a data container

Using the same docker image, built in the previous example create a container whose sole purpose is to persist data via it's volume

$ docker create --name mydata myimage

Launch another container that saves some data into the "/data" volume

$ docker run -it --rm --volumes-from mydata myimage bash
root@a1227abdc212:/# echo hello world > /data/helloworld.txt
root@a1227abdc212:/# exit

Launch a second container that retrieves the data

$ docker run -it --rm --volumes-from mydata myimage cat /data/helloworld.txt
hello world

Cleanup, simply remove the container and specify the "-v" option to ensure its volume is cleaned up.

$ docker rm -v mydata

Notes:

  • The "volumes-from" parameter means all data is saved into the underlying volume associated with the "mydata" container
  • When running the containers the "rm" option will ensure they are automatically removed, useful for once-off containers.
like image 83
Mark O'Connor Avatar answered Jan 07 '23 22:01

Mark O'Connor