How to create a static website using HUGO on Heroku

Matheus Villela Torres
6 min readJun 5, 2022
HUGO and Heroku logos.

Intro

I recently discovered HUGO (https://gohugo.io/), a static website generator, written in Go and easy to use. The main advantage of using HUGO is the speed and practicality to create websites and personal blogs.

With the site generated, comes the question, where to host it? That’s where Heroku (https://www.heroku.com/) comes in, a cloud application hosting service. The most interesting thing about this platform is that it offers between 550–1,000 hours* of free hosting per month, meaning you won’t have to pay to host your website.

Heroku does not currently support using HUGO directly, so to get around this problem, we will create a Docker image with the necessary settings for it to be booted by Heroku.

Prerequisites

To perform this tutorial, you will need:

Steps

  1. Create a new website using HUGO
  2. Link to GitHub**
  3. Create app on Heroku
  4. Download a Hugo theme and update config.toml
  5. Create the Dockerfile and heroku.yml files
  6. Test HUGO locally**
  7. Commit changes
  8. Upload image to Heroku
  9. Push changes
  10. Website access

BONUS — Custom domain with SSL

Hands-On

1. Create a new website using HUGO

First we will create a new site by the CLI (command-line interface).

Open your computer’s terminal (cmd on windows, terminal on linux and mac) and go to the folder where you would like to create your website.

In my case, I will create in the Documents folder.

Commands:

Command “hugo new site myhugosite” response.

2. Link to GitHub**

In the folder created by HUGO, initialize git and associate it with the repository on GitHub, which must be created before adding the remote.

Example of how to create repository on GitHub.

3. Creat app on Heroku

To create an app on Heroku, we can use both the graphical interface and the CLI, in this case, I’m using the CLI because it’s simpler. Having created the account on Heroku and installed the CLI, simply enter the commands below.

Command “heroku apps:create myhugosite” response.

Note that I’m logging in Heroku, creating an app called myhugosite and linking it to the repository that Heroku makes available to us.

4. Download a Hugo theme and update config.toml

In this step, your folder should have the following structure:

App structure created by Hugo.

If didn’t go through step 2, the difference is that you will not have the README.md and .gitignore files.

For this tutorial, let’s use hugo-cohub theme, to search for other themes, just visit https://jamstackthemes.dev/#ssg=hugo or https://themes.gohugo.io

By HUGO’s default, the themes must be cloned in the themes folder, so I’m passing the path themes/hugo-cohub. Note that I am removing .git from the cloned repository, I do this just so I don’t get references from other projects.

Now, let’s update config.toml file for our project. Note baseURL and theme fields. These are important for the correct use of the theme, the first one refers to the url generated by Heroku, the default is https://<appname>.herokuapp.com, in this case the url is https://myhugosite.herokuapp.com. The second refers to the name of the folder where the theme is located, in this case it is hugo-cohub (you don’t need to refer the themes path). The other settings are self-explanatory.

5. Create Dockerfile and heroku.yml files

We will now create a file called Dockerfile in the root of the app folder.

Dockerfile

Explaining: I’m using the debian:stable-slim image, copying all my files from the local folder (.) to the /src folder. After the copy, I install hugo clean the unnecessary files, create the hugo user, set the /src path as the default for the container and finally start hugo.

The next step is to create heroku.yml, this is the file that the platform will use to run the build and run steps. Documentation on how to write a heroku.yml is available at:

https://devcenter.heroku.com/articles/build-docker-images-heroku-yml.

heroku.yml

Explaining: The first step to be performed is to build the image according to the Dockerfile, we name the generated image as web. In the next step, run, we run the command on the web image.

Arguments:
bind=0.0.0.0 → Bind the connection interface to the server (default “127.0.0.1”), if not set to “0.0.0.0” Heroku will not be able to access the server.

port=$PORT → Heroku assigns a random port to your Dyno, but makes that value available as an environment variable (default “1313”).

appendPort=false → If you don’t change it to false, all the links references will come with the port number, causing an error in directing and accessing links (default “true”).

baseURL=https://myhugosite.herokuapp.com/ → hostname (and path) to the root, as we are using Heroku, we need to update according to the URL it offers us.

File structure.

6. Test HUGO locally**

To test locally we will copy the contents of the hugo-cohub/exampleSite theme folders to the folders of the structure generated by Hugo. After copying, just start the server with hugo server command.

If all goes well, you will be able to access your site locally at http://localhost:1313/

7. Commit changes

8. Upload image to Heroku

According to heroku’s documentation, to push the container Heroku’s registry, just hit the commands below:

9. Push changes

To make changes to your site, simply save the changes locally, commit, and push to Heroku.

If you performed step 2, we can configure Heroku to perform the deployments for each push you make to a branch.

Deployment configuration via GitHub.
Enabling automatic deployment from main branch.

10. Website access

To access the site, just wait for the build and deploy and access the link generated by Heroku (https://<appname>.herokuapp.com) or click on “Open app” button on your app’s Overview page.

Overview page.

BONUS — Custom domain with SSL

1. Domain purchase

It is possible to use domains from several registrars, a famous example is GoDaddy, where it offers domains of various types.

2. DNS Configuration

First we will need to add a domain through the Settings tab of your app on Heroku, “Add domain” button.

Domain configuration in the Settings tab.

Now just copy the generated “DNS Target” and change the CNAME value in your domain’s DNS settings (GoDaddy for example).

Configuração do DNS no registrador (GoGaddy).

IMPORTANT! → Still inDNS settings, configure permanent type (301) Forwarding for your domain address, for example: http://myhugosite.com or if you perform step 4, https://myhugosite.com.

3. Update config.toml and heroku.yml

In the config.toml and heroku.yml files change the baseURL value to your domain name, for example baseURL = ‘http://myhugosite.com/' or https://myhugosite.com/ if you perform step 4.

4. Upgrade Dyno to Hobby*** (7$ monthly).

To upgrade you need to register your credit card in Account Settings → Billing. After setting up, just change the Dyno plan through the Resources tab of your app from Free to Hobby.

Dyno types.

Then choose Automatic Certificate Management (ACM) form SSL Certificates.

SSL configuration.

Considerations

* https://devcenter.heroku.com/articles/free-dyno-hours#dyno-sleeping
** Optional
*** Only if you want SSL (HTTPS). If you don’t mind the HTTP address, you don’t need to change the plan.

--

--