Webhook server
adnanh/webhook is a lightweight incoming webhook server to run shell commands, written in Go. Easily install with:
sudo apt install webhook
Using the apt
method like this already created a service for me. As seen by service webhook status
command, service configuration is stored in /etc/webhook.conf
. It is enabled by default and that can be changed using standard systemctl enable/disable webhook
.
We can manually test configuration file:
webhook -hooks /etc/webhook.conf --verbose
Also use this directive to debug webooks after stopping the service temporarily.
Modify service to log messages
Edit service file by typing:
systemctl edit --full webhook
and add --verbose
to line ExecStart
like:
[Service]
ExecStart=/usr/bin/webhook -nopanic -hooks /etc/webhook.conf --verbose
And then monitor log file with:
tail -f /var/log/syslog -n 500 | grep webhook
Expose test webhook to public
|
|
Let’s test that webhook:
curl http://localhost:9000/hooks/test
Configure a reverse proxy in nginx
with typical setup that looks like
location /hooks/ {
proxy_pass http://127.0.0.1:9000;
}
but I wanted to change URL a little bit
location /webhook/ {
proxy_pass http://127.0.0.1:9000/hooks/;
}
Trailing slashes are extremely important in nginx proxy directive.
So, let’s test our webhook again, this time from outside:
curl https://savioko.com/webhook/test
Integration with GitHub
Generate my secret token with uuidgen
and make it permanent, as environment varibale:
|
|
Trigger webhooks from GitHub
X-Hub-Signature
is recommended for GitHub
https://docs.github.com/en/developers/webhooks-and-events/webhooks
|
|
better is: "response-message": "Deployment initiated...",
and test webhook with:
|
|
Now, got to GitHub and inside repository select Settings / Webhooks / Add webhook
.
Payload URL: https://savioko.com/webhook/deploy-treasury
Content type: application/json
Secret: ****** (your $SECRET_TOKEN)
Redeploy script
/var/www/notes.cvladan.com/
“-e” if any command fails, the script will terminate immediately so trap system works as expected
Block secret content
|
|
I need proper identity file a.k.a. “Deploy Keys”
You can’t reuse a deploy key for multiple repositories so we must create separate keys for every submodule
|
|
Now, put content of .ssh/id_rsa.github.*.pub
as “Deploy Keys” on corresponding GitHub repositories; the main one and in the submodule repository.
Failed attempts
I’ve tried using multiple identities in .ssh/config
but that doesn’t work
cat << EOF >> ~/.ssh/config
Host github.com
IdentityFile ~/.ssh/id_rsa.github.hugo
IdentityFile ~/.ssh/id_rsa.github.notes
IdentitiesOnly=yes
EOF
and I’ve also tried using env variable GIT_SSH_COMMAND
also with multiple identities…
Specifying multiple identities (-i
) doesn’t work; don’t know why?.
Option (-F /dev/null
) forces it to ignore any configuration file, global or per user.
GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i $HOME/.ssh/id_rsa.github.hugo -i $HOME/.ssh/id_rsa.github.notes -F /dev/null"
Finally, a working solution
I have to split into separate directives and specify identity on a submodule basis.
# clone main repo without submodules
#
export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i $HOME/.ssh/id_rsa.github.hugo -F /dev/null"
git clone "git@github.com:cvladan/hugo.git" "$HOME/hugo-staging_area"
# pull submodules
#
export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i $HOME/.ssh/id_rsa.github.notes -F /dev/null"
git submodule update --init
# update to latest commit
git submodule update --remote
Finalized script placed in /opt/webhook/deploy-treasury.sh
that will deploy my repo.
Error on GitHub
We couldn’t deliver this payload: timed out
Turns out that GitHub has a 10-second timeout set on webhooks.