
digitalocean_volume_manager
A Docker Volume Plugin
As is laid out here I deploy this blog to a Digital Ocean droplet using Docker containers controlled by Docker-Compose. It is a pretty simple setup. In good 12 factor app fashion, the only bit of persistence comes from image files stored in S3, and data stored in a Postgres database. Because I was trying to keep this cheap, I was not willing to pay for RDS or similar, I just host the database with the rest of the containers on the host. This could be a problem though- how do you keep from losing your data?? If I accidentally run docker rm -fv postgres while hooked up to the remote host, bad things could happen. In the aspect of cheapness, I wrote a script to take and restore backups using pgdump, and called it a day.
However, Digital Ocean recently announced a new block store service to compete with Amazon EBS. It lets you create volumes, attach them to droplets, and then detach them and move them to other droplets. If something goes wrong with the machine, you can just detach the volume and still have your data. This is the perfect solution for front-line storage on a simple database service like I was using. However, in a DevOps world, we don't want to manually log in and set up the device and program the Docker container to use it... we want that to happen automagically.
Introducing digitalocean_volume_plugin
So, the name is pretty damn weak lol. I apologize- though I bet you can guess what it does! It is a Docker volumes plugin that ties into the Digital Ocean api and lets you create, delete, and use DO block store devices as Docker persistent volumes.
disclaimer...
THIS IS ALPHA QUALITY SOFTWARE It is working for me so far, but it was written in a couple days by someone new to the field, so I am sure there are a billion use cases where there are bugs. Please feel free to report them or offer pull requests!
Getting started
To make things easier on me, the plugin can run as a Docker container itself!
docker run \
-v /dev:/dev \
-v /run/docker/plugins:/run/docker/plugins \
-v /do_volumes/:/do_volumes:rshared \
--privileged \
-e DIGITAL_OCEAN_TOKEN=<MY DO API TOKEN> \
pbecotte/digital_ocean_volumes
This command will start the plugin in a container. In order to do its magic, it needs some admin privileges... it needs to mount devices, format filesystems, and have those mount points be visible to other docker containers. That is the reason for the --privileged and :rshared bits. As an important note, if you are running Docker under systemd, the flag MountFlags=slave in your unit file will prevent rshared from being possible. Docker Machine will install such a unit at /etc/systemd/system/docker.service. Further, I believe that option wasn't added to Docker until version 1.11, so you'll need a recent build.
Supported Commands
docker volume ls will include a list of all the DO volumes in your account for the region the droplet is in.
docker volume create -d digitalocean -o size=5 -o desc='some description' --name myvolume would create a DO volume with the given name, size, and description in the same region as the droplet. Size and Name are required. This does NOT attach the volume to the droplet.
docker volume rm myvolume if myvolume is a DO volume, this will permanently delete your Volume.
docker run -v myvolume:/app ubuntu ls /app This would mount the block volume, attach it to the new container, and then print out the contents. When the container exits, the volume will be detached from the droplet. If more than one container on a single droplet attach to the same volume, it will stay attached until the last one exits. If the volume is already attached to another droplet, this command will fail.
Example
The github repo for devblog is updated to show this in use. The makefile now has a target to install the driver plugin on the Docker Machine target, and uses the volume crated by it in the compose file.