Rubber ducking a blog. Part 2 GitLab Pages
In my last posting I showed the technical bits about how this website is built. This post is dedicated to its hosting solution. 😁
The repository for this website is hosted on the Online version of GitLab so it was only natural to use GitLab Pages to host the actual blog.
You might already be familiar with Github Pages. Well, GitLab's implementation has identical goals: free hosting for static websites. The way they get there, though, is different. While Github only supports raw HTML files or Jekyll websites, GitLab Pages makes use of GitLab CI to work with any kind of build chain. And the best Part? GitLab CI is offered for free to all repositories hosted on the Online version of GitLab.
All you need to do to get GitLab to host your website for you is to define a CI job named
pages that exports a
public/ directory. The content under
public/ will then be available at
https://<username>.gitlab.io/<repository> or a custom domain, if you own one. You can get a site up at the root of the domain just by naming the repository
In this post I am going to go through the GitLab CI and Pages config for this website.
The GitLab docs offer a lot of information on both CI and Pages but it's a little dense for a quick start. I propose a simplified
.gitlab-ci.yml as a starter config:
$ cat - > .gitlab-ci.yml <<EOF pages: stage: deploy script: - echo "building" - mkdir public - echo "Hello" > public/index.html artifacts: paths: - public only: - master EOF
There are a couple of things happening in that file so let's take them one by one:
- It declares a
pagesjob. GitLab CI will automatically look for it and run it.
stage: deployadds the job to the
deploystage. A CI pipeline is formed out of multiple stages. GitLab defines a bunch of default stages (
deploybeing one of them) and you can define custom ones as well. You can read more about them here.
scriptattribute defines the series of steps needed to build the site.
- It marks the
public/directory as an artifact. GitLab is going to store it indefinetly on its servers.
only: mastersets up the
pagesjob to run only on changes to the
For this site I'm using:
image: node:latest pages: stage: deploy script: - npm install - npm run build artifacts: paths: - public only: - master
Not all that different from the starter
.gitlab-ci.yml. The only new thing is the
image: node:latest line. Through that I tell GitLab CI that the build script requires the
node:latest Docker image in order to run. You can use any image available on Docker Hub.
The only thing left to do is to setup a custom domain to the website. This is a two-step process: first we need to tell GitLab the custom domain we're going to be using and then to update the DNS settings of the domain.
You can add a custom domain to GitLab by going to the Pages settings tab of your repository and clicking on "New domain".
When I first wanted to add the custom domain to GitLab I encountered an error in the settings page telling me to "Contact System Administrator to add domains and certificates". Fortunately, in my case, the issue fixed itself the next day (probably a caching issue?) but if you encouter the same problem you should follow this thread on the GitLab Community Forums.
Now on to updating the DNS settings. This step depends on your own solution to managing DNS settings. I'm using Cloudflare because their service is free and comes bundled with a SSL certificate. Be warned though that the way Cloudflare works is by basically man-in-the-middle-ing your website. This is fine for a static website (I'm not worried about Cloudflare serving fake information about me) but could be a problem for a webapp that deals with any kind of user data
Add a new DNS A record to
220.127.116.11 if you plan on serving the site on the naked domain (e.g. just https://alexghr.me) or a CNAME record to
<username>.gitlab.io if you plan on serving under a subdomain.
That's it. In two relatively easy steps you can get a website built and deployed to the whole Internet.