GitLab Runner opzetten: blaas leven in je pipeline

“Ik heb de instructies gepusht, waarom gebeurt er niets?”

De vorige keer schreef ik vol ambitie een .gitlab-ci.yml-bestand en deed een push. “Nu wordt de deploy toch automatisch uitgevoerd?” Vol verwachting klikte ik op het menu ‘CI/CD > Pipelines’ in GitLab.

Maar wat ik op het scherm zag, was geen groen vinkje, maar een eindeloos draaiende laadbalk en de statusmelding ‘Pending’. Toen ik op de melding klikte, verscheen deze waarschuwing.

This job is stuck because the project doesn't have any runners online assigned to it.

Vrij vertaald: “Er is werk binnengekomen, maar de werknemer (Runner) die het moet uitvoeren, is niet komen opdagen.” Verdorie — ik had wel het werkbriefje aan de fabrieksdirecteur (GitLab Server) gegeven, maar ik had helemaal geen werknemer (Runner) aangenomen die het werk in de fabriek zou doen.

Hoe perfect het bouwplan ook is, zonder ‘werknemer’ om het in elkaar te zetten draait de fabriek niet.

GitLab Runner: de handen en voeten van je pipeline

GitLab is grofweg in twee onderdelen verdeeld.

  1. GitLab Server (hoofdkantoor/fabrieksdirecteur): slaat de code op, beheert de status van de pipeline en geeft de opdrachten.
  2. GitLab Runner (filiaal/werknemer op de werkvloer): wordt op de eigenlijke server geïnstalleerd, krijgt de opdrachten van het hoofdkantoor, haalt de code op, bouwt die en voert de deploycommando’s uit.

“Kan GitLab niet gewoon zelf verbinding maken met mijn server en de deploy uitvoeren?” Als je erover nadenkt, is dat ronduit gevaarlijk. Stel dat een website op het internet (GitLab) zomaar mijn computer (server) thuis kan binnenkomen en commando’s kan uitvoeren omdat iemand op een knop drukt — dat is feitelijk ‘hacken’. Als iemand mijn GitLab-account zou kapen, zou hij mijn server zomaar kunnen omtoveren tot een Bitcoin-mining-machine.

Daarom maakt GitLab geen directe verbinding met mijn server. In plaats daarvan plaatst het een ‘goedgekeurde tussenpersoon (Runner)’ die alleen binnen mijn server werkt, en geeft het opdrachten uitsluitend via deze tussenpersoon. Het ingewikkelde installatie- en registratieproces dat we nu gaan doorlopen, is precies de ‘beveiligingsprocedure’ om deze tussenpersoon te authenticeren.

Stap 1: bekijk de vacature (token uitgeven)

Voordat we de Runner installeren, moeten we eerst bij het hoofdkantoor (GitLab) een ‘vacature’ plaatsen — “ons project heeft een werknemer nodig” — en een ‘registratiebewijs (token)’ ontvangen.

In de nieuwste versies van GitLab is de manier om het token te vinden, om veiligheidsredenen, een beetje verstopt.

  1. Open je GitLab-project
  2. Menu links: Settings > CI/CD
  3. Klik in de sectie Runners op Expand
  4. Klik rechtsboven in de sectie Project runners op de knop met de drie puntjes (⋮)

Als je op deze knop klikt, verschijnt er een popup-menu met daarin de informatie die we zoeken. Noteer en kopieer de URL en het Registration token.

(Let op: er kan een onheilspellende waarschuwing verschijnen: ‘Support for registration tokens is deprecated’. Dat betekent dat deze methode op termijn verdwijnt, maar voorlopig wordt hij om compatibiliteitsredenen nog ondersteund — geen paniek dus, kopieer gewoon het token.)

[Tip] Meerdere projecten? (Group Runner) Als je, net als ik, meerdere projecten (frontend, backend, enzovoort) onder één groep beheert, is het inefficiënt om voor elk project apart een Runner te registreren. In dat geval registreer je de Runner niet in de projectinstellingen, maar via het menu Group Settings > CI/CD. Een ‘Group Runner’ die je zo aanmaakt, kan in zijn eentje al het werk van alle projecten binnen die groep afhandelen. (Ik heb veel projecten, dus ik heb deze aanpak gekozen.)

Je moet het verborgen menu (⋮) openen om het token te zien. Dit token is de ‘geheime sleutel’ die de Runner met de server verbindt — laat het dus nooit uitlekken.

