Automatically publishing websites with Hugo, Travis, and Github
Aug 26, 2017
5 minutes read

Welcome to the new an HTTPS website which is hosted for free, easy to maintain, and automatically built when I push updates to a git repository. It’s backed by Hugo, Travis-CI, GitHub, and Cloudflare.

Note: This article is out of date, as Travis-CI retired their open-source service and I moved the build to Github Actions. I’ll publish an update to this article in due time but until then, this pull request will explain the change.

Although I don’t intend for this article to be a complete how-to of launching a site like this, hopefully it gives you a basis to piece together how you can build your own.

A History

This site is rebuilt from the ashes of (defunct, now redirects to this site) with the intention to preserve links to old articles, but modernize everything else about the setup. The old site was built on Octopress, which—for a non-Ruby developer—was always problematic to build: it required unfamiliar tooling, installation of packages I didn’t otherwise need, and the typical gem and rvm foolin’ that doesn’t feel particularly worth it when you just want to update a blog post.

The Requirements

I went in with the following requirements:

  • HTTPS hosted
  • Staticaly generated
  • Built with a familar toolchain
  • Old links preserved
  • No “build” step; should be published automatically on commit/push

“Free” was not a requirement, but it ended up being (nearly) so due to the tools/services I chose.

The Tools is built using the following:

  • Hugo: a static-site generator written in Go
  • Travis-CI: a Continuous Integration (CI) service with a GitHub pages publisher out-of-the-box
  • GitHub/GitHub Pages: the ubiquitous code-hosting platform, and their free static-site-hosting service
  • Cloudflare: a service which provides a Content-Delivery Network (CDN), DNS hosting, and HTTPS termination
  • Amazon S3: a file-hosting service; here, it’s used to handle redirections for the old domain
  • Amazon Route 53: a DNS service; here, used to handle the old domain

Although I pay for many of these services for other reasons, here they are all used at their “free” tiers, with the exception of the Amazon services; those cost about $0.53 USD/month, fluctuating slightly based on usage.

The Build Process

The code for the site is hosted in a public repository on GitHub; this code contains the raw posts, configuration for Hugo, and the travis configuration which is the declarative file which tells Travis how to build the static site.

Really, you can learn the most from these two files:

Travis Configuration

The Travis configuration is the more interesting configuration; it’s embedded below, with annotations in-line:

The only other information Travis needs is your GitHub Token; you’ll want to generate one specificaly for this purpose. The Travis docs cover what access this token needs to your account. Once you have that, it just needs to be encrypted and stored in your .travis.yml, which is done with Travis’ CLI tools, run in your repository:

travis encrypt GITHUB_TOKEN=<your_token> --add env.matrix

This will encrypt the token, and insert it into your .travis.yml.

Custom Domain Setup

At this point, you should have Travis set up and auto-building your static site, and posting that build to the gh-pages branch of your repository, but not at a custom domain.

Follow the instructions at GitHub: Setting up a custom domain, which will direct you create a file in the root of your built site named CNAME. Hugo automatically puts any files in a directory named static at the root of your site; see my static directory for an example.


By now, your site should be served at your custom domain, but is not yet SSL protected. It’s time to set up your account at Cloudflare.

Once you sign up for a free account, Cloudflare will walk you through the process of setting up your domain and transferring DNS. There are only a few settings you’ll need to change after the fact:

  • Crypto > SSL: Change “Full” to “Flexible”. This will allow Cloudflare to hit GitHub’s servers without strict SSL, since its certificates won’t match your bare domain.
  • Crypto > Always use HTTPS: Change to “on”. This will redirect all HTTP requests to your domain to HTTPS.
  • Crypto > Automatic HTTPS Rewrites: Change to “on”. This will rewrite any URLs that are local to your domain over to HTTPS. Not strictly necessary, but allows you to be a little less careful with how you’re linking things. Ideally, you’ve got your domain correctly set up in your Hugo config.

With this set up, your site should be available over HTTPS in a short time.

Amazon Redirect

In order to redirect the existing, I used Amazon’s Route 53 and S3 site hosting service to redirect all URLs to; I won’t go into detail here as it’s not the primary interest; Amazon maintains a page on how to set this up.

There’s a few things to note:

Updating YAML Frontmatter

The frontmatter I was using for my Octopress posts needed some small updates. I changed it from:

layout: post
title: Fixing a Famicom Disk System
author: Nate
layout: post
  - Gaming
  - Famicom
  - repair


title: Fixing a Famicom Disk System
date: 2010-03-21T12:00:00-07:00
  - Gaming
  - Famicom
  - repair

Specifically, Hugo requires a strict ISO-8601 date, whereas Octopress was more permissive. URLs appear to be generated in the same manner between the two, so nothing was changed there.

Matching URLs

I needed to add the following to my Hugo config.toml to the permalinks matched the previous format:

blog = "blog/:year/:month/:day/:title/"

Other Reading

Back to posts