Bits of Geekery

Running Hugo on Nanobox for local dev

My previous post helped those running Solus Linux to install the Nanobox client, now it’s time to do some work! This blog is a static site generated by Hugo, let’s move that over to Nanobox so we don’t have to touch a server again. Check out their new pricing, I won’t be managing servers any more if I can help it!


In order to use hugo it first must be installed, this can be accomplished within the boxfile.yml file.

Note: I am working on moving this over to an engine. Nanobox engines are open source allowing me to easily accomplish this. Once I have it accepted, I will add a new blog post covering it and link it here.

boxfile.yml setup

The best approach in my mind, is to cover my boxfile.yml changes in small enough chunks to properly explain what is going on. At the bottom of this section I will paste the entire file.

I based this off Tyler Flint’s gist that installs Hugo but is bound to a specific version. Always installing the most recent version makes the most sense to me, but I needed the Github API to find out the download path. Mark Vincze posted about how to accomplish this in sh and powershell. Due to how Hugo names its downloads, I had to tweak the URL / file names.

LATEST_RELEASE=$(curl -L -s -H 'Accept: application/json'

$LATEST_RELEASE will be populated with the meta data for the latest hugo release. Example response below:


The latest version in tag format needs to be extracted from the $LATEST_RELEASE json payload. The specific key is tag_name.

LATEST_VERSION=$(echo $LATEST_RELEASE | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')

$LATEST_VERSION now contains v0.21.

Due to how the Hugo project names its downloads, we need the latest tag without the v prefix.


$LATEST_VERSION_NUM_ONLY has a value of 0.21.

Next the name of the Hugo file to download is built, and the URL to download the file from is constructed.


$HUGO_TAR_NAME would be hugo_0.21_Linux-64bit.tar.gz


Hugo is ready to be downloaded and extracted.

mv /tmp/hugo /app/.bin/hugo

Entire boxfile.yml

# forked from
# updated to work with the latest releases of hugo
# obtaining latest release via bash from:
# with additional tweaks to work with Hugo's download file naming

  engine: static
    - .bin
    - /app/.bin
    # fetch hugo binary if it doesn't exist
    - |
      if [[! -f .bin/hugo]]; then
        cd /tmp
        LATEST_RELEASE=$(curl -L -s -H 'Accept: application/json'
        LATEST_VERSION=$(echo $LATEST_RELEASE | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
        wget $ARTIFACT_URL
        tar -xzf $HUGO_TAR_NAME
        mv /tmp/hugo /app/.bin/hugo
        rm $HUGO_TAR_NAME
        cd - >/dev/null

    # generate the site
    - hugo

Launching the blog for local dev

Copy boxfile.yml to the root of the project directory, and then add a DNS entry so you don’t need to use the IP address. I love this small feature!

nanobox dns add local

When Hugo is launched it requires a few arguments to ensure images/stylesheets/js are served correctly.

--bind= – This binds the Hugo server to all network interfaces, not only localhost.

--baseURL= – The URL to use for creating links/imports/etc. This must match the DNS entry created earlier.

--port=1313 – I am being explicit with the port number, you probably won’t need this argument.

Just launch it already!

nanobox run hugo server --bind= --baseURL= --port=1313

Enjoy your Nanobox equipped Hugo development environment. Check back soon, as we launch it live on Linode in the next post!

Frank Kumro
Hi, my name is Frank Kumro. Writing Elixir and building hardware projects is a passion of mine. I enjoy sharing what I learn and hope it inspires others to do the same.