Continuous Integration and Deployment, or CI/CD, is the process of streamlining and accelerating development by automatically building and testing every commit to your project. GitLab integrates CI/CD into their git solution extremely well, and we’ll show how to set it up and work with it.

Setting Up a Build Server (GitLab Runner)

Often, compiling code can be an extremely intensive operation. Not all languages have this issue, but some, like C++, can take over half an hour to complete a complicated build. Chromium, for example, can take over an hour even on 12-core systems, as shown here in this graph from GamersNexus.

Time is money, so many companies will opt to have dedicated build servers, often a swarm of servers, and run their CI/CD pipelines on powerful hardware.

If you’re not self hosting, and are instead using GitLab’s online SaaS solution (gitlab.com), then you’ll need to pay for CI/CD minutes. The free tier includes 400 CI/CD minutes, which should be enough for simple projects, especially languages like JS where all that may be necessary is a basic npm build. The higher tiers, which charge per user, offer much more build time. You can view the up-to-date totals from GitLab’s pricing information page.

In our case, we’re self hosting, so we’ll need to set up a GitLab Runner, which installs on a server and configures it as a build agent. This is available as a binary as well as a Kubernetes deployment, which may be ideal for auto-scaling multi-server deployments.

Fortunately the install process is simple. You’ll need to find which binary you’ll need for your host, and download it. For Debian based systems like Ubuntu, that would be the deb package:

And install it with dpkg:

Next, you’ll need to configure it with the URL and token found in /admin/runners.

You’ll be asked to specify what executor this runner should use. In most cases, you can just use “docker,” with a default image like ubuntu.

Once configured, you can start the runner:

Then you should see it in the list.

In our case, there was a weird bug where the runner would not start because the /var/lib/gitlab-runner folder was not present. Manually creating it solved the issue immediately:

You will need to open the settings for the runner, and set proper tags for it that will get picked up by matching gitlab-ci.yml config files. If you’d instead not bother with tags, you can check this box here to pick up untagged jobs:

Next, you’ll need to configure your projects to use this runner.

Setting Up CI/CD For Your Project

Configuring GitLab CI is done with a file at the root of your project, called .gitlab-ci.yml. This is automatically used to run.

Of course, the exact configuration of this will depend highly on you and your needs. A good place to start would be looking up how others have done it for your language and runtime.

For example, a simple .NET build can be run using a config like the following:

First, we need to set the Docker image that GitLab will use to build your application. This is important because otherwise the environment won’t have the .NET runtime. Before anything, it runs dotnet restore, then runs dotnet build to actually build the application.

To learn more about the structure of this file, you can consult GitLab’s documentation.

Once committed to your repo, that commit will trigger the first pipeline. You can view pipeline results under CI/CD > Pipelines, where you’ll see each run alongside its status.

If you click the details, you can debug what went wrong with failed run, as it keeps a log of the console.