| Crates.io | system-hook |
| lib.rs | system-hook |
| version | 0.2.0 |
| created_at | 2023-04-09 02:25:11.010379+00 |
| updated_at | 2025-05-16 07:10:09.441861+00 |
| description | shook: webhook server to automatically update production servers |
| homepage | https://github.com/beaconbrigade/system-hook |
| repository | https://github.com/beaconbrigade/system-hook.git |
| max_upload_size | |
| id | 833892 |
| size | 86,022 |
system-hookshook at its core is a web server that listens for webhooks from Github
and then will automatically pull new changes to your repository and restart
your production servers with the new code. Shook assumes your server is running
through systemd and will automatically pull new changes and restart the service.
note: shook is designed to run on linux systems that use systemd.
shook can be installed using cargo-binstall:
cargo binstall system-hook
shook can be downloaded from Github Releases
shook can be built from source using cargo:
cargo install system-hook
Or, locally:
git clone https://github.com/beaconbrigade/system-hook.git
cd system-hook
cargo build --release
shook has three main commands: init, serve and daemon. To prepare shook
navigate to the repository you want to watch, and run sudo shook init. Sidenote: shook
usually needs to run as root because it interacts with systemctl or needs to write
files in the /etc/systemd/system/ directory. shook will guide you through creating a config
and it will generate the shook.toml in your repository's directory and /etc/systemd/system/shook.service.
The shook.toml file tells shook how to run.
After generating a shook.toml, shook can be run using shook serve which starts the server
in your terminal, or by running sudo shook daemon . start which starts the shook systemd service.
For testing out shook it is good to play with shook serve, you can use command line arguments
to augment values in the shook.toml file. When running in production it would probably be more helpful
to run sudo shook daemon . enable so shook is started when your computer starts. Note: shook daemon
just runs systemctl start, stop and enable under the hood, so you can bypass shook and run those
directly if you want.
nginxIf your main server is running behind nginx, your webhook proxy might look like this:
http {
server {
# example route to serve static files
location / {
root /www-data;
}
# proxy `shook` behind nginx
location /webhook {
# remove the '/webhook' part of the url so requests to https://yourserver.com/webhook
# are POSTed to '/' on `shook` (as it expects).
rewrite /webhook(.*) /$1 break;
# pass requests onto `shook`
proxy_pass http://unix://var/run/shook.sock;
}
}
}
As a side note, it can be really handy to test if your webhook server is working. You can use the
Github CLI to help with this. Refer to here
to set up webhook testing. To test shook I created a test repository on Github with a script
update.sh that appends data to the README.md file, then commits and pushes. Then, running shook serve --log-level=trace
in one terminal, gh webhook ... in another and ./update.sh in a third you can test your deployment.
shook creates its own systemd service to start listening for events. The shook service simply runs
shook serve from the right directory and sets a default logging level and log file to /var/log/shook.log.
The github-webhook-extract crate provides route extractors for a Github webhook event (note: github-webhook-extract supports
very few events at the moment). The text-completions crate provides environment variable and path tab
completions for the shook init command.
shook initThe init command will generate both the systemd service file for shook and the shook.toml for
your repository. The values for each config value can be optionally passed by command line, and if
they aren't present, they will be read from stdin using dialoguer.
The init command will store each config value in shook.toml stored in your given repositories directory.
The shook.service file generated by shook will invoke shook serve setting the log file to /var/log/shook.log
and will also put the working directory to your repositories path.
shook serveThe serve command will read the shook.toml file to configure itself. When the server receives a POST message
it will extract a Github payload from it, and then check if the event matches the allowed events in your config.
If there's a match, it will then use git to pull the most recent changes then systemctl restart your
service. Each config field influences the server, here's an example:
username = "rcullen"
repo_path = "/home/rcullen/rust/test-webhooks"
remote = "origin"
branch = "master"
system_name = "test-restart"
update_events = ["push"]
socket_group = "www-data"
socket_user = "www-data"
pre_restart_command = ":"
shook_service_name = "shook.service"
[addr]
type = "Unix"
value = "/var/run/shook.sock"
shook will su to this user to run git pull so that the proper https or ssh verification is
applied.shook will use this directory as its working directory, pull changes here, and find the shook.toml
here.shook will pull from with git it is the origin in git pull origin mainshook will try to pull fromshook will restart when it receives a webhook payloadshook will pull code after receivingshook is configured to listen on a unix socket, it will chgrp the socket to this groupshook is configured to listen on a unix socket, it will chown the socket to this userFinal note: if shook serves through a unix socket, it will chmod the socket with 0o666.
shook daemonThe daemon command is a simple proxy over systemctl. It can be easily bypassed without causing any harm.