We hope you find this tutorial helpful. In addition to guides like this one, we provide simple cloud infrastructure for developers. Learn more →

How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04

Posted Nov 9, 2015 19.9k views Applications Ubuntu


Hugo is a fast and easy-to-use static site generator written in Go and available across multiple platforms. Static site generators are a great choice for blogs and other content that do not require dynamic content pulled from a database. Choices like Hugo allow you to simplify your stack, write in user-friendly markdown, and handle updates and custom content without needing the bloat of a full content management solution.

In this guide, we will cover how to install and use Hugo on an Ubuntu 14.04 server. This will allow us to configure a static site, create content, and publish on the same server or deploy to a production location.


To follow along with this guide, you will need access to an Ubuntu 14.04 server. On this server, you will need to have a non-root user with sudo privileges configured in order to perform administrative tasks. You can find out how to create a sudo user by following our Ubuntu 14.04 initial server setup guide.

Installing the Latest Version of Hugo

Hugo is not available in Ubuntu's default repositories. However, packages are available on GitHub for various architectures and distributions.

Find Your System Architecture

Before we begin, we should check the architecture of our Ubuntu machine so that we can be sure to download the correct package. On your server, type:

  • uname -i

If you see the following, you are running a 64-bit installation of Ubuntu:


If, instead, your output looks like this, it means that you are working with Ubuntu's 32-bit version:


We will use this information below.

Download and Install the Hugo Package

Visit the Hugo releases page to find the latest version stable of Hugo (the one closest to the top). If you scroll down past the feature announcement text, you should find a section called "Downloads".

Next, we need to copy the link location for the appropriate installation package. The correct package will depend on the server architecture that you found above.

  • If you are on a 64-bit version of Ubuntu, right-click on the link ending with amd64.deb and copy the link location.
  • If you are on a 32-bit version of Ubuntu, right-click on the link ending with i386.deb and copy the link location.

On your server, logged in as your user with sudo privileges, move into a directory that you have write permission in. Use the wget command and paste the link location you copied to download Hugo:

  • cd ~
  • wget https://github.com/spf13/hugo/releases/download/v0.14/hugo_0.14_amd64.deb

Now, you can install the package with dpkg by typing:

  • sudo dpkg -i hugo*.deb

Test that the installation was successful by asking Hugo to print its software version:

  • hugo version

Hugo should print its current software version:

Hugo Static Site Generator v0.14 BuildDate: 2015-05-25T21:29:16-04:00

Installing Hugo's Supporting Software

The main Hugo application should now be installed. However, there are a few additional pieces of software that we should install to help us get up and running.

Install the Hugo Themes

The main Hugo package does not include any themes. Hugo themes define how the actual site content is rendered for users. The easiest way to get Hugo themes is to clone the Hugo themes git repository, which provides many preconfigured themes. We will need to install git for this process.

We can find git in Ubuntu's default repositories. Update the local package index and then install git by typing:

  • sudo apt-get update
  • sudo apt-get install git

Next, we can clone the Hugo themes repository. The repository on GitHub is organized with each individual theme included as a submodule.

Because submodules would significantly complicate the version control for the actual content for our site, we will actually just clone the themes to our home directory. We can then create a symbolic link to the themes within our site directory. This will also allow us to easily share the theme directory if we have multiple sites.

Clone the themes repository to your home directory by typing:

  • git clone --recursive https://github.com/spf13/hugoThemes ~/themes

Install the Pygments Syntax Highlighter

We will also install a piece of Python software called Pygments. This provides server-side syntax highlighting logic for any code blocks that would be included on our rendered pages. We can install Pygments easily with pip, Python's package manager.

We can get pip from the default repositories by typing:

  • sudo apt-get install python-pip

Once apt finishes, we can use pip to install the Pygments by typing:

  • sudo pip install Pygments

This will allow us to include syntax highlighted code blocks supporting over 300 languages in our post content if we choose. You can find out more on the project's page.

Enable Hugo Bash Auto-Completion

One last thing that we will do before getting started working on our first site is to generate Hugo's bash autocomplete functions. We can do this by typing:

  • sudo hugo gen autocomplete

