This plugin associates a container with a DigitalOcean volume. In swarm mode, the volume will "follow" the container around to whatever worker it gets scheduled on.
docker plugin install cjbottaro/do_storage:latest ACCESS_TOKEN=<your_DO_token>
Where ACCESS_TOKEN is your DigitalOcean personal access token.
The plugin needs to be installed on each machine where you plan to run containers that use it, even in swarm mode.
Create and format a DigitalOcean volume called pgdata.
Given the following docker-compose.yml file:
version: "3.4"
services:
postgres:
image: postgres:alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
PGDATA: /var/lib/postgresql/data/data # Workaround for quirk in image.
volumes:
pgdata:
name: pgdata
driver: cjbottaro/do_storage:latestCreate a container, then create a Postgres database, then stop the container.
node1$ docker-compose up -d
node1$ docker exec $(docker-compose ps -q) createdb foobar
node1$ docker-compose stopNow on a different machine, start a container using the same docker-compose.yml.
We can verify that the DigitalOcean volume followed us to this machine by listing
the databases.
node2$ docker-compose up -d
node2$ docker exec $(docker-compose ps -q) psql -U postgres -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
foobar | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)A DigitalOcean volume can only be attached to one node at a time. If you start a container using a volume that is already in use by a container on another node, the plugin will detach the volume from the running container and attach it to the new container. This will probably crash your process.
To illustrate, consider our example above...
node1$ docker-compose up -d
node2$ docker-compose up -d
node2$ docker exec $(docker-compose ps -q) psql -U postgres -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
foobar | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
node1$ docker exec $(docker-compose ps -q) psql -U postgres -l
psql: FATAL: could not open relation mapping file "global/pg_filenode.map": No such file or directoryWe start a container on node1, but then we start a container on node2 and the
volume is detached from node1 and attached to node2. Now when we ask the first
container to list the databases, it give us a fatal error.
docker-compose build do_storage
docker-compose run --rm do_storage_builder
docker plugin push cjbottaro/do_storage:latest