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.

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.

  1. On the server:
    1. Add my public SSH key to the ~/.ssh/authorized\_keys file. This gives me the ability to push to the repos on this user.
    2. Set up a bare Git respository for the website source files with git init --bare website.git.
  2. On my computer:
    1. Do git remote add deploy to add the bare server repo as a remote.
    2. The bare repository on the server doesn’t have anything in it, so I push the website to it with git push deploy.

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.

  1. Download Hugo.
  2. Clone the Git repository with git clone website.git website.
    1. 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 called website containing the “client” repo that pulls files from the “bare” repo.
  3. Create the file ~/website.git/.git/hooks/post-receive in the “bare” repo.
  4. 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:


# 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
rm -rf public

# Deploy
rsync -a public/ $DEPLOY_DIR --delete-after

With this post-receive script, pushing to the server will automatically build and deploy the website.


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.