Afterwards, we can source the system-wide completion configuration so that our current shell can use the auto-complete functions without logging out and logging back in:

  • . /etc/bash_completion

Now, if you type hugo followed by a few taps of the TAB key, you will see the commands that Hugo knows about:

  • hugo [TAB][TAB][TAB]
benchmark config gen help new undraft check convert gendoc list server version

Creating Your First Site

Now that we are all set up, we can go ahead and create our first Hugo site. Hugo has a generator that can create a skeleton of the files and directories it needs to function.

We can create a new site in your home directory by typing:

  • hugo new site ~/my-website

Move into your new Hugo site and take a look around:

  • cd ~/my-website
  • ls -F

You will see the directory structure and the primary configuration file used to build the Hugo site:

archetypes/ config.toml content/ data/ layouts/ public/ static/

Let's go ahead and link the ~/themes directory that we cloned into our new site. In order to make this link more flexible for possible deployment, we will create a relative symbolic link. If you deploy your Hugo repository to a remote server, you will just have to make sure to clone the themes directory into Hugo's parent directory again:

  • ln -s ../themes .
  • ls -l
total 28 drwxrwxr-x 2 demouser demouser 4096 Nov 5 11:25 archetypes -rw-rw-r-- 1 demouser demouser 210 Nov 5 11:55 config.toml drwxrwxr-x 3 demouser demouser 4096 Nov 5 11:38 content drwxrwxr-x 2 demouser demouser 4096 Nov 5 11:25 data drwxrwxr-x 2 demouser demouser 4096 Nov 5 11:25 layouts drwxrwxr-x 13 demouser demouser 4096 Nov 5 11:25 public drwxrwxr-x 2 demouser demouser 4096 Nov 5 11:25 static lrwxrwxrwx 1 demouser demouser 9 Nov 5 14:21 themes -> ../themes

As you can see above, the themes directory in our current directory is actually just a link to the themes repository we cloned to our home directory.

Committing Your Site to Source Control

Before we configure our settings and create some content, we should make our new site into a Git repository.

Make sure that you are in your site directory and initialize a new get repository by typing:

  • cd ~/my-website
  • git init
Initialized empty Git repository in /home/demouser/my-website/.git/

Next, set up the basic git configuration items needed to commit code to a repository. The easiest way to do this is with the git config --global command. We need to set our name and email address so that git can record our information as a committer correctly:

  • git config --global user.name "Your Name"
  • git config --global user.email "user@email.com"

By default, git will not commit any empty directories to the repository. Hugo, at times, requires these directories to be present even if they don't have any content in them. To work around this, we can include a hidden .gitkeep file in each of these empty directories. This is enough for git to commit the directory without affecting the actual functionality for Hugo.

We can add a hidden .gitkeep file to each of our top-level directories (other than the actual .git hidden directory) by typing:

  • for DIR in `ls -p | grep /`; do touch ${DIR}.gitkeep; done

We can see that a hidden .gitkeep file has been added to all of our top-level directories by typing:

  • find . -name .gitkeep
./data/.gitkeep ./layouts/.gitkeep ./archetypes/.gitkeep ./static/.gitkeep ./content/.gitkeep

We also want to make sure that our rendered site content is not added into source control. The actual HTML, JavaScript, and CSS assets should be generated fresh on each deployment, not kept in source control itself. We can tell git to ignore the public directory where generated content would be stored by adding that location to a .gitignore file:

  • echo "public" >> .gitignore

Now, we can commit our clean site skeleton to the repository by adding all of the content in the current directory and then committing:

  • git add .
  • git commit -m 'Initial commit, pre-configuration.'

Adjusting the Initial Configuration for Your Site

Let's adjust Hugo's main configuration file to set up the way that Hugo will build our site.

Open the config.toml file in your editor:

  • nano config.toml

Inside, you will find a few items that we need to adjust:

baseurl = "http://replace-this-with-your-hugo-site.com/"
languageCode = "en-us"
title = "My New Hugo Site"

