Building a basic Content Management System with Jekyll and Gitlab CI/CD

Mar 15, 2019

Using Jekyll has made maintaining my website a hell of a lot simpler, but I did miss the ability to edit documents online that I got from a CMS. But with Gitlab CI/CD hooked up to my server, I can use the Gitlab interface as an online CMS interface. Jekyll This particular brief tutorial is focused on those of you who are using VMs to host your stuff, rather than AWS or Azure. The Gitlab CI script that we product fires your site across to the server by SCP. If you’re using another sort of server, then a few tweaks should get you running.

Step 1 - Put the code on Gitlab

Fairly straightforward, this one. Get an account, and push your code up to it.

Step 2 - Make sure you’ve got an ssh login to your server

So before you can use Gitlab CI to deploy to your server, you need to make sure that you have access to it via SSH. There’s a host of documentation on the net about setting this up, and it’ll be specific to the OS that you’re running. This one, for example, gets you pretty far on some versions of Ubuntu, but doesn’t mention the “authorized_keys” file, so you’ll want to make sure you have the right instructions for whatever version of your OS you’re running, too.

Step 3 - Set up Gitlab CI

There are really two parts to this. The first is setting up a simple flow, the second is making sure that your Jekyll site is rebuilt before it’s pushed across to your server.

This first script will fire across whatever is in your repository to a location that you’ve specified on your server:

image: ubuntu:latest
stages:
  - deploy
deploy_jekyll:
  stage: deploy
  environment:
    name: Staging
    url: "$JEKYLL_URL"
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - mkdir -p ~/.ssh
    - eval $(ssh-agent -s)
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - ssh-add <(echo "$PRIVATE_KEY")
    - ssh -o StrictHostKeyChecking=no root@"$JEKYLL_SERVER" 'rm -rf /var/www/target'
    - scp -v -P22 -r $(pwd) root@"$JEKYLL_SERVER":/var/www/target

So you’ll see there are a few variables in there. You’ll have a private key ready, for accessing your server. Upload that to the environment variables store in Gitlab, with the name “PRIVATE_KEY”, and mark it as protected. Likewise, you should set an environment variable of “JEKYLL_SERVER” to the domain that ssh is going to be connecting to for file transfer.

Obviously you’ll want to change “/var/www/target” to wherever it is on your server that you’re storing your site files.

Now, as long as you’re able to build your Jekyll site before pushing it to Gitlab, this is fine, but as we want to use Gitlab as a pseudo-CMS - perhaps from our phones - we won’t be able to do that. We’ll have to get Gitlab to build the site for us. We’re going to use Bundler to run the ‘jekyll build’ command to build our site. Unfortunately the straight Ubuntu Docker image which we used in the previous example doesn’t include Ruby or Bundler, but the default Ruby image does.

image: ruby:latest
stages:
  - deploy
deploy_jekyll:
  stage: deploy
  environment:
    name: Staging
    url: "$JEKYLL_URL"
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - mkdir -p ~/.ssh
    - eval $(ssh-agent -s)
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - bundle install --path=vendor
    - bundle exec jekyll build
    - rm -r vendor
    - ssh-add <(echo "$PRIVATE_KEY")
    - ssh -o StrictHostKeyChecking=no root@"$JEKYLL_SERVER" 'rm -rf /var/www/target'
    - scp -v -P22 -r $(pwd) root@"$JEKYLL_SERVER":/var/www/target

Note that after executing the jekyll ‘build’ instruction, we delete the “vendor” directory. This is very important - a load of random Ruby files kicking around in your site might not be the end of the world, but the painfully slow upload times that come with them are certainly painful.

Step 4 - Build stuff with Gitlab CI!

If you’ve done all of that in the right order, then hey presto! You can now edit your files in raw markdown or the Gitlab IDE and update your site in real-time from anywhere in the world!