Blog » Setup your own GitLab CI runner in minutes with Docker Compose

Setup your own GitLab CI runner in minutes with Docker Compose

Found out that some people find this blog because they want to run GitLab in Docker. If this you? Maybe this Git repo can help you out! This post is about running a GitLab CI runner in Docker.

For my own projects I've always just used GitLab shared runners within their free tier. This worked out fine.

But sometimes, I ran out of CI minutes.
And I just didn't want to spend 10 dollars on CI minutes, it's just more fun setting up my own runners on my own hardware for side projects! So let's use that server that is is almost doing nothing the whole day besides running some home automation stuff).
And I was surprised; I've had my first runner working in about 5 minutes!

I've found this forum post with some Docker Compose file, and after setting up the docker-compose.yaml and after setting up the runner inside GitLab project settings and, adding the registration token to the .env I was ready to run docker compose up --build -d and my runner was ready to handle CI jobs with my own home server.

Step By Step setting up your runners

Add project runner to your GitLab project

  1. Go to https://[gitlab-project-url-here]/settings/ci_cd (Settings => CI/CD)
  2. Add a new "Project Runner" under the "Runners" section
  3. Setup the runner with platform "Linux" and check the "Run untagged jobs"
    1. For myself, I don't tag jobs. So I just want the runner to pickup every untagged job.
  4. If needed, add some description and other configuration. Save the runner and copy the token somewhere save. You will need this token later.
  5. Disable the shared runners

Now you are ready to setup you runner on your machine with Docker Compose

Setting up your first runner in Docker

1. Use the docker-compose.yaml from the blog post or what you find below:

docker-compose.yaml

services:
  dind:
    image: docker:20-dind
    restart: always
    privileged: true
    environment:
      DOCKER_TLS_CERTDIR: ""
    command:
      - --storage-driver=overlay2

  runner:
    restart: always
    image: registry.gitlab.com/gitlab-org/gitlab-runner:alpine
    depends_on:
      - dind
    environment:
      - DOCKER_HOST=tcp://dind:2375
    volumes:
      - ./config:/etc/gitlab-runner:z

  register-runner:
    restart: 'no'
    image: registry.gitlab.com/gitlab-org/gitlab-runner:alpine
    depends_on:
      - dind
    environment:
      - CI_SERVER_URL=${CI_SERVER_URL}
      - REGISTRATION_TOKEN=${REGISTRATION_TOKEN}
    command:
      - register
      - --non-interactive
      - --locked=false
      - --name=${RUNNER_NAME}
      - --executor=docker
      - --docker-image=docker:20-dind
      - --docker-volumes=/var/run/docker.sock:/var/run/docker.sock
    volumes:
      - ./config:/etc/gitlab-runner:z

2. Add this to a .env file and fill in your runner name and registration token

.env

RUNNER_NAME=RUNNER-NAME
REGISTRATION_TOKEN=TOKEN
CI_SERVER_URL=https://gitlab.com/

Now run docker compose up --build -d and your runner will get started.

Now you can trigger a CI job, and your personal runner will handle it!

Running multiple runners

If you want to run multiple runners, you can for example add this below your docker-compose.yaml

docker-compose.yaml

  runner2:
    restart: always
    image: registry.gitlab.com/gitlab-org/gitlab-runner:alpine
    depends_on:
      - dind
    environment:
      - DOCKER_HOST=tcp://dind:2375
    volumes:
      - ./config2:/etc/gitlab-runner:z

  register-runner2:
    restart: 'no'
    image: registry.gitlab.com/gitlab-org/gitlab-runner:alpine
    depends_on:
      - dind
    environment:
      - CI_SERVER_URL=${CI_SERVER_URL}
      - REGISTRATION_TOKEN=${REGISTRATION_TOKEN2}
    command:
      - register
      - --non-interactive
      - --locked=false
      - --name=${RUNNER_NAME2}
      - --executor=docker
      - --docker-image=docker:20-dind
      - --docker-volumes=/var/run/docker.sock:/var/run/docker.sock
    volumes:
      - ./config2:/etc/gitlab-runner:z

And add this to your .env.

.env

RUNNER_NAME2=RUNNER-NAME-FOR-SECOND-RUNNER
REGISTRATION_TOKEN2=TOKEN-FOR-SECOND-RUNNER

Now some second runner can be spin-up with the same docker compose file. Make sure the volumes are mounted to a second config directory, and the registration token/runner name are updated.

All runners will share 1 dind (Docker in Docker) container.

For myself I now have 3 runners up and running, ready to handle CI jobs. All within ~20 minutes!

Having questions/tips/want to say thanks?

Please leave some comment below! I will be happy to hear from you!

Post your comment

Comments

No one has commented on this page yet.

RSS feed for comments on this page | RSS feed for all comments