Deploying Hugo on NearlyFreeSpeech.NET with Git
Published: 2020-08-23 14:20:24

---
title: Deploying Hugo on NearlyFreeSpeech.NET with Git
published: true
date: 2018-12-12 22:30:00 UTC
tags: 
canonical_url: https://www.euantorano.co.uk/posts/hugo-git-deployment-nearly-free-speech/
---

I’ve been hosting this site with [NearlyFreeSpeech.NET](https://www.nearlyfreespeech.net) for a little over 2 years now, and have been using Hugo to generate it for slightly longer. I decided it might be a good idea to dump my setup somewhere so that I can refer back to it at a later date, and since I’m doing so I may as well make the details public as a post.

## Installing Hugo on NearlyFreeSpeech

The first step is to install the Hugo binary on NearlyFreeSpeech. I personally use a simple bash script to do this which allows me to bump the version used when needed and simply re-run it to upgrade:

```
#!/usr/bin/env sh

set -ex
VERSION=0.74.3
FILENAME="hugo_${VERSION}_FreeBSD-64bit.tar.gz"
BIN_DIR=$HOME/bin
mkdir -p "${BIN_DIR}"
fetch -q -o hugo.tar.gz "https://github.com/gohugoio/hugo/releases/download/v${VERSION}/${FILENAME}"
tar -C "${BIN_DIR}" -xvzf hugo.tar.gz hugo
rm hugo.tar.gz

```

This downloads the FreeBSD x64 version `0.74.3` of Hugo from the GitHub release, grabs the `hugo` binary from the archive and drops it into `$HOME/bin/hugo` and then cleans up the download.

Personally, I don’t add Hugo to my `$PATH`, as the only time I actually interact with it is via a Git hook - more on that below…

## Setting up a Git repository on NearlyFreeSpeech

I deploy the site to the server using Git - I simply add the repository on my NearlyFreeSpeech server as a Git remote (`nfsn`) and whenever I want to push an update to the site it’s as simple as a `git push nfsn master`.

### Create the repository on the server

First step is to create an empty Git repository on the server. I name this repository `euantorano.co.uk.git`, but obviously this should be changed if your site isn’t called that…

```
cd $HOME
mkdir euantorano.co.uk.git
cd euantorano.co.uk.git
git init --bare

```

### Create a checkout directory for the commit hook to make use of

Next we need to create a directory on the server that will contain a checkout of the repository that Hugo will work on:

```
cd $HOME
mkdir euantorano.co.uk.checkout
cd euantorano.co.uk.checkout
git clone $HOME/euantorano.co.uk.git

```

### Create the Git `post-receive` hook

The final step on the server is to add a `post-receive` hook to the Git repository on the server. This hook will run after a `git push` occurs, and will checkout the Git repository to the above checkout directory, then run Hugo to publish the updated site.

First, create the hook file and make it executable:

```
cd $HOME/euantorano.co.uk.git
touch hooks/post-receive
chmod ug+x hooks/post-receive

```

Next it’s time to actually write the hook script:

```
#!/bin/bash

set -ex
SITE_CHECKOUT=$HOME/euantorano.co.uk.checkout
GIT_DIR=$SITE_CHECKOUT/.git
PUBLIC_WWW=/home/public
cd $SITE_CHECKOUT
git --git-dir=$GIT_DIR pull -f
$HOME/bin/hugo --cleanDestinationDir --minify -d $PUBLIC_WWW
exit

```

This script first navigates to the site checkout directory (`$HOME/euantorano.co.uk.checkout`), then pulls the latest copy of the site source. Finally, it builds the site using Hugo, outputting the generated content to the public website directory. I also personally enable Hugo’s built in minifier to strip insignificant whitespace from the generated HTML.

### Add the new remote to your local repository

In order to be able to push to the server, you need to add a new Git remote to your local repository containing your site:

```
git remote add nfsn user@server:/home/private/euantorano.co.uk.git

```

Obviously, `user` and `server` depend on your NearlyFreeSpeech username and server name - both of these can be found in the NearlyFreeSpeech.NET Member Interface under the `sites` tab within the `SSH/SFTP Information`.

## Deploying an update

Now that Hugo is installed and the Git hook is configured, updating the site is as simple as:

```
git commit -m "..."
git push nfsn master

```

The Git push proceeds as normal, then runs the `post-receive` hook which echos out all that it does (thanks to the `set -x` flag we included):

```
Enumerating objects: 16, done.
Counting objects: 100% (16/16), done.
Delta compression using up to 8 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (10/10), 3.77 KiB | 3.77 MiB/s, done.
Total 10 (delta 5), reused 0 (delta 0)
remote: + SITE_CHECKOUT=/home/private/euantorano.co.uk.checkout
remote: + GIT_DIR=/home/private/euantorano.co.uk.checkout/.git
remote: + PUBLIC_WWW=/home/public
remote: + cd /home/private/euantorano.co.uk.checkout
remote: + git --git-dir=/home/private/euantorano.co.uk.checkout/.git pull -f
remote: From /home/private/euantorano.co.uk
remote: ef9d151..7afb7dd master -> origin/master
remote: Updating ef9d151..7afb7dd
remote: + /home/private/bin/hugo --cleanDestinationDir --minify -d /home/public
remote: Building sites …
remote: | EN
remote: +------------------+----+
remote: Pages | 37
remote: Paginator pages | 0
remote: Non-page files | 0
remote: Static files | 6
remote: Processed images | 0
remote: Aliases | 11
remote: Sitemaps | 1
remote: Cleaned | 0
remote:
remote: Total in 681 ms
remote: + exit

```

Magic!