Build a website with Gitlab, Hugo and Academic

Photo by “My Life Through A Lens” on Unsplash

This post will show you how to create and host a static website using Gitlab, Hugo and the Academic theme. In a couple of hours 1 you could create a website identical to the demo site that accompanies this article.


I’ve often considered, and been told I should create a blog. I know it makes sense. One way or another I never got around to it, until now.

For my work, I recently joined a client that uses Gitlab, including the CI/CD capabilities, exclusively. In preparation, I created an account to do some research. When creating a new project I discovered the built in project templates and a few minutes later I had a fully working proof of concept using the Beautiful Hugo theme. One thing lead to another!

Hugo Benefits

I’m regularly working in a mixture of Windows(TM) and Linux(TM) environments. Due to this I have a strong preference for cross platform tools. I’ve tried Jekyll in the past and found Windows configuration non trivial. Configuring a Jekyll vm was also time consuming. 2 I use Chocolatey to manage my Windows machines. Hugo installation via chocolatey is a simple choco install --yes hugo-extended, and away hugo. 3 Installing Hugo on Linux is similarly trivial.

Why Academic?

I didn’t want a cookie cutter site so I searched the Hugo themes with a few criteria in mind:

  • Low effort to get started.
  • Actively in development.
  • Capable of tweaking the look and feel.
  • Capable of being extended and providing options for growth in future.

I nearly discounted Academic based on the fact that the demo site would need a fair bit of content and customisation to get started. I then found Joshua Hu’s minimal-academic which was reasonably close to my design ideas and showed the potential for paring Academic back to the basics.

The Final Push

I mentioned Hugo to a few friends. In my excitement I got a bit carried away and proclaimed how fast you could get something up and running using the Gitlab and hugo combination all for free. One challenged me and said with a grin:

“Oh yeah? Then show me! You can use the guide as your first post can’t you?”

Game on. Here is that guide.


Create a Gitlab Project

Create a new empty project in your Gitlab account. When you click create, keep the page open as you can copy and paste the git commands from the output in the next step.

For simplicity, you could use the same repository name as I have ‘hugo-academic-lean’, otherwise (where needed) you will need to do some translation.

The repository created for this post is configured as public. The guide will also work with the repository configured as private - this way you can keep any work in progress private before release.

Create the Hugo Site

Open your bash command line. Note that my root working directory is ~/projects. Your configuration may be different.

I recommend that you use the same name as your Gitlab project in the hugo new site ... command.

cd ~/projects
hugo new site hugo-academic-lean

cd hugo-academic-lean/
# Insert YOUR gitlab credentials and origin!
git init
git config "Neil Kidd"
git config ""
git remote add origin

git add .
git commit -m "Create an empty hugo site"
git push -u origin master

Import Academic

The following command tracks the theme master branch and pins it to the commit at the time of writing this guide.

For stability4 you may prefer to track a specific release. I recommend following the steps here and updating at your leisure later.

git submodule add themes/academic

# Pin the theme to the commit at the time of writing
cd themes/academic
git checkout 92c1bca1a9f1b53d03fc402796d5aa1b8e5dd68a

cd ../..
git add .
git commit -m "Add academic theme git submodule"
git push

Optional Review

It is worth spending some time to review the demo exampleSite included with the theme. It showcases the rich capabilities of Academic and will provide inspiration for the future!

Simply cd into the theme and run the provided script. The script will output the url:port to open in your browser.

cd themes/academic/

When you have finished, don’t forget to stop the hugo server with ctrl+c and cd ../.. back to the repository root.

Site Configuration

Now we’ll do a little clean up and copy some structural content from the theme.

Delete Default Hugo Files

When you generate a new site, Hugo creates a config.toml file and a template for new content under archetypes/ We’ll be using the theme-provided config and templates so will remove the defaults.

rm ./config.toml
rm -Rf ./archetypes
git add .
git commit -m "Delete default Hugo files"
git push

Copy Theme dot Files

# We echo the .gitignore so the public directory is also ignored
echo -e "public/\n\n$(cat themes/academic/.gitignore)" > .gitignore
cp themes/academic/.editorconfig .editorconfig

git add .
git commit -m "Copy academic theme .gitignore and .editorconfig"
git push

Copy Structural Content

Academic uses a widget system. The site root, home/ is of type widget_page which is capable of displaying multiple widgets. The widgets are configured in files in the same directory. In our case, we’ll use one widget to display post summaries, configured in the file home/

cp -R themes/academic/exampleSite/config/ .
cp -R themes/academic/exampleSite/content/authors/ ./content/

mkdir -p content/home
cp themes/academic/exampleSite/content/home/ content/home/
cp themes/academic/exampleSite/content/home/ content/home/

git add .
git commit -m "Copy example content from the themes exampleSite"

Personalise Author Config

Rename the authors/admin directory to authors/neil.

Remember to substitute yourname for neil in any future commands and edits!
mv content/authors/admin/ content/authors/neil/

From this point forward I have only documented the important edits. Do feel free to explore and customise the configuration as you like. Although I suggest you defer too much further exploration for now - let’s get this done!

Edit Author Settings

The file is: content/authors/neil/

# Display name
name: Neil Kidd

# Username (this should match the folder name)
- neil

# Social/Academic Networking
# For available icons, see:
#   For an email link, use "fas" icon pack, "envelope" icon, and a link in the
#   form "" or "#contact" for contact widget.
- icon: blog
  icon_pack: fas
  link:  # For a direct email link, use "".
