Automated Deployment on Docker Swarm

From GitHub to Docker Hub to Docker Swarm

Image for post
Image for post

Configuring automated deployment of an image to Docker Hub every time a change is pushed to a specific GitHub branch (or when a new release is tagged) is easy to do with Docker Hub user interface.

Docker Hub will automatically configure your GitHub repository to trigger this for you and is able to build different Docker images from different GitHub branches.

While it’s quite straightforward to setup and run a private registry, using Docker Hub is very cheap and provides automated image building, starting at only $7 a month for 5 private repositories.

This makes using DockerHub much more cost effective option than spending time setting up and maintaining your own pipeline for building images, which can easily end up costing that much in compute time and cloud storage alone.

You can configure Docker Hub to call a webhook each time a new image is published.

Unfortunately, Docker Swarm does not integrate with Docker Hub to trigger deployments automatically out of the box, which is where docker-deploy-webhook comes in.

Using docker-deploy-webhook you can run a Docker Service to listen for webhooks from Docker Hub on a Docker Swarm cluster, and trigger deployment of the new image on a corresponding service.

The webhook works with private repositories on GitHub / Docker Hub and with self-hosted Docker Swarms You don’t need to use Docker Cloud to manage your Swarm to use this webhook.

The easist way to use docker-deploy-webhook is to fork it and configure it with the images you want to listen for updates to.

The key to how it works is actually in how the service is deployed:

docker service create \
--name docker-deploy-webhook \
--with-registry-auth \
--constraint "node.role==manager" \
--publish=8080:8080 \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
-e CONFIG="8080" \
-e CONFIG="production" \
-e TOKEN="123456ABCDEF" \
-e USERNAME="docker-hub-username" \
-e PASSWORD="docker-hub-password" \

The --mount option used here lets the service access the Docker API on the parent host and the --constraint option ensures this service only runs on Manager Nodes (as Worker Nodes do not have access to update services).

The docker socket is also how management interfaces like Portainer access and control the instance of docker they are running on.

This webhook works great with Portainer as it will display detailed information in the logs, which is helpful to check it’s all working, especially when setting it up for the first time.

Crucially, the Dockerfile for docker-deploy-webhook project comes with an up-to-date version of Docker:

FROM node:8-alpine
RUN apk update && apk add docker

If a Docker app in a container is out of date with the version used to run the Docker Swarm and interacts with it via /var/run/docker.sock you won’t get an explicit error from docker but you will run into problems during deployment (such as services failing and even left being unconfigured after triggering an update).

In practice this is an issue only when the versions are very mismatched, but be aware Docker itself does not check for version mismatches so it’s something to watch out for if you are developing your own service that interacts with Docker Swarm via a socket exposed from a host to a container.

If folks are interested, I’m happy to add a simple web based interface to manage configuration and to provide options for handling other tasks that you might want to run on deploy, such as telling docker to clean up old images to relaim diskspace.

Written by

Software for news and media and civic tech. Cat herder. Director at Glitch Digital.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store