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 anymore if I can help it!

Setup

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 allowoing 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' https://github.com/spf13/hugo/releases/latest)

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

{"id":6462777,"tag_name":"v0.21","update_url":"/spf13/hugo/releases/tag/v0.21","update_authenticity_token":"6dpZZ/7wB+ge7D2f8Klr7ei491G0LOsZHfQImc8zwHr9o0WwgGsXhHt/NyBB5JmOjzFQ4rOo7ohL7flBFKnXew==","delete_url":"/spf13/hugo/releases/tag/v0.21","delete_authenticity_token":"bZltcQlCjiapVvZiGdgs0wUm5DP7bYML/0WBff1ogxA5n1WNVSNuDg20OuMqLswoeMuPBCsB1IJFapXoHI22Ng==","edit_url":"/spf13/hugo/releases/edit/v0.21"}

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=${LATEST_VERSION:1}

$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="hugo_${LATEST_VERSION_NUM_ONLY}_Linux-64bit.tar.gz"
ARTIFACT_URL="https://github.com/spf13/hugo/releases/download/${LATEST_VERSION}/${HUGO_TAR_NAME}" 

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

$ARTIFACT_URL is https://github.com/spf13/hugo/releases/download/v0.21/hugo_0.21_Linux-64bit.tar.gz

Hugo is ready to be downloaded and extracted.

wget $ARTIFACT_URL
tar -xzf $HUGO_TAR_NAME

Final steps are to move the hugo binary to /app/.bin and then clean up files we don’t need.

mv /tmp/hugo /app/.bin/hugo
rm LICENSE.md README.md $HUGO_TAR_NAME

Entire boxfile.yml


# forked from https://gist.github.com/tylerflint/c6316e7755f5a5e330c3ffe709102161
# updated to work with the latest releases of hugo
# obtaining latest release via bash from:
# https://blog.markvincze.com/download-artifacts-from-a-latest-github-release-in-sh-and-powershell/
# with additional tweaks to work with Hugo's download file naming

run.config:
  engine: static
  
  cache_dirs:
    - .bin
    
  extra_path_dirs:
    - /app/.bin
  
  extra_steps:
    # fetch hugo binary if it doesn't exist
    - |
      if [[ ! -f .bin/hugo ]]; then
        cd /tmp
        LATEST_RELEASE=$(curl -L -s -H 'Accept: application/json' https://github.com/spf13/hugo/releases/latest)
        LATEST_VERSION=$(echo $LATEST_RELEASE | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
        LATEST_VERSION_NUM_ONLY=${LATEST_VERSION:1}
        HUGO_TAR_NAME="hugo_${LATEST_VERSION_NUM_ONLY}_Linux-64bit.tar.gz"
        ARTIFACT_URL="https://github.com/spf13/hugo/releases/download/${LATEST_VERSION}/${HUGO_TAR_NAME}"  
        wget $ARTIFACT_URL
        tar -xzf $HUGO_TAR_NAME
        mv /tmp/hugo /app/.bin/hugo
        rm LICENSE.md README.md $HUGO_TAR_NAME
        cd - >/dev/null
      fi

deploy.config:
  extra_steps:
    # 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 blog.dev

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

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

--baseURL=http://blog.dev/ - 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=0.0.0.0 --baseURL=http://blog.dev/ --port=1313

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