- icon: linkedin
  icon_pack: fab
- icon: gitlab
  icon_pack: fab

# user_groups:
# - Researchers
# - Visitors
git add .
git commit -m "Edit author configuration"

Edit Global Site Config

The file is: config/_default/config.toml

Note that you should replace the baseurl according to your Gitlab repository configuration.

# Title of your site
title = "Hugo Academic Lean"

# The URL of your site.
# End your URL with a `/` trailing slash, e.g. ``.
baseurl = ""

Configure Language

The file is: config/_default/languages.toml

  languageCode = "en-gb"

Configure Site Menu

The file is: config/_default/menus.toml

Comment out everything (with a leading #) except the posts section. We’ll clean this file up later.

  name = "Posts"
  url = "#posts"
  weight = 20

Configure Common Site Parameters

The file is: config/_default/params.toml

Again, the are many options for you to explore - at a later date! Note that I’m based in the UK so setting the privacy_pack option was trivial for GDPR compliance.

  privacy_pack = true
edit_page = {repo_url = "", repo_branch = "master", editable = {docs = false, page = false, post = false}}

## Clear Contact widget
# Enter contact details (optional). To hide a field, clear it to "".
email = ""
phone = ""
address = ""

# Office hours: use `<br>` to insert a line break, or set to "" to remove office hours
office_hours = ""

# Enter an optional link for booking appointments (e.g.
appointment_url = ""

# Contact links
#   Set to `[]` to disable, or comment out unwanted lines with a hash `#`.
contact_links = []

##Clear map
map = 0
map_api_key = ""
latitude = ""
longitude = ""
zoom = 15

# Align the main menu to the right of the page? (true/false)
menu_align_right = true
git add .
git commit -m "Add and edit configuration"

Create Posts

To get a realistic preview of the site, we’ll copy and edit post content from the theme.

mkdir -p content/post
cp -R themes/academic/exampleSite/content/post/ content/

# delete unwanted jupyter files - we are using markdown and being lean and clean!
find ./content/ -type f -name '*.ipynb' -delete

Search and replace for admin in the files under content/post/*.md to assign the posts to your author name.

- admin # edit here

The following files will need editing:

  • content/post/getting-started/
  • content/post/jupyter/
git add .
git commit -m "Copy sample posts"
git push

Review Progress

To make local previews a little easier we’ll create a bash script. Trust me, it will pay off in the long run.

cat << EOF >
#!/usr/bin/env bash

if [ -d "resources" ]; then
  rm -Rf resources

hugo --i18n-warnings server --watch --disableFastRender --buildDrafts --baseUrl ""


Commit and push the script.

git add .
git commit -m "Create local preview script"
git push

To preview the current state simply run ./ The script output will tell you the url:port to open in your browser. Use ctrl+c to stop the server.

First draft preview
First draft preview

This is a good basic start, but the header menu is a little bare and it can easily be enhanced using Academic functionality.

Add Extra Menu Options

Edit the file : config/_default/menus.toml

Add a menu option Home to the left of the Posts link. The site title text, Hugo Academic Lean is also a link to home, but the textual link is a good UX addition.

  name = "Home"
  url = ""
  weight = 10

Add an About Me menu item on the far right - we get this out of the box due to completing the author configuration earlier.

  name = "About Me"
  url = "authors/neil/"
  weight = 30

Now clean up the file by deleting any of the remaining commented menu items and save the file.

git add .
git commit -m "Complete header menu"
git push

If you stopped the server, start it again with ./ and review your handiwork.

Navigation menu complete
Navigation menu complete
About Me page
About Me page

Going Live

This is it - the point you’ve been working towards! Gitlab provides ci/cd functionality for free. We’ll configure 5 this and publish the site live for all to see.

Create a .gitlab-ci.yml file using a Here Document.

cat << EOF > .gitlab-ci.yml
# All available Hugo versions are listed here:
# Optional: review and set an exact version to align with your local hugo installation


  - hugo --gc --minify
  - master

  - hugo --gc --minify
    - public
  - master


Commit and push the ci file to trigger the build pipeline.

git add .
git commit -m "Add .gitlab-ci.yml to auto publish"
git push

Return to your Gitlab repository, navigate to CI/CD => Pipelines then locate and click on the job number. All being well, you should see something similar to the following image.

Pipeline Success
Pipeline Success
In a short period of time 6 your site will available at https://{YOUR-GITLAB-USERNAME}{REPOSITORY-SLUG}. The actual site URL can also be found in the Gitlab UI under Settings => Pages.

That’s it, you are finished! 😄

Next Steps

We have only scratched the surface of the capabilities of Hugo and Academic. Now the basics are in place you can grow your site as and when you like.

A Few Ideas


  1. Depending how focussed you choose to be! ↩︎

  2. “Just use docker!” I hear you scream. I use Virtualbox on Windows to isolate my work VMs, which seriously complicates running docker on Windows. I really look forward to WSL 2↩︎

  3. Apologies for the irresistible pun. It’s especially for Sam Davies, one the punniest people I know! 😄 ↩︎

  4. Updated 2019-10-27: Added pinning the theme to a specific hash. ↩︎

  5. configure feels a grandiose term for pushing a simple script! ↩︎

  6. In practice, page publishing time appears to range somewhere between 2 and 30 minutes. ↩︎

Neil Kidd
Neil Kidd
Head of Academy

My interests include Software systems development, flow and what enables organisations and people succeed.