Search code examples
dockervolume

Writing to docker volume from Dockerfile does not work


Please consider the following Dockerfile:

FROM phusion/baseimage
VOLUME ["/data"]
RUN touch /data/HELLO
RUN ls -ls /data

Problem: "/data" directory does not contain "HELLO" file. Moreover, any other attempts to write to volume directory (via echo, mv, cp, ...) are unsuccessful - the directory is always empty. No error messages shown.

I could not find anything in documentation or on stackoverflow regarding this problem.

Is this something well-known or new?

docker version returns:

Client version: 1.2.0
Client API version: 1.14
Go version (client): go1.3.1
Git commit (client): fa7b24f
OS/Arch (client): linux/amd64
Server version: 1.2.0
Server API version: 1.14
Go version (server): go1.3.1
Git commit (server): fa7b24f

Solution

  • Each step of the Dockerfile is run in it's own container that is discarded when that step is done, and volumes are discarded when the last (in this case only) container that uses them is deleted after it's command finishes. This makes volumes poorly suited to use in Dockerfiles because they loose their contents half way through. Docker files are intended to be able to be run anywhere, and if they used Volumes that persisted it would make this harder. On the other hand if you really want this, just back the volume with a directory on the host.

    PS: Initializing the host's data directory is best done outside of the Docker file.

    Last time I needed this I left this step out of the docker file because the idea of this step is to prepare the host to run the Image produced by this Dockerfile. Then I made a container with docker run and within that container I ran the usual DB setup stuff.

    docker run -v /var/lib/mysql:/raid/.../mysql ...
    /usr/bin/mysql_install_db 
    mysql_secure_installation
    

    Now when this container is moved to a new host, that Data dir can either be brought with it, or created using the same process on that host. Or if, as in my example, you wanted another mysql db for some other application you don't have to repeat the container creation.

    The important idea is to keep the container creation and host setup seperate.