📅 26 Jan 2021
How to automatically update a live website using git
This post is another follow-up of the howto post on a Simple.css-based Hugo-generated website. This time I want to show how you can automatically update a generated, static, self-hosted website by simply pushing commits to a git repository.
Note the modifier self-hosted in the sentence above. There are nice turnkey solutions out there that will already do that out of the box, like Netlify. So, if you’re not selfhosting or you don’t want to go through the hassle of setting everything up yourself, then such services might be more appropriate for you.
I know that most of the explanation below will be fairly trivial for regular git users. Nevertheless, I wanted to document all the steps because some of them involve fairly obscure git settings that — I at least — tend to forget quite rapidly and never seem to be able to find in the documentation. 😉
Prerequisites
This tutorial assumes that you are self-hosting your website, meaning that you at least have:
- ssh access to the webserver;
- your user account has write permissions to the local folder(s) on the server from which the website is hosted;
- next to that you should also have git installed on both your local development machine and the webhost.
Also, note that there are many ways to achieve the same end result. Below, I’ll only describe one method. Depending on your situation, that might not be the ideal solution for you. At least I hope that I can convey the basic idea so you can remix this solution into something that works for you.
Setting up the local git repository
Assuming that you are developing the website on your own laptop/desktop, make sure to put the current version of your project into a git repository. This can be done by simply running the following set of commands in the top-level directory of your Hugo/Jekyll/… project:
$ git init
Initialized empty Git repository in /home/mogwai/git/foobar/.git/
$ git add .
$ git commit -m "Initial version of my website"
[main (root-commit) d6a8479] Initial version of my website
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bar
create mode 100644 foo
That’s all for now. We’ll come back to this repository later on.
Setting up the webhost/server git repository
We begin by setting up a git repository on the webhost as well. We are going to create this repository outside of the webhosting directories. The reason is that our repository contains a Hugo/Jekyll/… project, and we only want to share the built version of the site and not our project files.
So, create a new directory somewhere (e.g. in your home directory; ~/website
), and run the following command:
$ git init
Initialized empty Git repository in /home/mogwai/website/.git/
What we want to achieve is to have our website re-built and copied into the webserver directory everytime a new commit is pushed to this repository. This will take a few steps.
The first thing to is to make sure that, when a new commit is pushed, our working copy (i.e. the contents of ~/website
) is updated automatically. This is needed because we want to build the website based on the latest version; if we can’t see those files, we can’t build it.
Git will not do this by default because in most scenarios/setups this will be a dangerous thing. Luckily, there is a simple configuration setting that will enable this. In the git directory run:
$ git config receive.denyCurrentBranch updateInstead
NOTE: In most cases you would want to create a bare repository here. But since we also need a working copy to generate our site from, we would have to create yet another, separate directory. Hence, a non-bare repository is going to be more efficient here.
Next up is to create a git hook to build and deploy the site on each new commit being pushed to this repository. In order to do that, we will create a new file .git/hooks/post-receive
. Then add the following content:
#!/bin/bash
PUBLIC_WWW=/srv/http/mogwai.be
set -e
rm -rf ${PUBLIC_WWW}/*
/usr/bin/hugo -s .. -d $PUBLIC_WWW
and make sure to replace the path that PUBLIC_WWW
refers to your webserver directory. As mentioned before, your user account on the webserver should have write permissions to this directory. Of course you can replace the hugo
command by any other static generator command. Just make sure that the output gets directed to ${PUBLIC_WWW}
.
Now make this script executable:
$ chmod +x .git/hooks/post-receive
Now we’re done with setting up the webhost configuration. Let’s return to the local development machine.
Configure the local git repository to push to the webserver
Next up is making your local development git repository aware of the repository on the webserver. We’ll do this by adding a remote and setting that as upstream.
So, in your local git repository, run:
$ git remote add www ssh://<webserver-url>/home/mogwai/website
make sure to replace /home/mogwai/website
by the actual directory of the git repository on your webserver.
Now, we’re going to push our first version to the server, while also setting that remote branch as default upstream:
$ git push -u www master
assuming that your default branch is called master
. Note that this is probably subject to change in the near future.
The output should look something like this:
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 2 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 436 bytes | 436.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Start building sites …
remote: WARN 2021/01/27 11:06:49 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
remote: WARN 2021/01/27 11:06:49 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
remote:
remote: | EN
remote: -------------------+-----
remote: Pages | 9
remote: Paginator pages | 0
remote: Non-page files | 0
remote: Static files | 7
remote: Processed images | 0
remote: Aliases | 0
remote: Sitemaps | 1
remote: Cleaned | 0
remote:
remote: Total in 80 ms
To ssh://server/home/mogwai/website
8f5dd23..4a800fd master -> master
Branch 'master' set up to track remote branch 'master' from 'www'.
Pushing site updates to the webserver
From now on, anytime you want to update the live website you can simply push your changes by running the following commands from your development machine’s git repository:
$ git add .
$ git commit
$ git push
That’s it. That’s all, folks!
References
Of course I didn’t invent the wheel here; I hardly even inflated the tires. 😉
So here are some other posts that I used as reference. These approach the problem from slightly different angles:
- https://gist.github.com/Nilpo/8ed5e44be00d6cf21f22
- https://hackernoon.com/deploy-website-to-remote-server-using-git-da6048805637
- https://toroid.org/git-website-howto
- https://stackoverflow.com/questions/3838727/git-post-receive-hook-for-website-staging
- https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04
💬 Looking for comments?
I don't have comments on this site as they're difficult to manage and take up too much time. I'd rather concentrate on producing content than managing comments.
Instead of leaving a comment, feel free to contact me ✉️ contact me instead.