Ghost Letters 幽霊文字

Create WebHooks with Caddy

WebHook == Run Some Command

A webhook is a an HTTP endpoint that triggers ‘some action’. The action will be specific for the application that provides the endpoint. In my case the action/endpoint will update my blog. Let’s ignore for a moment how exactly ‘updating the blog’ works, and just pretend I want to execute some arbitrary command on my server as soon as I call some very specific URL.

Run Commands with Caddy ‘Exec’ Module

The Exec Module (for some reason caddy calls plugins ‘modules’) allows to bind a path to a command. So a config in the caddyfile like

1
2
3
example.com

exec /createFile touch /home/user/new_file.txt

would create an empty file on the server when someone calls example.com/createFile. Instead of creating a file we could run any series of command line tools.

They Said It Would Be Easy

The final result and how my workflow looks is already sketched in this note. While I imagined it to be pretty straight forward, it took me several hours in the end to put it together. In case you are not familar with the term yak shaving I highly recommend to read Don’t Shave That Yak!. Spoiler ahead, I did shave that yak!

So what happened? Luckily, I took notes while implementing the solution. This is how they look

1
2
# create a new 'caddy' binary with 'exec' module
xcaddy build --with github.com/abiosoft/caddy-exec@8d34c546e3f0aa43ba803955e7d5dd2bc7bb3780
1
2
3
4
5
6
7
8
9
ghostletters.xyz {
  route {
    # update hugo blog
    exec /<long secret path> sh /home/caddy/refresh_blog.sh
    
    # for all other pathes redirect to blog
    redir https://blog.ghostletters.xyz{uri}
  }
}
1
2
3
4
5
6
7
8
9
#!/bin/sh
set -xe

cd /home/user/github/blog
git pull

hugo --destination /home/caddy/blog

touch /home/user/blog_refreshed.txt      # optional

I struggled with installing the Exec module. Also I encountered some weird behaviour where I could run the script, but when caddy executed the same script, the cp (copy) command produced some read only file-system errors. Anyway, in the end it worked and now my Hugo-based blog updates in less than 1 seconds.

Happy Easter.

Comments

You can use your Mastodon account to reply to this post.

Reply