Creating and Hosting a Website with Hugo
A colleague wanted to host his own website. Whilst explaining that I use Hugo, I realised this would make a useful blog post others could use as a reference to setting up their own Hugo website. This is not a unique topic. There are plenty of blog posts and social media comments praising Hugo but another bit of good press won’t do the project any harm.
What is Hugo
Hugo is a blazingly fast static site generator written in Go with a rich ecosystem of themes, a very flexible framework and a active community. It is what I use to run this website.
Why I Like Hugo
- Portability: As Hugo is generating HTML pages it is very lightweight to host. I have hosted this website a few places such as locally behind nginx, AWS S3 object storage and now GitHub Pages. Should my current hosting provider decide to change its terms, I could pick up my 628 KB website and move it elsewhere
- Maintainability: As it is just HTML, there is no database to keep updated and by leveraging services such as GitHub Pages, AWS S3, Cloudflare Pages there is less underlying server maintenance on my part.
- Security: Again it’s just HTML pages. Fewer moving parts means a smaller attack surface. Just because it’s HTML does not mean there are no potential risks. Someone could breach the hosting provider and leave something malicious, however compared with many other content management systems and blog platforms the risk is considerably reduced.
- Themes: I am by no means a great frontend developer, thankfully due to the popularity and the active community of Hugo I have been able to use a theme that somebody else has created under a permissive licence. A small selection of themes can be found on the Hugo themes website.
How to use Hugo
Want to create a new website?
hugo new site my-hugo-website
cd my-hugo-website
Want to use a theme?
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
Creating a blog post?
hugo new content/posts/$(date +%y%m%d)-blog-post.md
Want to see your website before you publish your post?
hugo serve -D
Publishing your website? Once configured it can be as simple as
hugo deploy
These are just a few examples of how straightforward Hugo can be. You can find plenty more examples and useful bits of information in the Getting Started guide and documentation
Hosting your website
Hugo’s flexibility leaves you with a whole load of options for hosting. I’ve listed a few when discussing maintainability but you can find a considerable number of options that have been battle tested on Hugo’s Host and Deploy documentation page. This list is not exhaustive but gives you ideas. Remember this is just HTML pages so any web server would be sufficient. At the time of writing this post I use GitHub Pages. This is predominantly cost driven as GitHub Pages provides me web hosting at no fiscal cost to myself. The simplicity of not having to manage the underlying host system has reduced the maintenance effort also.
Automating website deployment
Finally you may wish to automate the deployment process if you’re using something like GitHub/GitHub Pages. If you’re in the GitHub ecosystem you could leverage GitHub Actions to achieve this thanks to the fine work of peaceiris. I use a 2 git repository solution to achieve this. One that is private so I can commit draft blogs prior to them going public and my public github user repo sbt92/sbt92.github.io which automatically enables GitHub Pages and serve my website. If you wish to do what I do you can store this Github Actions pipeline code in your private repo under .github/workflows/deploy-website.yaml.
name: Deploy website to GitHub Pages (<github_username>.github.io)
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true # Fetch Hugo themes
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.131.0' # Optional
extended: true
- name: Build website
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.GITHUB_API_KEY }} # Generate this in user Development Settings and add to your private repository secrets.
external_repository: <github_username>/<github_username>.github.io
publish_branch: main
publish_dir: ./public
full_commit_message: ${{ github.event.head_commit.message }}
cname: www.<mywebdomain>.co.uk # https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site