Building my blog using Gitlab pages and Pelican

What's more fitting for a first blog post than one about the blog its self! I've probably put off writing up a first post for far longer than I initially intended, but life just gets in the way sometimes. I thought I'd do a quick walk through of how I build and host this blog including setting up SSL with Let's Encrypt, all managed via Gitlab's excellent CI/CD platform.

Gitlab Pages

Gitlab Pages, much like its forebear Github Pages allows you to easily host a static (that is, only HTML, CSS and JS) site for free, based on the contents of a git repository. Unlike the Github offering Gitlab Pages allows you to use the Gitlab CI tools to generate your static site however you like (afaik, and at the time of writing, Github pages can be Jekyll-based or HTML directly in the repo).

By default all new Gitlab repositories comes with Pages enabled and it can be configured via the Settings menu on the left. The first time you visit it will provide you with a wizard for setting up your pipeline (but see below for an example too). You can use pages with a free subdomain on or with your own domain (you'll need to prove ownership by setting some TXT records for your domain). Both options come with HTTPS out-of-the-box provided by Let's Encrypt.

Static Site Generation

While it is certainly possible to maintain a static site by editing the pages manually it's more common, especially if you have lots of blog entries, to use a static site generator. There exist a plethora of options for generating a static site written in every programming language imaginable from Yass (Ada) to Hydrogen (Typescript). For the purpose of this blog I wanted to go with a tool written in a language I was familiar with so started looking around for Python-based tools and eventually landed on Pelican. Pelican, like a lot of generators, takes reStructuredText or Markdown and using some templates spits out a pile of HTML pages that can be hosted basically anywhere. Getting started with Pelican is as easy as running pip install pelican[Markdown] then pelican-quickstart to get a Pelican skeleton setup in the current directory. I'll leave the configuration and usage of Pelican in the hands of its capable documentation and move onto how we get this all up and running on Gitlab Pages.

Deployment Pipeline

To deploy our static site to Gitlab Pages all we need to do is provide an artifact that exposes a public/ directory, Gitlab Pages does the rest!


  - build

  image: python:3-alpine
  stage: build
    - pip install -r requirements.txt
    - pelican -s
    - master
    - schedules
    untracked: true
      - public/
    expire_in: 1 hour

(I'm using a custom theme that's included in my website repository as a git submodule, hence GIT_SUBMODULE_STATEGY: recursive)

Aaaand....we're done. It really was this easy.

(Update 2023: I made this a whole lot harder on myself and now host these static pages via a Kubernetes cluster on OCI. But that's a story for another time.)