Thumbnail image

GitHub Pages vs GitLab Pages - Improving CI/CD for Static Sites

Sun, Jun 7, 2020 7-minute read

GitHub Pages is a really easy way to get a static site up and running with a static site generator like Jekyll, Hugo, Gatsby, etc. This site is built using Hugo. My first iteration was deployed via Travis CI to GitHub Pages using a builder bot. It is totally functional and deploys easily enough.

The main issue I have with the current deployment using Travis CI is builds take 7-8 minutes for each pull request or merge to master. This takes up quite a bit of time. Because of the fact that there is a build for both PR and merge to master, each change to the site will take at minimum 15 minutes. I have been thinking of ways to use new tools to streamline this. I have had both GitLab and GitHub accounts for a while, but I have primarily used GitHub (there isn’t any particular reason why that’s the case.) Both services have been fine for what I need to do, but I have a lot more hands on experience with GitHub.

Why GitLab?

GitLab was one of the first repository management platforms that offered DevOps tools. I have heard that as a result, their CI/CD platform is very mature and robust compared to some others. I wanted to see what all the buzz is about. GitHub now has GitHub Actions, but I wanted to get out of my comfort zone to use some new platforms and tools (perhaps I will test using GitHub Actions at a later date).

Another reason I chose GitLab to test is I wanted to see how reliable GitLab’s offerings are. I have heard good things about GitLab. Meanwhile, I’ve personally experienced a small handful of issues with things like GitHub webhooks failing to send/trigger builds due to outages (it isn’t common, but it has happened occasionally due with GitHub reporting issues on their end). While I don’t personally use GitHub Actions, I do see frequent notifications from GitHub reporting issues. I can’t really speak on how minor or major these issues actually are, but I do see the notifications about that service.

Initial Prep

Prior to starting this I had already created a .gitlab-ci.yml and it was already added to the project. When researching what would be needed for this file, I noticed Hugo had a guide for deploying on GitLab. Looking at the configuration for this, I realized that I wouldn’t really have to change anything from the base config, which is the following:

image: monachus/hugo

variables:
  GIT_SUBMODULE_STRATEGY: recursive

pages:
  script:
  - hugo
  artifacts:
    paths:
    - public
  only:
  - master

My site was already uploaded to my GitHub account. Using GitLab’s import functionality, I imported my repo from GitHub to GitLab. From there I just ran the pipeline and waited for it to complete. I noticed that the builds were immediately faster.

Difficulties and Differences

Getting Started

After running the first pipeline, the site did deploy successfully but the CSS was not displaying properly and the site was not visually acceptable. Using Hugo to build the site both on my local PC and via Travis CI, there were no issues. To get it working on GitLab pages a little bit of modifying needed to be done to the config.toml. It appears that this can occur because the URL that is used for GitLab pages is a bit different. GitHub Pages would use al-haras.github.io for the project and locally it is just localhost. When using GitLab Pages to host the site the base URL is al-haras.gitlab.io/alex-haras-hugo. Thus, adjustments are needed for the baseurl value.

If you are migrating from GitHub, you may need to modify your config.toml. This is the diff for the adjustments I made:

image

All and all, it was a minimal change and wouldn’t deter me.

Builds

Using GitLab to deploy my site, my build and deployment times dropped substantially. The builds went from 7-9 minutes to 46 seconds. That is an unbelievable amount of time saved. In additon, I did not need or want to create a bot account to deploy my site. I also did not need to add and mask credentials for the builds. It just runs and deploys your code.

GitLab CI - 47 seconds image

Travis CI - 7 minutes 34 seconds image

Something else that isn’t needed for GitLab is seperate repos for Hugo files, and the website files that Hugo generates. The CI tool just runs and deploys the public directory. It is very simple to setup.

SSL Certificates

Both GitHub Pages and GitLab Pages offer the ability to use SSL certs and automatically redirect http requests to https. Both also have the ability to automatically create SSL certs via LetsEncrypt. A difference is that GitLab allows you to upload and use your own SSL certs rather than using the LetsEncrypt certs. It is nice to see that offered. At the time of writing this, with GitHub Pages this is not available and the only option is to use the GitHub provided LetsEncrypt certs.

DNS - Custom Domains

I will say that GitHub Pages is a bit easier to setup DNS for custom domains. You just need to create A and CNAME records for your. GitLab requires that you additionally verify your domain ownership via a TXT record. Not that this is terribly difficult, but it is a difference.

Site Performance

I will just say it right off the bat. The GitHub Pages site loads faster. The GitLab Pages site is absolutely usable, but it is very difficult to see any difference in performance between the GitHub Pages site and using Hugo to serve the site locally (cache was cleared before testing). Both text and picture content load great with GitHub Pages. It is noticably slower on GitLab Pages which is disappointing. Site performance is one of my most important requirements for this project.

Will I Move to GitLab?

I would love to move to GitLab based on the build times. GitLab is a great platform and the CI/CD tools were really easy to work with. However, after looking at the performance of both sites side by side, it is hard for me to get over the difference. GitHub Pages just seems to be the better performer between the two. I think that rather than fully migrating to GitLab it would be best to first revisit the Travis CI builds and see if they can be improved.

A part of why my Travis CI builds take so long is both Go and Hugo are downloaded during the build. The container image recommended by Hugo for GitLab is monachus/hugo which has Hugo already installed. I thought about it and decided to refactor my Travis CI pipeline as I could very well see similar build times. Ideally, I’d be able to achieve this without sacrificing site performance.

Refactoring Existing CI/CD - GitHub Pages and Travis CI

Looking at the Travis CI documentation, Travis CI supports snaps (including Hugo) which I had not realized before. Just installing Hugo via snap would save quite a bit of time for the current builds due to not needing to install both Go and Hugo. I modified my .travis.yml accordingly:

---
dist: bionic
addons:
  snaps:
    - hugo
script:
  - hugo
branches:
  only:
  - master
deploy:
  local_dir: public
  repo: $SITE_REPO
  target_branch: master
  provider: pages
  skip_cleanup: true
  github_token: $GITHUB_TOKEN
  email: $GITHUB_EMAIL
  name: $GITHUB_USERNAME
  on:
    branch: master

On the next build, I got exactly what I was looking for.

Travis CI - 30 seconds image

My build times for PRs dropped from 7-9 minutes to 30 seconds. My deploy builds now take about 55 seconds. Build times are nearly tenfold less overall. I was able to achieve the same result benefit as I was on GitLab while keeping the same site performance by adjusting the existing process slightly.

Wrapping Up

After working on this project with GitLab there are a lot of features that GitHub simply lacks. GitLab is an incredible platform and has a lot of features that I didn’t realize it had. I am incredibly interested in working with it to work on other projects. While the performance of GitLab Pages didn’t wow me, the CI/CD and other tools did and I look forward to using it in the future.

If the site performance was the same, I would really consider moving from GitHub to GitLab as I feel like GitLab has more features.

All and all, this was a great experiment to do. I was able to learn a bit more about GitLab and reflect on the current CI/CD pipeline and implement some improvements.