Stap 2: neem de werknemer aan (Runner installeren)

Laten we nu de Runner echt installeren op een Linux-server (of je eigen pc). De netste manier is uiteraard onze geliefde ‘Docker’ gebruiken.

# 1. Start de GitLab Runner-container
docker run -d --name gitlab-runner --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v gitlab-runner-config:/etc/gitlab-runner \
  gitlab/gitlab-runner:latest

  • -v /var/run/docker.sock:/var/run/docker.sock: dit is belangrijk. Omdat de Runner zelf weer andere Docker-containers (voor de build) moet opstarten, delen we de Docker-socket van de host met hem. (De Docker-in-Docker-aanpak)

Stap 3: onderteken het arbeidscontract (Runner registreren)

Met de installatie van de Runner ben je er nog niet. De Runner moet zich nog bij de GitLab-server registreren met de boodschap: “Ik ben de werknemer van project A.”

Laten we de net gestarte Runner-container binnengaan en het registratiecommando uitvoeren.

# Voer het registratiecommando uit in de runner-container
docker exec -it gitlab-runner gitlab-runner register

Vervolgens begint in de terminal een soort vraag-en-antwoordspel. Vul gewoon de gegevens in die je in stap 1 hebt gezien.

  1. Enter the GitLab instance URL:
    • https://gitlab.com/ (of het adres van je eigen GitLab-server)
  2. Enter the registration token:
    • (plak het token dat je net hebt gekopieerd)
  3. Enter a description for the runner:
    • my-runner-01 (maakt niet uit, als het maar een herkenbare naam is)
  4. Enter tags for the runner:
    • (Je kunt dit overslaan met Enter. Het is bedoeld voor als je de Runner alleen jobs met bepaalde tags wilt laten uitvoeren.)
  5. Enter an executor:
    • docker (we gaan bovenop Docker builden, dus vul je docker in.)
  6. Enter the default Docker image:
    • docker:latest (de image die standaard wordt gebruikt)

“Runner registered successfully.” Zodra deze melding verschijnt, is de aanname rond! Vernieuw nu de GitLab-pagina en je ziet een Runner met een groen lampje die roept: “Klaar (Online)”.

Als de koppeling lukt, kleurt het statuslampje van de Runner in het GitLab-scherm groen.

Stap 4: pipeline starten!

Op het moment dat de Runner geregistreerd is, komt de stilstaande (Pending) pipeline vanzelf in beweging. Running… en even later Passed!

Ik heb niets gedaan, maar de machine voert zelf de tests uit, doet de build, maakt de image en pusht hem naar de registry. Toen ik de terminal opende om de logs te bekijken, was het hele proces veel sneller en nauwkeuriger afgerond dan wanneer ik het handmatig had gedaan.

“Wow… het werkt echt?”

Wat eerst een handmatige deploy van 10 minuten was, is nu klaar met één git push. Ik kan nu een deploy starten en rustig een kop koffie gaan halen.

Praktijktip: Docker-permissieprobleem (Permission Denied)

Er is een fout die je bij de eerste keer instellen van een Runner met 99% zekerheid tegenkomt: dial unix /var/run/docker.sock: connect: permission denied

De Runner probeert Docker-commando’s uit te voeren, maar heeft daar geen rechten voor. Open in dat geval het gitlab-runner-configuratiebestand (config.toml) en zet de optie privileged = true aan.

# /etc/gitlab-runner/config.toml (runner-configuratiebestand)
[[runners]]
  name = "my-runner-01"
  executor = "docker"

[runners.docker]

privileged = true # Dit moet je op true zetten, anders werkt Docker-in-Docker niet goed. # …

Tot slot: nu kan ik naar huis

Eindelijk heb ik mijn eigen ‘deploy-robot’. Vanaf nu hoef ik me alleen nog op het schrijven van code te concentreren. Het saaie, repetitieve werk van controleren en deployen wordt overgenomen door mijn trouwe robot (Runner).

Maar er ontbreekt nog 2%. Op dit moment draait de pipeline onvoorwaardelijk telkens als er naar de master-branch wordt gepusht. “Wat als ik automatisch wil deployen naar de dev-server (dev), maar pas naar de productieserver (prod) als ik op een ‘goedkeuringsknop’ druk?”

De volgende keer kijken we naar slimmere pipelinebesturing met ‘deploystrategieën per branch’ en ‘handmatige goedkeuring (Manual)’.

Plaats een reactie