Some time ago I wrote about using Portainer for Docker hosting and using GitLab as 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, 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 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:
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.
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:
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.