Deploying Jekyll with GitLabCI

My blog is based on Jekyll, a static website generator. This means that the pages need to be generated before they’re deployed. Until recently, I used to build the content locally using a Jekyll Docker image, commit and push the generated content to my GitHub repo, SSH to my web server, and pull the changes from the repo.

The process was quite annoying, which is why I decided to set up a CI/CD (Continuous Integration and Delivery) pipeline, using GitLabCI.

Pipeline

The CI/CD pipeline I’ve implemented is the following:

The pipeline is defined in a file .gitlab-ci.yml at the root of the project:

The test step builds the Jekyll project, then runs HTMLProofer on the generated files. This step will check and validate the HTML output.

The deploy step transfers the generated files to my home gateway, then runs a script (located on the gateway) to transfer those files to my web server (the web server is not exposed outside of my network).

SSH Configuration

The gateway is accessed via SSH. To do that, I’ve created a specific SSH key only used by GitLab CI.

To generate a new SSH key:

ssh-keygen -o -t rsa -b 4096 -C "gitlabci"

The public key needs to be added to the authorized keys before it can be used:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

Configuration

The pipeline contains variables to improve the security:

SSH_PRIVATE_KEY: a base-64 representation of the SSH private key used to access my gateway. The value is retrieved by running this command on the gateway:cat id_rsa > base64 -w0

SSH_HOST_KEY: the RSA key of the gateway. Retrieved by running on the gateway:ssh-keyscan -t rsa server_ip

SSH_SRV: the SSH connection information, like my_user@my_server

SSH_PORT: the SSH port on the gateway

Usage

I can now follow the following process to publish changes to my website:

if needed, clone the GitHub repo on my computer

make the changes (create a new blog post,…)

test the changes locally (the Docker compose file allows me to build and serve the website on my computer)

commit and push the changes

if I push to a branch other than master, only the test step is executed

if I push to master, the whole pipeline is executed, so my site is built, tested and automatically deployed.