Setting up an nginx/Hugo Site

With git-hooks for deployment

What follows is something of a personal reminder of how I got this webserver set up, using nginx to serve a static website which is generated by Hugo using git-hooks to deploy with a simple git push. I had to read several different tutorials to figure it out; those that I can remember I have linked at relevant points.

A while later, I added HTTPS support using letsencrypt, but I’ll save that for another post since it required some more fiddling.

Hugo and nginx

DigitalOcean Tutorial

Install nginx

1sudo apt install nginx

Install Hugo

Grab the latest Hugo release from their github repo.

1wget https://github.com/gohugoio/hugo/releases/download/v0.32.3/hugo_0.32.3_Linux-32bit.deb
2sudo dpkg -i hugo*.deb

Install themes and Pygments

Clone the Hugo themes. Bit lazy, really you should just clone the ones you need.

1git clone --recursive https://github.com/spf13/hugoThemes ~/themes
2sudo pip install Pygments

nginx setup

Create the vhost file for the site:

1cd /etc/nginx
2sudo nano sites-available/web
 1#/etc/nginx/sites-available/web
 2server {
 3    listen 80;
 4    server_name mydomain.com;
 5
 6    location / {
 7        alias /home/username/public_html/;
 8        autoindex on;
 9    }
10}

And “enable” it by symlinking the file in the sites-enabled directory (removing the default vhost while we’re here):

1cd sites-enabled
2rm default
3ln -s ../sites-available/web web

Clone git repo of site

1cd ~
2git clone --bare http://www.example.com/mysite.git mysite.git
3
4mkdir public_html
5mkdir backup_html #In case things go wrong!

Deployment Setup

DigitalOcean Tutorial

The git-hooks script post-receive is triggered when the repo is pushed to. We’ll use this to automatically build and deploy the site when we push changes to the production server.

1cd ~/mysite.git/hooks
2nano post-receive
 1#!/bin/bash
 2#~/mysite.git/hooks/post-receive
 3
 4GIT_REPO=$HOME/mysite.git
 5WORKING_DIRECTORY=$HOME/my-domain-working
 6PUBLIC_WWW=$HOME/public_html
 7BACKUP_WWW=$HOME/backup_html
 8MY_DOMAIN=mydomain.com
 9
10set -e
11
12rm -rf $WORKING_DIRECTORY
13rsync -aqz $PUBLIC_WWW/ $BACKUP_WWW
14trap "echo 'A problem occurred.  Reverting to backup.'; rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY" EXIT
15
16git clone $GIT_REPO $WORKING_DIRECTORY
17rm -rf $PUBLIC_WWW/*
18/usr/local/bin/hugo -s $WORKING_DIRECTORY -d $PUBLIC_WWW -b "http://${MY_DOMAIN}"
19rm -rf $WORKING_DIRECTORY
20trap - EXIT

Finally, don’t forget to chown +x the post-receive script, else nothing will happen when you push to it.

Then on your development machine, add the bare repo as a remote like so:

1dev-system> git remote add prod [email protected]:mysite.git

Then it’s simply a case of

1dev-system> git push prod master

And your changes are (hopefully) live!