Skip to main content

Setting up an nginx/Hugo Site

·2 mins

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 #

sudo apt install nginx

Install Hugo #

Grab the latest Hugo release from their github repo.

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

Install themes and Pygments #

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

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

nginx setup #

Create the vhost file for the site:

cd /etc/nginx
sudo nano sites-available/web
#/etc/nginx/sites-available/web
server {
    listen 80;
    server_name mydomain.com;

    location / {
        alias /home/username/public_html/;
        autoindex on;
    }
}

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

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

Clone git repo of site #

cd ~
git clone --bare http://www.example.com/mysite.git mysite.git

mkdir public_html
mkdir 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.

cd ~/mysite.git/hooks
nano post-receive
#!/bin/bash
#~/mysite.git/hooks/post-receive

GIT_REPO=$HOME/mysite.git
WORKING_DIRECTORY=$HOME/my-domain-working
PUBLIC_WWW=$HOME/public_html
BACKUP_WWW=$HOME/backup_html
MY_DOMAIN=mydomain.com

set -e

rm -rf $WORKING_DIRECTORY
rsync -aqz $PUBLIC_WWW/ $BACKUP_WWW
trap "echo 'A problem occurred.  Reverting to backup.'; rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY" EXIT

git clone $GIT_REPO $WORKING_DIRECTORY
rm -rf $PUBLIC_WWW/*
/usr/local/bin/hugo -s $WORKING_DIRECTORY -d $PUBLIC_WWW -b "http://${MY_DOMAIN}"
rm -rf $WORKING_DIRECTORY
trap - 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:

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

Then it’s simply a case of

dev-system> git push prod master

And your changes are (hopefully) live!