There’s a ton of different frameworks, tools and platforms available when building a personal website today.
In this post I’ll go into how and why I chose to build my webpage using the Hugo framework. I’ll also show how to setup the hosting on Github pages which includes pushing the webpage from a private repository to a public one with Github Actions.
My requirements for the tech stack were:
- Fast
- Low maintenance
- Easy to create and manage content
- Content version control
- Automated deployment
- Low cost
Hugo is a static site generator which typically makes loading of webpages extremely fast. Static sites are also in general low maintenance. All content are markdown files which makes it easy to see changes with git and makes the content highly portable. By hosting it on github pages we get automated deployment from github actions and low cost. I only pay for the domain itself.
These are the steps required to get your own site up and running:
- Installing Hugo and choosing your theme.
- Create your
username.github.io
repository, where username is your username on Github. Remember to set it as public. - Create your private repo with a name of your choosing.
- Initiate a new Hugo project in the private repo and add Papermod theme as a submodule.
- Create a GH action for automatic compilation and deployment of Hugo’s public folder from your private to public repo.
- (Optional) Setup your custom domain name.
Where applicable I’ve linked to resources which goes into detail on specific steps. The content I’ve linked to goes deeper into the material and is more likely to be updated if there’s been any changes. I recommend to use this post more as a high-level guide of the steps involved and diving into the linked content when you need further details.
Creating your website
Installation and introduction to Hugo
Hugo has a great quick start page here which goes through how to install Hugo, a theme and gives an overview of basic commands. This youtube video from Luke Smith is also a great introduction which I used when learning how Hugo works.
Note that your configuration file can either be YAML, TOML or JSON. I went for the yaml format as that’s what I’m used to.
Choosing your theme
You can preview a ton of themes at themes.gohugo.io. Another alternative is to look at the hugo-theme topic on github which can give you an idea of which themes are the most popular. I went for papermod as the theme. There is a great guide available at the papermod wiki on how to install it. I used method 2 and installed papermod as a Git Submodule as it makes it easy to apply future updates.
Architecture
If you have a free github account your site repo needs to be public.
When Hugo compiles your website all required content to render it is dumped into the public
folder.
This means that in order to keep our drafts secret we can keep our main repo as a private repo and deploy the public
folder to the public facing repo using github actions.
This ensures your drafts are kept secret until it’s ready to be published.
Once your website is ready to be published it’s time to setup the automated deployment. I used the gh action template available at finisky as a starting point and did the following changes:
- Updated the versions
- Included the git submodules in the checkout step
- Run Hugo with –minify flag to reduce the size of the generated HTML files which should give slightly faster page loading.
Place the following script in your private repo in this directory: .github/workflows/publish.yml
|
|
The action itself uses a combination of jobs, these are:
- Checkout to make the private repo accessible to the rest of the workflow
- Actions-Hugo to build the Hugo site
- GitHub Pages Deploy Action for automatic deployment to Github Pages. In our case copying the
public
folder over the public facing repository.
In order for the action to work we need to create a Personal Access Token (PAT).
Ideally we want a fine-grained PAT to be inline with principle of least privilege. The action requires workflow
and write:packages
scopes.
The latter is not supported yet so we need to create a classic PAT.
Follow this guide to create it.
After creating it change the PAT_DEPLOYMENT
on line 36 in the script to the PAT secret name and change the repository-name
on line 35 to your corresponding github pages.
This action deploys on pull request. If you’d rather prefer it to run on pushes to main change lines 3-5 to:
|
|
and remove the commit-message
on line 41. I use pull_request
as I like to verify that everything was published correctly and in case I find any last minute typos.
That should be it! If everything is configured correctly your site should be up and running and pushing changes to the site any time you do either a pull request or push depending on your config.
(Optional) Custom domain name
The workflow for how to use a custom domain name is available on github docs here. I also used this stackoverflow post for some clarification. After finishing the configuration your DNS records should look something like this: