# Updating Docker services with Portainer webhooks

_Continuous Delivery_

Author: Georg Ledermann  
Published: 2018-09-17  
Tags: Docker, Portainer, Deployment, CI/CD  
Canonical: https://ledermann.dev/blog/2018/09/17/updating-docker-services-with-portainer-webhooks/

Deploying a new Docker image by hand means logging in, pulling, restarting. With a Portainer webhook, every successful CI build deploys itself.

---

Some time ago I wrote about [using Portainer for Docker hosting](/blog/2018/03/29/migration-from-docker-cloud-to-portainer/) and [using GitLab as container registry](/blog/2018/04/05/switching-from-docker-hub-to-gitlab-container-registry/). Due to the further development of Portainer there is an interesting improvement regarding the installation of updates.

To update my Docker services I've been using [Shepherd](https://github.com/djmaze/shepherd), a small tool that constantly polls the registry to see if a new Docker image is available and then fetches it from there, updating the running container with it. This works, but is not perfect: It leads to a basic load of the host and updates are delayed noticeably, especially if there are lots of services to check.

It would be better if a **push** mechanism could be used instead of polling, so that action is taken only when an updated image is available. Exactly this is possible with the recently released version [1.19.2](https://github.com/portainer/portainer/releases/tag/1.19.2) of Portainer: Now you can enable a webhook for each service. This webhook reacts to POST requests and performs an update.

This can easily be integrated into a CI/CD pipeline, I want to describe it using _GitLab CI_:

## Step 1: Activate webhook in Portainer

First, the webhook for the desired service needs to be activated in Portainer. This generates an endpoint we will use later:

  Enabling webhooks in Portainer

## Step 2: Add CI variable in GitLab

Second, this endpoint must be made known to the CI/CD. In _GitLab_ I'm adding a variable for this. Caution: If the same image is used for several services, several webhooks are required accordingly.

  Setting GitLab variables

## Step 3: Enhance .gitlab-ci.yml

In the CI script `.gitlab-ci.yml` this variable needs to be used to post a request to the webhook after the image was successfully pushed to the Docker registry. The script will look like this:

```yaml
release:
  script:
    - ...
    - docker build ...
    - docker push ...
    - curl -X POST $PORTAINER_HOOK_APP
    - curl -X POST $PORTAINER_HOOK_WORKER
```

That's it. Now, after a new image is released, the Portainer host gets informed about this, so an update can be installed immediately.

BTW: I'm still using Shepherd, but for external images only, where an update check at longer intervals is sufficient, e.g. once a day.
