Fast Website Deployment, Previews and TLS with Hugo & Netlify

I’ve been a “Wordpress does the trick” guy. But only until recently, when I’ve started hearing more and more about static website generators, such as Hugo, Jekyll, Gatsby and others, which are, apparently, taking over the webpage space.

I’ve used Jekyll before, so I am very familiar with the static generator concept, but I haven’t expected it to pick up it’s popularity so fast, that even big companies and communities, such as kubernetes.io, datadog.com and many others would actually use it as a part of their marketing and branding efforts.

So I decided to give it a try. I had a personal profile page on about.me, which became a great candidate for transplantation. In addition to it I was aspiring to recover my blogging habit, aka “Second Head” style blog, which used to be hosted on Wordpress and had gone south since.

Goals

In this post you will learn how to deploy a simple Hugo website to Netlify in less than 10 minutes. (Just wait for the DNS records to propagate for the best results).

Assumptions and Constants

The scope of this post assumes the following:

  • You have a free Netlify account.
  • You have a free GitHub account.
  • You have a domain name and access to it’s DNS configuration. iwantmyname.com or namecheap.com could be good options.
  • Console commands are performed in MacOS terminal with Homebrew installed (can be easily adopted to Linux or Windows).
  • For the sake of this post, website’s domain is automationd.com.
  • For the sake of this post github repo that we will create will have this git url git@github.com:AutomationD/automationd.com.git

1. Create a Hugo Website

Thankfully there is a homebrew package for Hugo. Installation is as simple as:

brew install hugo

Hugo comes with tons of built-in tools, so in order to create a new website you need to run the following command (where automaitond-com is an arbitrary name that we will use as a safe name later on)

hugo new site automationd.com

There is an official Quick Start Guide, which I’ve personally used

  1. Browse themes.gohugo.io and pick a theme. I picked LoveIt.
  2. Copy a link from a “Download” button (looks like https://github.com/dillonzq/LoveIt.git)
  3. Install it:
cd automationd.com
git init
git submodule add https://github.com/dillonzq/LoveIt.git themes/LoveIt

# Enable the theme in Hugo's config
echo 'theme = "LoveIt"' >> config.toml

This part was a bit unclear to me initially, but each theme has it’s own set of mandatory config options that have to exist in the config.toml in order for Hugo to be able to render it. Typically there is a sample config file located in the theme repo. LoveIt has one too.

What you need to do is to:

  • Copy this file into your root directly (replacing the default one)
  • Personalize config.toml. I’m sure you’ll find a way to apply your creativity here. If there is anything specific that is not self-explanatory, orm aybe even it deserves a separate post? Feel free to drop a comment below.

The beauty of Hugo is that it gives you ability to livereload your changes.

hugo server -D

This will produce an url, something like http://localhost:1313/. Open this address in your browser and behold your new website.

It is working locally. But the issue is that you won’t be able to serve your website to tens of thousands of your visitors just from your laptop. So we need to find a decent hosting solution.

Ideally, it should cause as less pain as possible, and, also have a build-in CI/CD, CDN as well as TLS form LetsEncrypt. Also, it should be free for personal use and be able to scale if you decide to grow into commercial scale.

Well, the good news is that there are multiple options available today, and I’ve chosen to give Netlify a try (as you probably have guessed).

2. CI/CD for a Static Website on Netlify

Netlify allows you to have a closed-loop CI/CD, which means that not just every commit will be automatically built and deployed to your designated domain, but also pull requests and branches will get a very special treatment and get deployed separately as well.

As in any decent CI/CD implementation, you get rollbacks, build flags and environment variables. But first, you need to get a github repo.

Netlify works with Github, Gitlab and BitBucket out-of-the-box. Let’s create a private Github repository for seamless deployment to Netlify to work.

/static-website-with-cicd-cdn-tls-hugo-on-netlify/b8deb381.png

Create netlify.toml in the root of the repo. This file will tell Netlify how to build your Hugo website. Here’s a sample config file that I was able to find on the internet. Feel free to take it as a base

[build]
publish = "public"
command = "hugo --gc --minify"

[context.production.environment]
HUGO_VERSION = "0.67.1"
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"
GIT_LFS_ENABLED = "true"

[context.split1]
command = "hugo --gc --minify --enableGitInfo"

[context.split1.environment]
HUGO_VERSION = "0.67.1"
HUGO_ENV = "production"

[context.deploy-preview]
command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"


[context.deploy-preview.environment]
HUGO_VERSION = "0.67.1"
GIT_LFS_ENABLED = "true"

[context.branch-deploy]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"

[context.branch-deploy.environment]
HUGO_VERSION = "0.67.1"

[context.next.environment]
HUGO_ENABLEGITINFO = "true"

Git Large File Storage (LFS) replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server like GitHub.com. This allows you not to bloat your git repo, as without lfs git would store a binary file in each revision as a blob.

brew install git-lfs
git lfs install
git lfs

You will need to set GIT_LFS_ENABLED to true in order to make it work on Netlify:

/static-website-with-cicd-cdn-tls-hugo-on-netlify/1cc03894.png

Add a remote for your repo, commit your code and push it to your new repository. For now, we’ll be pushing directly to master.

git add .
git commit -m "Initial"
git remote add origin git@github.com:AutomationD/automationd.com.git
git push --set upstream origin master

Click on GitHub, select Authorize and choose your repo where you have your Hugo website.

/static-website-with-cicd-cdn-tls-hugo-on-netlify/bd61d3f9.png

Since we’ve created netlify.toml, Netlify should pick up basic build config automatically.

/static-website-with-cicd-cdn-tls-hugo-on-netlify/654d6e66.png

Add a custom domain

/static-website-with-cicd-cdn-tls-hugo-on-netlify/c78afcc8.png
/static-website-with-cicd-cdn-tls-hugo-on-netlify/b5981318.png

Netlify uses NS1 underneath, so in order for you to be able to use magical branching and PR review features of Netlify you would need to change your DNS on your domain to point to Netlify’s (in fact NS1’s) NS servers.

/static-website-with-cicd-cdn-tls-hugo-on-netlify/4391f9d2.png
/static-website-with-cicd-cdn-tls-hugo-on-netlify/eace0dff.png
Change your current NS records to these that you would see in your Netlify account, wait about 24 hours (or less), and viola, your website will be reachable via your domain name (automationd.com in my case)!

Now, when you have Netlify manage your DNS records you can utilize branch and preview deploys. I love this feature, because when I want to create a blog post like this I can branch off master, add my markdown files, media, push it to Github and create a PR. Netlify will trigger a preview build/deploy and generate a unique subdomain for that specific PR. I can review how my post looks when deployed as well as observe how CDN works and so on without disturbing the main site.

Obviously, the changes can be even bigger than just a new post, which makes this approach even more handy.

Conclusion

That’s about it for now! I am planning to post more about Hugo, CI/CD, Site Reliability and DevOps in general. If you have any suggestions - let me know in the comments.

This is my first come-back post, and I would love to hear any feedback on the format, content or anything else related. Moreover, if you have found even a tiny portion of it, please share it on social networks or leave a comment! I would highly appreciate it!

Disclamer
This post is has not been sponsored by GitHub, Netlify or any other brand or service mentioned in it. I’m sharing it solely in hopes to make a working process helpful to other people.

Related Content