Using webhooks to trigger actions when a docker image are pushed to a private docker registry
Start by setting up your own docker registry. Here is a little shell script doing it for you
#/bin/sh
docker pull registry:2
docker stop registry
docker rm registry
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v ./registry:/var/lib/registry \
-v ./config.yml:/etc/docker/registry/config.yml \
registry:2
As you can see we are mounting a directory for the registry and a config file. Lets dig into the config file
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
notifications:
endpoints:
- name: alistener
url: http://localhost:9000/hooks/redeploy-webhook
timeout: 500ms
threshold: 5
backoff: 1s
The secret to trigger something when you push to the registry is the notifications part in the end.
So lets continue with setup a simple webhook on your machine. For that we are using, webhook by Adnan Hajdarević. There are several ways of install the software on your machine, I recommend docker or apt depending on your use case.
sudo apt-get install webhook
Now lets continue configure webhook software. Create a directory for it
mkdir /etc/webhook
Create a file named hooks.json and a directory named hooks and a file named git-redeploy.sh
touch /etc/webhook/hooks.json
mkdir /etc/webhook/hooks
touch /etc/webhook/hooks/git-redeploy.sh
Add the following content to the hooks.json file, don’t forget change the names and number of the docker images you ant to perform some actions when a new image are pushed.
hooks.json
[
{
"id": "redeploy-webhook",
"execute-command": "/etc/webhook/hooks/git-redeploy.sh",
"command-working-directory": "/etc/webhook/hooks",
"pass-arguments-to-command": [
{
"source": "payload",
"name": "events.0.target.repository"
}
],
"trigger-rule": {
"and": [
{
"match": {
"type": "value",
"parameter": {
"source": "payload",
"name": "events.0.action"
},
"value": "push"
}
},
{
"or": [
{
"match": {
"type": "value",
"parameter": {
"source": "payload",
"name": "events.0.target.repository"
},
"value": "my-docker-image-1"
}
},
{
"match": {
"type": "value",
"parameter": {
"source": "payload",
"name": "events.0.target.repository"
},
"value": "my-docker-image-1"
}
}
]
},
{
"match": {
"type": "value",
"parameter": {
"source": "payload",
"name": "events.0.target.tag"
},
"value": "latest"
}
}
]
}
}
]
git-redeploy.sh
#!/bin/sh
git_repository=$1
echo "Redeploying $git_repository container..."
cd /home/admin/docker
echo -n "Current working directory: "
echo `pwd`
echo ""
if [[ "$git_repository" = "my-docker-image-1" ]]; then
echo "Redeploying my-docker-service-1..."
docker pull localhost:5000/my-docker-image-1:latest
docker stop my-docker-service-1
docker rm my-docker-service-1
docker run --name my-docker-service-1 localhost:5000/my-docker-image-1:latest
echo "Redeploying $git_repository container done!"
elif [[ "$git_repository" = "my-docker-image-2" ]]; then
echo "Redeploying my-docker-service-2..."
docker pull localhost:5000/my-docker-image-2:latest
docker stop my-docker-service-2
docker rm my-docker-service-2
docker run --name my-docker-service-2 localhost:5000/my-docker-image-2:latest
echo "Redeploying $git_repository container done!"
else
echo ""
echo "ERROR: Redeploy of unknown repository $git_repository failed !!!"
exit -1
fi
exit 0
The webhook software could be executed as a service, how to achieve that depends heavily on your OS. This is an example for alpine linux.
/etc/init.d/webhook
#!/sbin/openrc-run
name="webhook"
command="/usr/bin/webhook"
command_args="-hooks /etc/webhook/hooks.json -verbose -logfile=/var/log/webhook.log tunnel run &"
pidfile="/var/run/webhook.pid"
depend() {
need net localmount
after firewall
}
Enable startup of service at boot time and then start it up
# Start service ay boot time
rc-update add webhook default
# Start service
rc-service webhook start