Deploying Hugo With Netlify

I admit I had not paid much attention to Netlify earlier. It sort of seemed like yet another web performance related startup.

But on reading Fatih’s article on hosting Hugo on Netlify, it piqued my interest. A CDN/hosting service which puts your content in caches all around the world, and triggers Hugo (and bunch of other common scripts) on Github commits? And all this for free? Sounds too good to be true, and memories of Posterous floated in my mind.

But again, the best part of using static blogging software like Hugo, is that there is so less to lose from trying out a new hosting option - no databases to setup, no old content to migrate.

And so i decided to try it out as well. And it turned out to be blindingly simple! Netlify turned out to be awesome!

Here are all the stuff I needed to do to move my Hugo hosting from my shared hosting account at Dreamhost to Netlify.


Steps:

  1. Create account and link to Github
  2. Setting up a custom domain
  3. Setting up SSL
  4. Setting up preview website
  5. Tweaks for Hugo

I first created an account of Netlify, and after logging in, I set up access to Github. If you use the “Login using Github” option while signing up, I suspect that both the account creation and Github linking will happen at the same time. I prefer using a distinct email based account in every site, for various reasons.

After linking to Github, there was an option presented to choose an existing repository to pick up changes from, and since I was already pushing the source of my Hugo site to Github, this wasn’t much trouble. I was asked the command to build (I used hugo), and the directory where the static content is to be generated (I used the default public/). And that was it!

Netlify picked up my changes and created a random host name under the netlify.com and published it there!

Netlify: Master publish

An interesting thing is that my Hugo source uses themes as Git submodules. Netlify checked out these theme submodules before running Hugo. Neat!

Setting up a custom domain

Netlify lets you point a custom domain to your hosted website for free! Crazy! All I had to do was to log in to my DNS provider, remove the A record for my earlier website, and add a CNAME instead to the random hostname on which Netlify was hosting my website.

$ dig  blog.sandipb.net

...
;; ANSWER SECTION:
blog.sandipb.net.   3582    IN  CNAME   awesome-blackwell-069f9b.netlify.com.
awesome-blackwell-069f9b.netlify.com. 2 IN A    35.199.180.1

Within a few minutes, I could already see my content on Netlify! I tried to use a curl from various servers to believe my eyes!

$ curl -sI https://blog.sandipb.net/
HTTP/1.1 200 OK
Cache-Control: public, max-age=0, must-revalidate
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Mon, 29 Jan 2018 06:02:15 GMT
Etag: "98934c8fe85d0e8c73379da28cedef89-ssl"
Strict-Transport-Security: max-age=31536000
Age: 1
Connection: keep-alive
Server: Netlify          <<<<-------

As an aside, you can change the hostname under netlify.com domain as well, but since the only characters allowed as alphanumeric+underscore, you can’t get too creative here. Interestingly, even though I changed my Netlify hostname, the DNS setup didn’t break. Netlify still keeps the original random hostname alive. Nice.

$ dig +short blog.sandipb.net
awesome-blackwell-069f9b.netlify.com.
104.198.106.181

$ dig +short awesome-blackwell-069f9b.netlify.com.
104.198.106.181

$ dig +short blog-sandipb-net.netlify.com.
104.198.106.181

All this was nice and good, but there were a few more details to sew up!

Setting up SSL

Just like my previous hosting provider, Dreamhost and many other hosting providers nowadays, Netlify has automated Lets Encrypt SSL sourcing and installation features. Within a few minutes, my site was running on SSL.

BTW, if you choose to only use your xxx.netlify.com hostname, you don’t need this, because Netlify uses a wild-carded SSL certificate for all their sub-domains.

There was also an option to force HTTPS for the website, which I of course turned on.

Chrome showed a niggling security warning about a resource being insecure, and I hunted down and found out that the badge I pull in from Feedburner had a non-https URL. Fixing that and committing to Github, caused Netlify to rebuild, and within a few minutes, the site was completely free of SSL warnings.

Setting up preview website

A fantastic feature that Netlify offers, again for free, was an automatic staging website to preview pull requests and branch changes.

If you have a pull request on your master branch, there would automatically be a build done on it, and made viewable on a unique hostname created from the commit id. You can view the final changes, and proceed to Github to merge it in.

You also have the option to set up one or more dev/staging branches, all of which will get automatic previews on every commit.

There were some niggling UI issue in configuring this though. The UI provides a weird combination of dropdown+text field to specify the branches. The dropdown is empty by default, you are actually expected to type in the branch name, even if it already exists on the repository.

In any case, previews will start happening from the next commit to the branch, and not automatically from the present content.

Tweaks for Hugo

As Fatih mentions in his post, there is an apparent conflict between Hugo configuration and how the preview system works.

You might be using a baseurl of / for links to work locally using relative URLs. But you might want the production baseurl to be that of the website address so that all links are absolute.

This doesn’t work very well with the default set up in Netlify because the domain name for previews are random, and the production baseurl is different.

One way Fatih suggests is to use Netlify configuration files. These files allow you to change environment variables based on the deployment context - production or deploy-preview.

Hugo allows all its main site configuration variables to be overridden by environment variables (Reference).

Also, Netlify allows you to specify the Hugo version to use for building.

Since I mostly use Hugo via Homebrew which keeps the Hugo version pretty up to date, I specified the Hugo version in the configuration file as well.

So this is the final netlify.toml file that I currently use, which is pretty much the same that Fatih proposed.

[context.production.environment]
  HUGO_VERSION = "0.30"
  HUGO_BASEURL = "https://blog.sandipb.net/"


[context.deploy-preview.environment]
  HUGO_VERSION = "0.30"

Update: One thing I found out, was that while each pull request and each commit to a non-master branch got an unique hostname for the preview, Netlify also maintains a constant hostname for every branch. For example, for my dev branch on the website blog-sandipb-net.netlify.com, there is always a preview site at https://dev--blog-sandipb-net.netlify.com/ with a build off the top of this branch. So, I could actually make absolute links work in the deploy-preview environment as well by specifying the HUGO_BASEURL environment variable in netlify.toml.

techblogging
Settling on Vscode for Go Using Zap - Simple use cases