How to run your own GitLab CI Runner for 1.28€/mo and why it's worth a try

by Puzl Team
Last updated on 10 Feb, 2024
We've made some exciting updates

This article covers the old GitLab runner setup on We're thrilled to announce our new SaaS Runners for GitLab, arguably the world's fastest and most cost-effective solution for running GitLab pipelines.

Dive in and see why it's a game-changer, all without any code adjustments on your end!

Get free trial

In this article, we will show how to easily deploy your application to Kubernetes on the example of and GitLab Runner, why it might be better to install your own CI runner, and how Puzl helps you to reduce costs and headache in this case.

Why set up your own GitLab runner

GitLab Runner allows you to run GitLab pipelines and returns the results of the pipeline work back to GitLab. You can even run any application and databases in your pipelines.

Even though popular git-providers offer free pipeline minutes, there are several reasons why you should consider having your own CI runner.

Since Puzl provides you free direct access to your own cloud Kubernetes namespace, you can create burstable Pods and pay only for resources utilised by your running pipelines based on the pay-per-pod model. It means that:

  • Your pipeline on Puzl will be executed within a minimum possible amount of time because its resources won’t be limited. Shared cloud runners can not offer that flexibility.
  • You will never exceed the free limit (Puzl has no free limit) and will never be switched to an overpriced tariff. Puzl offers fair, transparent and predictable pricing.

Starting from September 2020 GitLab reduced the amount of free pipeline minutes from 2000 to 400. In case you need more, you will have to pay $10 for every 1000 minutes. Let’s calculate price of that 400 minutes on Puzl and why it might be better for you to pay for the first 400 minutes, than use shared cloud runners.

Let’s assume that your pipelines had been working for 7 hours (420 min) within a month and consumed precisely 4GB of RAM and 2vCPU during the whole period of work. In this case, the cost of the runner and all pipelines launched by it will be:

  • 1.28€ for the runner itself, which is working for the whole month non-stop and can serve thousands of pipelines;
  • 0.039€ per hour for 7 hours of pipelines, which equals to 0.273€.

That makes 1.55€ per month, totaly. In fact, 1.55€ are your maximum monthly costs in comparison with cloud pipeline minutes. At the same time, Puzl saves you money if you use more than 400 pipeline minutes per month, and also Puzl saves you time on waiting for pipeline’ execution on shared runners.

Why use Puzl instead of cloud instances

  • You don’t have to rent unnecessary cloud instances, that will be idle most of the time when no pipes are running.
  • You don’t have to run benchmarks to estimate how many resources your pipeline consumes to rent cloud instance of suitable configuration.
  • You don’t have to bother about scaling your cloud instances in case of a sharp increase in the number of pipelines run simultaneously: every new pipeline runs in a separate Kubernetes pod. It allows you to allocate resources flexibly and without sacrificing performance.

One of the most powerful aspects of Puzl is that your pipelines are running inside your isolated Kubernetes namespace. That means that you can interact with Kubernetes API directly from the code of a pipeline, which makes your GitLab pipelines an efficient automatisation tool.

Install your own GitLab Runner in your Puzl Kubernetes namespace

We will use a small dummy HTTP server built with Python, to demonstrate GitLab Runner installation process.


  • Puzl’s example sanic server, where we have already set up deployment and build configuration:

    • .gitlab-ci.yml - configuration of GitLab pipeline
    • Dockerfile - Docker Image to deploy our HTTP server. To build your Docker image, we recommend Kaniko: it allows you to safely build a Docker image from a Dockerfile, without using Docker daemon.
    • example-sanic-server.yaml - simple deployment configuration for Kubernetes to run our server in Puzl cloud.
  • Docker Hub account to push your built Docker Image.

  • GitLab account.

  • Puzl Cloud account.

Install the GitLab Runner app in Puzl cloud dashboard.

  1. Find GitLab Runner in the Marketplace section of your Puzl dashboard, press Install.
  2. Fill in Token and URL: In your GitLab account, go to the Project > Settings > CI/CD > expand Runners section and copy token and the URL.

Get Gitlab Runner token

  1. Fill in the tag (e.g. puzl-runner, puzl) which you want to associate with the runner. Remember to put this tag to the tags section of your project’s .gitlab-ci.yml as well.
  2. Press Install and get your runner up and running in a minute.

Swipe image to play

  1. To check that your runner is working, in the GitLab go to the Project > Settings > CI/CD > Runners.

Check Gitlab Runner

Configure Runner on GitLab

Now, we need to configure GitLab project variables. Go to Project > Settings > CI/CD > Variables and add the following variables:

  1. Set up Docker credentials: log in your Docker Hub account by cli with the command docker login. Get the contents of ~/.docker/config.json and put it in the separate variable under the name DOCKER_REGISTRY_CONFIG (as it’s used in .gitlab-ci.yml). ⚠️ Set variable type as File.

    ⚠️ Note: your config should contain key auth like in the example below. All other keys are not required.

    "auths": {
    "": {
    "auth": "a2N...JE="

    If there’s no auth key, you should remove the key credsStore from the generated config and do docker login again. This time auth key should be there.

  2. If you need access to k8s api from pipeline set variable with name KUBERNETES_SERVICE_ACCOUNT_OVERWRITE and value user.

  3. Add the following files to your project: Dockerfile, example-sanic-server.yaml, .gitlab-ci.yml and wait for the pipeline to finish.

    Don’t forget to specify your DockerHub account name in the .gitlab-ci.yml script section instead of puzlcloud:

    - /kaniko/executor --context $CI_PROJECT_DIR
    --dockerfile $CI_PROJECT_DIR/Dockerfile
    --destination YOUR_DOCKERHUB_NAME/example-sanic-server:0.1.0

    Do the same in example-sanic-server.yaml:

    - name: example-sanic-server
    image: YOUR_DOCKERHUB_NAME/example-sanic-server:0.1.0
  4. When the pipeline is finished, you will see Pod with example-sanic-server running on your Pod’s page.

Check Gitlab Runner

Access your test server

Once your Pod is Running, you can access your HTTP server by an external port and a hostname, specified in the Network panel on the Pod’s page.


Port was created automatically from the config, specified in example-sanic-server.yaml. Note, that such label is required to display the port in your Puzl Dashboard:

example-sanic-server.puzl/Deployment: ""

Add Gitlab Runner Variable

Don’t forget to subscribe to our Twitter to not miss the important updates!