Quick Links

Docker is a tool that makes it easy to run apps in portable containers. One of the primary benefits of containerization is easily managed updates---all you need to do is restart with a new container, and there are tools that can automate this entire process.

Automatically Deploying Docker Containers

Docker is a great choice for continuous integration/continuous deployment pipelines (CI/CD) as it helps automate both steps of the process. Dockerfiles themselves provide a way to build your app's image, and it's pretty easy to set up automated container builds from source on services like Github. Once built, and pushed to an "image registry," it can then be downloaded and ran by any server running Docker.

This is great, but that still involves running commands on the server every time you want to update. If you'd like it to be truly automatic, then you may be interested in a tool called Watchtower.

Watchtower is a utility that runs on your Docker host and periodically checks for updates to containers. If it detects a new version of an image from the container registry, it will automatically kill the container and restart it immediately.

This is a very attractive feature, but before you go installing it, it's important to discuss the downsides. Doing updates entirely automatically means you will have less control over the time and prior testing of the deployment, as whenever the commit in your repository goes through and triggers a build, the running containers will update. If you don't own the image being ran, it may update unexpectedly if you don't exclude them from Watchtower.

If you're not doing updates every day, you may be better off with a Docker GUI like Portainer, which lets you browse running containers across your servers and click a button to update them automatically. This gives you more control over the process and can help prevent unexpected updates.

Portainer's container details screen

If you'd like to get started using Portainer, you can read our guide to setting it up to learn more.

Using Watchtower

Watchtower is packaged as a Docker container itself, so it's pretty easy to install---just one command will get it up and running:

docker run -d 
    

--name watchtower

-v /var/run/docker.sock:/var/run/docker.sock

containrrr/watchtower

This launches a Watchtower container, and also creates a binding mounting the docker.sock from the host so that it can interact with the Docker API. By default, this scans all running containers for updates every 24 hours, which can be changed with the --interval flag.

You can also create a docker-compose.yml file to start Watchtower as a service:

version: "3"
    

services:

watchtower:

image: containrrr/watchtower

restart: always

volumes:

- /var/run/docker.sock:/var/run/docker.sock

- /root/.docker/config.json:/config.json

command: --interval 300

"All running containers" probably includes some things you'd rather not have unexpectedly update, including images from the Docker Hub that you don't have control over. You can exclude containers from updates, but only by setting a label on the container being scanned.

You'll need to either set this flag on the command line during docker run, or specify it in the container's build process using the LABEL directive.

docker run -d --label=com.centurylinklabs.watchtower.enable=false nginx
    

LABEL com.centurylinklabs.watchtower.enable="false"

You can also do the reverse, by passing the --label-enable flag when starting Watchtower and setting containers to "true."

Running Watchtower as a Docker Compose Service

A better method, especially when you only need to run Watchtower for a single container, is to package it into an existing docker-compose.yml file and create a scope for Watchtower to scan for. In this example, the NGINX image is given the scope "nginx," and Watchtower is configured to only update containers with that scope label.

version: '3'
    

services:

nginx:

image: nginx

labels:

- "com.centurylinklabs.watchtower.scope=nginx"

watchtower:

image: containrrr/watchtower

volumes:

- /var/run/docker.sock:/var/run/docker.sock

command: --interval 300 --scope nginx

labels:

- "com.centurylinklabs.watchtower.scope=nginx"

If you only use Watchtower this way--packaged into a compose file with a scope---it will allow you to run multiple instances. If you run Watchtower without a scope on the same system though, it will override these instances.

Using Third Party Registries

By default, Watchtower only works with the Docker Hub and any other public registry. This excludes certain services like Github's Container Registry, which requires a username and Personal Access Token (PAT) to pull images from.

You can add config for private registries by creating a config.json file with the following content:

{
    

"auths": {

"ghcr.io": {

"auth": "credentials"

}

}

}

The "credentials" value should be set to a base64 encoded string of your username:password combo, or personal access token in the case of Github.

echo -n 'username:password' | base64

Then, when you run Watchtower, pass in an additional mount for this config.json file.

docker run -d 
    

-v config.json:/config.json

-v /var/run/docker.sock:/var/run/docker.sock

containrrr/watchtower