Setup static website hosting with Gitlab pages

Introduction

This article covers how to setup a static website (HTML/Jekyll) with Gitlab and Gitlab-CI. Gitlab is a git repository hosting solution and comes in two flavors: a community edition and an enterprise edition. What’s described in this article is supported by both flavors. Gitlab-CI is an addendum to Gitlab and may be used to setup pipelines and provide continuous integration for code deployments.

Architecture

A high-level flow of what we are going to talk about in this article can be described with this schematic.

We are going to keep things simple and not worry about things like scalability at the moment. As such we will have all our components in one box. However, please note this is not ideal for a production environment.

Implementation

We are going to start with setting the things we need up and move on to creating a test static website. The only prerequisite required for this tutorial is an installation of Gitlab community or enterprise edition. We are also going to work on an Ubuntu box. For other distros, while the conceptual basis of this article would remain unchanged, you may have to adjust some commands and settings.

Set up Docker

Setting up Docker is pretty straight forward and there are several articles on the Internet for it. As such I am going go over just the basics and leave everything that’s not relevant to this article out.

Add the GPG key for the Docker repository:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add the Docker repository to the APT sources:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Update your package database:

sudo apt-get update

Install Docker:

sudo apt-get install -y docker-ce

This would install and start Docker up. For our example, we are going to install just one image: rails. At the time of writing this article, these were the available images.

sudo docker search rails
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
rails                          Rails is an open-source web application fr...   692       [OK]
bluebu/rails-alpine            rails-alpine with different ruby version, ...   6                    [OK]
asux/rails                     Docker base image: Rails + Puma                 5                    [OK]
dkubb/alpine-rails-nginx       An Alpine Linux container for Rails applic...   3                    [OK]
bitnami/rails                  Bitnami Ruby on Rails Docker Image              3                    [OK]
instedd/nginx-rails            nginx rails                                     3                    [OK]
toxix/debian-rails             Debian based Ruby on Rails incl. imagemagi...   2                    [OK]
newsdev/rails                  The base Ruby image with additions to supp...   2                    [OK]
tenstartups/rails                                                              2                    [OK]
zumbrunnen/rails               Ruby on Rails image, using Passenger Stand...   2                    [OK]
ledermann/docker-rails         Simple Rails application to demonstrate us...   1                    [OK]
citizensadvice/rails           The Citizens Advice Ruby on Rails base image    1                    [OK]
mainlxc/nginx-rails            nginx-rails                                     1                    [OK]
liulantao/rails                Docker/Rails develop environment.               1                    [OK]
opensnp/rails                  opensnp.org                                     1                    [OK]
inklusive/rails                Custom rails build                              0                    [OK]
noonarai/rails-new             for just running rails new                      0                    [OK]
justincampbell/rails-compile   Environment for compiling a Rails app (bun...   0                    [OK]
uniqrn/rails                   rails image bundled relating gems               0                    [OK]
fishisfast/rails               Fishisfast rails image with nginx to serve...   0                    [OK]
convox/rails                   Convox base image for Ruby on Rails             0                    [OK]
bitnami/che-rails              Bitnami Rails Docker Image for Eclipse Che      0                    [OK]
reqvu/rails                    Rails                                           0                    [OK]
krismichalski/docker-rails     Ready to use Docker image for running Ruby...   0                    [OK]
fredym/rails                   Rails Docker Image                              0                    [OK]

We are going to install the very first one.

sudo docker pull rails

Setup continuous integration

Assuming that you have a working installation of Gitlab, let’s go about setting up continuous integration with Gitlab and Gitlab-CI.

Install one or more runners

Gitlab-CI uses “runners” as workhorses for compiling code. Runners are primarily connector code that can pull code from a git repository and run a pre-defined set of commands on a pre-defined platform. For example, say we want to build a project containing Java code on git push. When we push code into a Gitlab repository and the repository contains a build file (Gitlab calls it .gitlab-ci.yml, it’s YAML and needs to be present in the root directory of the project), Gitlab would trigger Gitlab-CI to build the code which in turn would trigger one or more runners which in turn would call (say) a Docker container and build the code. Pretty simple, right. Now Gitlab has two flavors of runners: a single runner and a multi-runner. As the names suggest, a single runner can run only one build at a time whereas a multi-runner can fork other runners to run multiple builds in parallel. We are going to install the multi-runner.  Assuming we have the Gitlab repository in our APT sources,

sudo apt-get install gitlab-ci-multi-runner

Register a runner with Gitlab

Gitlab needs to know where all its runners are at. To register a runner with Gitlab:

gitlab-ci-multi-runner register
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://mygitlabinstance.com/
Please enter the gitlab-ci token for this runner:
xxxxxxxx

The first prompt is the URL to your Gitlab instance and the second is a unique token found at Admin > Overview > Runners, like so:

We need to do this every time we want to register a new runner. When one or more runners are registered, it will show up in Admin > Overview > Runners, like so:

We need to make sure our runner is setup as a shared runner. A shared runner may be used by any build in a Round-Robin fashion whereas specific runners need to be assigned to projects.

Setup Gitlab pages

Now that we have continuous integration set up, it’s time to set Gitlab pages up. Gitlab pages is enabled by default. All the setup we really need to do is provide a domain for our pages. Now there are several approaches to setting domains up with Gitlab pages. One may set up a custom domain for a group of repositories serving some pages or one may set up a wildcard sub-domain to serve any and all kind of pages from any and all kind of groups or one may point a custom domain to one repository of pages as well. For this article, we are going to create a wildcard sub-domain and point it to our installation of Gitlab pages. That will help us achieve get URL’s like <repo_group>.domain.com/<repo_name>.

Setup a wildcard sub-domain

This is a simple one. We need to head over to our domain’s DNS settings and add an A record (for IPv4) or an AAAA record (for IPv6) or both. For IPv4, it would look something like:

A    *    1.1.1.1    Automatic

where the first column is the record name, the second column is the sub-domain alias, the third is the IP address and the fourth is the TTL.

Add the domain information to Gitlab config

Open up gitlab.rb, usually in /etc/gitlab and search for pages_external_url. Add your domain name there. For instance, say if our domain is domain.com and our wildcard character sub-domain is *.domain.com, we need to add http://domain.com/.

Setup a project

We are going to setup a simple project with two file: a .gitlab-ci.yml and a index.html. Our build file (.gitlab-ci.yml) would tell Gitlab CI to deploy our HTML files to a public directory ready to be served to the World Wide Web, like so:

pages:
  stage: deploy
  script:
  - mkdir .public
  - cp -r * .public
  - mv .public public
  artifacts:
    paths:
    - public
  only:
  - master

And a index.html:

This is for https://abhishekdeydas.com/setup-static-website-hosting-with-gitlab-pages.

A git push would trigger a build which would pick up our runner. All pipeline builds are recorded under Pipelines like so:

You may click on the job number and the deploy stage to see the console log for the build, like so:

After the build succeeds, we need to go to Settings > Pages in our Project to get the URL to our Gitlab pages website, like so:

And that’s about it!