How to create a static website using HUGO on Heroku
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:
- Hugo — https://gohugo.io/getting-started/installing/
- Heroku account — https://id.heroku.com/login
- Heroku CLI — https://devcenter.heroku.com/articles/heroku-cli#install-the-heroku-cli
- GitHub account** — https://github.com/
- Git CLI — https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
- Docker — https://docs.docker.com/engine/install/
Steps
- Create a new website using HUGO
- Link to GitHub**
- Create app on Heroku
- Download a Hugo theme and update config.toml
- Create the Dockerfile and heroku.yml files
- Test HUGO locally**
- Commit changes
- Upload image to Heroku
- Push changes
- 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:
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.
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.
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:
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.
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.
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.
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.
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.
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.
Now just copy the generated “DNS Target” and change the CNAME value in your domain’s DNS settings (GoDaddy for example).
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.
Then choose Automatic Certificate Management (ACM) form SSL Certificates.
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.