Being able to just kill a docker container and start up a fresh container with a new version of your application is nice but what if you have data attached to it? For example if you launch a database via docker? Or if your application has some userdata in its filesystem (for example images users uploaded) which need some kind of migration step before the new version can be run (for example generate a new thumbnail size) ?
While this post might be a case of “stating the obvious” I was really surprised to not find plenty of material concerning this topic and especially nothing related to the major databases (which change their data format from time to time and need an upgrade).
So here is how I would do it :) I will use arangodb but this workflow should be valid for anything having some data attached to the container.
Attached container data should be placed in docker volumes. Docker volumes reside outside the normal docker layered file system. They are placed on the host. Since 1.9.0 there is even a separate command docker volume to manage these volumes.
While it is excellently documented, many people (including my former self) seem to not really be aware that docker volumes are more than “Yeah understood. I can mount a host volume into the container using -v and I am done”.
Docker images declare their volumes inside the Dockerfile. Whenever you launch a docker container using for example docker run -d --name arangodb arangodb/arangodb:2.7.5 all volumes declared in the image will be created on the host filesystem.
docker@default:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
arangodb/arangodb 2.7.5 221948f0d01c 6 days ago 439.8 MB
docker@default:~$ docker inspect 221948f0d01c | grep Volumes -A 5
As we can see arangodb defines 4 volumes. What happens if we delete the container?
docker@default:~$ docker run -d --name arangodb arangodb/arangodb:2.7.5
2016-01-31T20:48:49Z  INFO permanently changing the gid to 999
2016-01-31T20:48:49Z  INFO permanently changing the uid to 999
So now our arangodb is running. As it happens arangodb 2.8.0 was released last week. What if we want to upgrade? Simply delete the old docker container and fire up the new one. Again we simply use the volumes from our data-only container :)