Simple Website CI
Continuous integration using only a Git hook
This is how running git push deploy
automatically builds my website on the server and deploys it.
- I build my website with the static site generator Hugo.
- I host my website anywhere, currently renting from Hetzner for €5 per month.
- I have the website Git repository on the server, and I use that repo as a Git remote on my computer.
- The server has a Git hook that runs a script when I push to the repo.
- The script builds the website with Hugo, and copies it to the public html folder, making it go live.
When I want to deploy the latest version of the website I just do git push deploy
to push to the server’s Git. My changes go live after a few seconds thanks to the hook and the script.
Since the server builds the website, the website can be updated from any device with Git, even phones.
Details About My Setup
Here are some details about my setup.
Pushing to the Server
This is how I set up so I can push to the server.
- On the server:
- Add my public SSH key to the
~/.ssh/authorized\_keys
file. This gives me the ability to push to the repos on this user. - Set up a bare Git respository for the website source files with
git init --bare website.git
.
- Add my public SSH key to the
- On my computer:
- Do
git remote add deploy user@orsvarn.com:website.git
to add the bare server repo as a remote. - The bare repository on the server doesn’t have anything in it, so I push the website to it with
git push deploy
.
- Do
Now the Git remote on the server is set up.
Git Hook to Build & Deploy
Let’s set up the Git hook and the script that builds and deploys the website. All these steps are done on the server.
- Download Hugo.
- Clone the Git repository with
git clone website.git website
.- Note: The bare repository holds all the Git stuff, but does not have a working copy. This step allows the server to actually access the files in its repository. After this step there are two folders, one called
website.git
containing the “bare” repo, and one calledwebsite
containing the “client” repo that pulls files from the “bare” repo.
- Note: The bare repository holds all the Git stuff, but does not have a working copy. This step allows the server to actually access the files in its repository. After this step there are two folders, one called
- Create the file
~/website.git/.git/hooks/post-receive
in the “bare” repo. - Write a script in the new hook file to pull the latest version, build it, and copy it to the public website folder.
This is the script I use:
#!/bin/bash
# Constants
declare REPO_DIR=/home/git/website
declare DEPLOY_DIR=/var/www/website
# Checkout files
git work-tree=$REPO_DIR --git-dir=“$REPO_DIR.git” checkout -f
# Build
cd $REPO_DIR
rm -rf public
./home/git/bin/hugo
# Deploy
rsync -a public/ $DEPLOY_DIR --delete-after
With this post-receive script, pushing to the server will automatically build and deploy the website.
Conclusion
This setup makes it easy to update my website. I don’t rely on any tools that can be taken from me, or services that can be shut down by someone else.
I’m confident the setup will keep working for tens of years, which gives me peace of mind.
Send comments via email or Mastodon.
Thanks
- This post is a response to Lu’s post about hosting options: https://www.todepond.com/wikiblogarden/my-wikiblogarden/hosting/rubbish-options/
- Thanks to iliazeus for posting that there are Git clients and Markdown editors for phones: https://lor.sh/@iliazeus/111384898270207362