Deploy from Github/Gitlab to server using Webhook

Xabi
The Sysadmin
Published in
3 min readOct 26, 2020

The team working on a web project asked me to deploy their Github repository to our web server. Every commit pushed to the repository must be immediately sent to the server. How would you do that?

Using Webhook, I can set up a hook that runs a redeploy script in my staging server whenever somebody pushes changes to the project.

Webhook is a lightweight configurable tool written in Go, that allows you to easily create HTTP endpoints (hooks) on your server, which you can use to execute configured commands. You can also pass data from the HTTP request (such as headers, payload or query variables) to your commands. webhook also allows you to specify rules which have to be satisfied in order for the hook to be triggered.

Installation

Are you using Debian or Ubuntu? Then just type:

$ apt install webhook

Configuration

We need to generate a JSON configuration file. For instance:

[
{
"id": "mydomain-redeploy",
"execute-command": "/var/www/mydomain.com/redeploy-webhook.sh",
"command-working-directory": "/var/www/mydomain.com/html",
"trigger-rule":
{
"match":
{
"type": "payload-hash-sha1",
"secret": "mysecret",
"parameter":
{
"source": "header",
"name": "X-Hub-Signature"
}
}
},
}
]

In the above example I’m just checking that the secret is correct. We will set up this password later in our Github webhook. We could add more conditions or rules. You can find more configuration file examples to work with Bitbucket or Gitlab.

Save it as /etc/webhook.conf and try to execute it manually:

$ webhook -hooks /etc/webhook.conf -verbose

By default it will listen in port tcp/9000.

If it returns the message “address already in use”, keep in mind Ubuntu installation package configures a SystemD script, so you may stop the service before run it manually:

$ systemctl stop webhook

Git script

This is the easy step. First you need to download/clone the code to your webroot directory. Then there are several ways to keep it updated. For instance, you could run the following script:

#!/usr/bin/env bashgit fetch --all
git checkout --force "origin/main"

Keep in mind you may create SSH keys and add it to the repository.

Github configuration

Go to your repository Settings — Webhooks — Add webhook:

You’d probably want to set up the secret “mysecret” as it’s the only rule we specified in our hook.

After saving the webhook, Github will PING your webhook URL. You will see the log message in webhook command verbose output:

[webhook] 2018/02/05 11:56:01 [5d6294] finished handling ping

Now, if you push any change, Github will call your webhook URL, and Webhook will call your deploy script, keeping your files always synchronized. It requires only 2–3 seconds to complete this workflow!

Webhook with HTTPS

Webhook will use HTTP by default. It’s really easy to set up HTTPS:

Don’t you have your certificates yet? Use Certbot to retrieve them.

certbot certonly --webroot -w /var/www/mydomain.com/html/ -d mydomain.com

Now you can run Webhook with HTTPS enabled using the following options:

webhook -hooks /etc/webhook.conf -secure -cert /etc/letsencrypt/live/mydomain.com/fullchain.pem -key /etc/letsencrypt/live/mydomain.com/privkey.pem -verbose

If you need more parameters, you can check the following list: https://github.com/adnanh/webhook/blob/master/docs/Webhook-Parameters.md

Systemd script

Ubuntu’s Webhook package will set it up a Systemd service script and it will run it at startup.

If you want to change the script, for instance to enable HTTPS as mentioned above, you need to adapt the following file:

/etc/systemd/system/multi-user.target.wants/webhook.service

[Unit]
Description=Small server for creating HTTP endpoints (hooks)
Documentation=https://github.com/adnanh/webhook/
[Service]
ExecStart=/usr/bin/webhook -nopanic -hooks /etc/webhook.conf -secure -cert /etc/letsencrypt/live/mydomain.com/fullchain.pem -key /etc/letsencrypt/live/mydomain.com/privkey.pem
[Install]
WantedBy=multi-user.target

Do not forget to reload SystemD:

$ systemctl daemon-reload

Ready for production

Now yes, your Webhook is ready for production:

$ systemctl start webhook

--

--