Moving to a static website using zola and github pages
Static site generators create a website by converting human readable format files i.e markdown into a web page hierarchy.
We recently moved our website from being hosted on a Debian virtual machines using Wordpress to be a static site that we generate and push to github pages for hosting.
We are very happy with the outcome as now we can;
- Keep the website content under version control
- Forget about having to host or maintain virtual machines
- Forget about having to keep updating Debian and Wordpress
- Trivially update the web site with a single
git push
command.
To help others make the transition we have posted some brief notes below, along with our working configurations.
Install the required tools on your workstation
Tools used
zola is a web static site generator written in rust. tabi is a zola theme used to customize the look and layout of a zola generated website. github pages supports hosting web pages directly from a github repository.
Install zola and tabi
Instal zola and tabi using the tabi-start repository. If you will be hosting your static site on github pages then call your new github repository https://github.com/<username>/<username>.github.io
(so we used https://github.com/flocknetworks/flocknetworks.github.io
). This is a reserved name in github that indicates you want the output of this repository to be hosted on github pages as your main domain.
Create the website content
zola configuration file
You will find the main zola config file in the root of your repository. This config file also holds the config settings for the zola theme you have chosen, in our case tabi.
ncarter@zola:~/src/flocknetworks.github.io$ ls config.toml
config.toml
This configuration file was created when you ran zola init
. Below are the settings you are most likely to want to edit.
# TODO: Change base_url once flocknetworks.com DNS points to the new site at github.io.
# base_url = "https://flocknetworks.com"
base_url = "https://flocknetworks.github.io"
title = "Flock Networks"
description = "Next Generation IP Routing Suite"
author = "Nick Carter"
theme = "tabi"
...
menu = [
{ name = "brochure", url = "brochure", trailing_slash = true },
{ name = "products", url = "products", trailing_slash = true },
{ name = "white papers", url = "whitepapers", trailing_slash = true },
{ name = "blog", url = "blog", trailing_slash = true },
{ name = "tags", url = "tags", trailing_slash = true },
{ name = "about", url = "about", trailing_slash = true },
]
Check website content is correctly generated
Run zola serve
which will build and then serve your website on your development workstations loopback interface on port 1111.
ncarter@zola:~/src/flocknetworks.github.io$ zola serve
Building site...
Checking all internal links with anchors.
> Successfully checked 0 internal link(s) with anchors.
-> Creating 7 pages (0 orphan) and 7 sections
Done in 99ms.
Listening for changes in /home/ncarter/src/flocknetworks.github.io/{config.toml,content,static,themes}
Press Ctrl+C to stop
Web server is available at http://127.0.0.1:1111 (bound to 127.0.0.1:1111)
Where to store your content
The content used to generated your website is held in the well named content
directory. If you have content that you want to include that is already in its final form (i.e. PDF documents, PNG images, etc) they should be placed under the static
directory.
ncarter@zola:~/src/flocknetworks.github.io$ ls content/
about archive blog brochure _index.md privacypolicy products whitepapers
ncarter@zola:~/src/flocknetworks.github.io$ ls static
docs img
ncarter@zola:~/src/flocknetworks.github.io$
content/_index.md
is your websites homepage stored in markdown format.
ncarter@zola:~/src/flocknetworks.github.io$ head -n 6 content/_index.md
+++
[extra]
header = { title = "Next Generation IP Routing", img = "img/flock-favicon.jpg" }
+++
Flock Networks have upgraded the IP routing suite to match the demands of the modern network. Using 30 years of network architecture and network operations experience, we have created the [third generation](https://www.flocknetworks.com/docs/third-gen-routing-suite-2020-07-27.pdf) of IP routing suite.
Publish the website content to your custom domain
DNS changes
Change the DNS settings for your domain name to point at github pages
# Github pages IPv4 DNS servers
A @ 185.199.108.153
A @ 185.199.109.153
A @ 185.199.110.153
A @ 185.199.111.153
# Github pages IPv6 DNS servers
AAAA @ 2606:50c0:8000:0:0:0:0:153
AAAA @ 2606:50c0:8001:0:0:0:0:153
AAAA @ 2606:50c0:8002:0:0:0:0:153
AAAA @ 2606:50c0:8003:0:0:0:0:153
# map canonical subdomain name www.flocknetworks.com to flocknetworks.github.io
# Do not use an `A` or `AAAA` record to map subdomains or github pages will fail the subdomain DNS check
CNAME www flocknetworks.github.io
If you already have DNS settings registered with another hosting company then delete all those records.
Add CNAME file in the static dir in your main git branch
ncarter@zola:~/src/flocknetworks.github.io$ git status
On branch main
ncarter@zola:~/src/flocknetworks.github.io$ cat static/CNAME
flocknetworks.com
If you don’t have a CNAME
file then github will create one (in the auto created gh-pages branch). But be warned github pages custom domain settings will be lost on every git push and your site will become unavailable until you manually reinstate the domain settings.
Update zola base_url to point at your domain name
diff --git a/config.toml b/config.toml
index 7c2819d..e17f9a1 100644
--- a/config.toml
+++ b/config.toml
@@ -1,5 +1,5 @@
-base_url = "https://flocknetworks.github.io"
+base_url = "https://flocknetworks.com"
Add github actions YAML file to build and publish your site
Note that the zola version specified should match the version of zola you are running on your workstation. You also need to give github actions write permissions https://github.com/<username>.github.io/<username>/settings/actions
.
ncarter@zola:~/src/flocknetworks.github.io$ cat .github/workflows/build.yml
name: build.yml Deploy Zola site to Pages
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build and deploy
# @v0.19.2 is the zola version to use, when running zola build.
# So match the version we are using locally (zola --version)
uses: shalzz/zola-deploy-action@v0.19.2
env:
PAGES_BRANCH: gh-pages
TOKEN: ${{ secrets.GITHUB_TOKEN }}
Add a git pre-push hook
By running zola check
we prevent pushing a branch that has broken links.
ncarter@zola:~/src/flocknetworks.github.io$ cat .git/hooks/pre-push
#!/bin/bash
# Verify what is about to be pushed. Called by "git push" after it has
# checked the remote status, but before anything has been pushed.
# If this script exits with a non-zero status nothing will be pushed.
zola check
if [ $? -ne 0 ]; then
exit 1
fi
exit 0
Publish your site
This is simply a case of git pushing your main branch.
ncarter@zola:~/src/flocknetworks.github.io$ git status
On branch main
ncarter@zola:~/src/flocknetworks.github.io$ git push
Checking site...
Checking all internal links with anchors.
> Successfully checked 0 internal link(s) with anchors.
Checking 31 external link(s). Skipping 0 external link(s).
> Checked 31 external link(s): 0 error(s) found.
-> Site content: 7 pages (0 orphan), 7 sections
Done in 3.0s.
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 3.55 KiB | 3.55 MiB/s, done.
Total 5 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To github.com:flocknetworks/flocknetworks.github.io.git
+ 3e5e868...646f631 main -> main
Your website content will be built in the gh-pages
branch (as specified in build.yml)
ncarter@zola:~/src/flocknetworks.github.io$ git log origin/gh-pages
commit 32d4a17f463bbbcf84ea6d3cfed20ca701d93e73 (origin/gh-pages)
Author: GitHub Actions <github-actions-bot@users.noreply.github.com>
Date: Wed Feb 26 10:47:17 2025 +0000
Deploy flocknetworks/flocknetworks.github.io to flocknetworks/flocknetworks.github.io:gh-pages
Tell github pages to use your custom domain
Visit https://github.com/<username>/<username>.github.io/settings/pages
and set the “Custom Domain” to your domain name.
If the “Custom Domain” DNS check is failing then check your DNS changes are correct and have come live (DNS records are widely cached so the old entries need time to go stale and expire).
ncarter@condor:~$ dig flocknetworks.com | grep flocknetworks.com
; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> flocknetworks.com
;flocknetworks.com. IN A
flocknetworks.com. 2954 IN A 185.199.108.153
flocknetworks.com. 2954 IN A 185.199.111.153
flocknetworks.com. 2954 IN A 185.199.110.153
flocknetworks.com. 2954 IN A 185.199.109.153
Enable SSL by clicking on the button. github pages will then get a certificate from the lovely folks at lets encrypt and github pages will automatically renew it for you before the certificate expires.
Your website should now be globally accessible at https://<your-domain-name>
Updating the website with new content
Now everything is set up, updating content on the web site is as simple as;
git commit
git push
ncarter@zola:~/src/flocknetworks.github.io$ git status
On branch main
ncarter@zola:~/src/flocknetworks.github.io$ git commit -a -m "my new content"
[main 8a3b1ab] my new content
1 file changed, 7 insertions(+)
ncarter@zola:~/src/flocknetworks.github.io$ git push
Checking site...
Checking all internal links with anchors.
> Successfully checked 0 internal link(s) with anchors.
Checking 32 external link(s). Skipping 0 external link(s).
> Checked 32 external link(s): 0 error(s) found.
-> Site content: 7 pages (0 orphan), 7 sections
Done in 2.9s.
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 570 bytes | 570.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), completed with 4 local objects.
To github.com:flocknetworks/flocknetworks.github.io.git
97b67e5..8a3b1ab main -> main