As the file suffix indicates, this file is written using the TOML language. This is a simple configuration language that mainly uses keys, values, and sections.

The first item that we should change is the baseurl item. This is used to construct URLs when the site is built. Change this to reference the domain name or public IP address of your server. You should also edit the value assigned to the title. This is used to set the tab or window title for your site and is used on the page for certain themes:

baseurl = "http://your_domain_or_IP/"
languageCode = "en-us"
title = "Your Site Name"

There are a few additional settings we should add to this file. First, we can set our preferred text editor. That way, when we generate new pages, the page template will be opened in our editor, ready to work.

We should also set a default theme. We will use a theme called "nofancy" to get started. You can override this later on the command line to test out alternatives and then edit the configuration file when you find one that suits you. We will also set our preferred code block styling:

baseurl = "http://your_domain_or_IP/"
languageCode = "en-us"
title = "Your Site Name"
newContentEditor = "nano"
theme = "nofancy"
pygmentsStyle = "native"

You can find some more information about available settings on this page. For now, save and close the file.

Let's commit our configuration changes before continuing:

  • git add .
  • git commit -m 'Initial configuration complete'

Creating New Pages for Your Site

We're now ready to start creating site content. Content in Hugo is written using easy-to-use markup languages. Page metadata is provided in a special section on each page called "front matter" using the same configuration syntaxes available for the main configuration file.

We can generate new content with Hugo by using the hugo new command followed by the path to the content we want to produce. By default, Hugo content is written in Markdown. In order for Hugo to correctly generate HTML from our Markdown pages, we need to create files that end with the .md extension.

Create an About Page

The pages that will be linked to from the homepage and the relative paths that your pages will need are largely dictated by your theme. View the theme's page on GitHub to learn more about what it expects. Our "nofancy" theme has a link for an "about" page. Let's start off by creating that page:

  • hugo new about.md

A new page will be created in the content directory called about.md. Since we set the newContentEditor option in our configuration file, the file should automatically be opened with your preferred editor. It should look like this to start:

categories = ["misc"]
date = "2015-11-05T16:58:58-05:00"
title = "about"


The settings and metadata for the page are configured in the "front matter" for the page, the section marked off on either side by lines of "+++". The front matter included by default is often defined by the theme that you are using.

Our current theme includes three items in the front matter of generated pages. You can adjust these or add additional items as you'd like. The general variables available to Hugo can be found here. Your chosen theme might also use its own front matter variables. Check out your theme's README in the Hugo theme repository to get specifics about your theme.

Some important general front matter items are:

  • date: The date that should be used for sorting your content
  • description: A description of the page content
  • draft: Will mark the page as not ready for publication if set to true
  • slug: Set this if you would like to specify an alternative URL name for the content
  • publishdate: This can be set to a date in the future if you only want to build the page after a certain date
  • title: The title of your page

For now, let's just edit the title of our "About" page:

categories = ["misc"]
date = "2015-11-05T16:58:58-05:00"
title = "About Me"


Now, we can add Markdown text below the bottom "+++". This will be translated to the body HTML text. We will add a few paragraphs, a heading, and a picture licensed under Creative Commons made available from Eva Hejda that we liked:

categories = ["misc"]
date = "2015-11-05T16:58:58-05:00"
title = "About Me"


Hello and welcome to my site!

## A Bit About Me

I like alpacas and I'm a fan of static sites.

