Deploy static Websites with Git
With the following I will describe how the deployment of a Hugo website is automated with git hooks. If you are interested in further details to git hooks I can recommend this tutorial from Justin Ellingwood.
Automation with Git hooks
To keep track of my website I have a local git repository and a remote one on
the webserver. For deployment there is the branch
public. Whenever there is a
commit to that branch the site is rebuilt with Hugo. If the branch
pushed to the webserver the content of the folder public within the git
repository is copied to the directory of the webserver. This is all done with
Build the Site with the pre-commit Hook
The Git hooks are located in the folder
.git/hooks/ of the repository. As we want
to build the site before the commit, we use the hook
it doesn’t exist create it and make it executable (
chmod +x pre-commit).
#!/bin/bash echo "*** Executing pre-commit hook" BRANCH=$(git rev-parse --abbrev-ref HEAD) if [ "$BRANCH" != "public" ]; then echo "Not on branch public." exit 0 fi echo "Cleaning public directory.." rm -r public/* echo "Rebuild site.." hugo if [ $? -ne 0 ]; then echo "Website build failed!" echo "Aborting commit." exit 1 fi git add public/. echo "Site built and added to commit." exit 0
If there is a commit to the branch
public this script cleans the public
directory (as Hugo won’t delete possibly removed files there) and rebuild the
site with Hugo. If the rebuild fails the commit is aborted.
Deploy the Site with the post-receive Hook
To deploy the site the hook
my_repo.git/hooks/post-receive (from the remote
repository at the webserver) is used. If it doesn’t exist create it and make it
executable like above.
#!/bin/bash # # git post-reveive hook for (Hugo) website deployment # WORKDIR='/var/www/my_site' PUBLICDIR="$WORKDIR/html" BACKUPDIR="$WORKDIR/bak" WEBUSER='my-user' WEBGROUP='www-data' while read oldrev newrev branch do if [[ $branch =~ .*/public ]];then echo "Branch public updated. Deploying website.." git --work-tree=$WORKDIR checkout -f public -- public if [ $? -eq 0 ];then if [ -d "$BACKUPDIR" ]; then rm -rf "$BACKUPDIR" fi chown $WEBUSER:$WEBGROUP $WORKDIR/public mv $PUBLICDIR $BACKUPDIR mv $WORKDIR/public $PUBLICDIR echo "Done." else echo "Checkout failed. Website not deployed." exit 1 fi fi done
If there is a push to the
public branch of the remote repository this script
- Checks out the public folder of the Hugo site from the repository to the
working directory (
- Changes its user (
WEBUSER) and group (
WEBGROUP) to ensure it can be read by the webserver.
- Deletes the old backup (
BACKUPDIR) if it exists.
- Moves the folder with the current website (
PUBLICDIR) to the backup location.
- Moves the public directory to the website folder.
If the checkout fails the deployment is aborted.
With these two scripts a Hugo website can be built automatically with a
commit and deployed with a