![Great alpaca picture](https://upload.wikimedia.org/wikipedia/commons/c/c4/Alpaka_33444.jpg)

When you are finished, save and close the file.

Create Your First Post

We created the about.md page in the root of our content directory because that is where our theme expects it to be. However, most of our posts will be best kept in a post subdirectory (some themes look for posts in a posts subdirectory instead).

Let's create a first post in the "posts" directory. Hugo will automatically create any leading directories it needs when generating pages:

  • hugo new post/My-First-Post.md

If we use dashes in the Markdown filename, they will be converted to spaces for the auto-filled title:

categories = ["misc"]
date = "2015-11-05T17:52:41-05:00"
title = "My First Post"


Fill in any missing metadata and add some markdown to the page. We will add a code example here so that you can see the code highlighting that the Pygments tool provides. To do this, instead of using regular Markdown triple backticks to enclose a code block, we place the code between two highlight tags that look like this:

{{< highlight language >}}


{{< /highlight >}}

This will apply the Pygment styling to the code within. Keep in mind that certain themes include CSS files that will override the Pygment style choices. The <pre> tag often has additional styling applied that can override the background color for the Pygment theme. Our particular theme doesn't suffer from this issue however.

Inside our page, the completed content will look like this:

categories = ["misc"]
date = "2015-11-05T17:52:41-05:00"
title = "My First Post"


This is my first post on the site.  I hope that you like it!

## Welcome Function

Here is a little Python function to welcome you:

{{< highlight python >}}
def hello_world():
    print "Hello there!"
{{< /highlight >}}

Save and close the file when you are finished. If you need to edit these pages later, you can find them in the content directory of your Hugo site.

Let's commit our new pages to our git repository:

  • git add .
  • git commit -m 'First pages of our site'

Building and Serving the Site

Hugo can take your Markdown files, apply the settings defined in your configuration and theme, and render the actual HTML pages that will be shown to visitors.

To build your site, you can simply type:

  • hugo

This will generate your pages and put all of the rendered content into the public directory on your server. If you wish, you can transfer the contents of this directory to your web server to deploy and serve your content.

Hugo does not clean up the output directory after each build. This means that there is a possibility of stale content being left in the public directory from a previous build. The Hugo developers recommend that you delete the public directory after each build (especially before moving to production) so that the content can all be recreated fresh.

Hugo also includes a web server of its own. While you might not want to use it to serve your production traffic, it is an excellent way to view your working copies and test the rendering prior to deploying your pages.

To make your pages available on your Hugo server, use the hugo server command. This will render your pages (there is no need to run the hugo command beforehand) and then start the web server.

We will use the --bind option to specify that we wish to make the site available on all interfaces (if you have installed Hugo locally, you can remove this). We also need to include the --bindUrl option. We set this in our configuration file, but it isn't picked up by the server in the current version of Hugo. Set this to your website's domain name or IP address:

  • rm -r public
  • hugo server --bind= --baseUrl=http://your_domain_or_IP/

If you set draft = true in any of your pages, or set the date to a future time in some of your content, you can build and preview those pages by including the -D and -F flags respectively:

  • rm -r public
  • hugo server --bind= --baseUrl=http://your_domain_or_IP/ -D -F

Now, if you visit your server's domain name or IP address in your web browser and append the :1313 port specification to the end, you will see your rendered site:

  • http://your_domain_or_IP:1313

Hugo test site

We can click on our first post to check out our rendered Markdown. Our Pygments style has been applied to the code block:

Hugo first page

If we click on the "About" link, we will be taken to our "About Me page:

Hugo about page

As you can see, our theme is fairly basic but it functions exactly as we expected.

If you would like to try out alternative themes, you can add the --theme= option to the end of your server line:

  • rm -r public
  • hugo server --bind= --baseUrl=http://your_domain_or_IP/ --theme=redlounge

Keep in mind that each theme has its own expectations about your directory structure and configuration settings. You might need to adjust some things to get each new theme to work correctly.

If you would like to use Hugo to serve content on port 80 like a conventional web server, you will have to add the --port option to your command line. You will also have to prepend sudo to the command since ports below 1024 are restricted for normal users:

rm -r public
sudo hugo server --bind= --baseUrl=http://your_domain_or_IP/ --theme=redlounge --port=80

You should now be able to visit your site in a browser window without the port number appended.

After running the Hugo server with sudo, you will have to preface the rm command with sudo as well:

  • sudo rm -r public


Hugo is a great way to get a site off of the ground quickly and easily. Static sites offer a less resource-intensive alternative to the traditional CMS sites. The majority of users do not need database-driven content and do not use the extra features that content management systems provide. With Hugo, you can focus your energy on creating content instead of administering a complex system.

Our next guide will take this setup a step further by covering how to deploy a Hugo site using Git Hooks.


Creative Commons License