26. Self-hosted GitLab Runner. Про DevOps. Run CI jobs locally. Docker-in-Docker

Відео версія
(YouTube - для зворотнього зв'язку)

TL; DR

Ніколи не встановлюйте GitLab Runner (Jenkins або щось інше) на продакшн-сервер. Використовуйте окремий деплой-сервер або хоча б stage-сервер.

У проєкті GitLab Build => Runners => New group runner => Вводимо тег і копіюємо токен.

Раджу використовувати теги — це допоможе в розумінні, які проєкти використовують які runners, і дозволить обмежити використання ресурсів для джобів.

Далі розгортаємо runner у Docker'і:

run docker container
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest

/srv/gitlab-runner/config — містить файл конфігурації config.toml.

register runner
docker exec -it gitlab-runner gitlab-runner register \
  --non-interactive \
  --name "local" \
  --url "https://gitlab.com/" \
  --registration-token "secret" \
  --executor "docker" \
  --docker-image "docker:26.1.3" \
  --docker-privileged \
  --docker-volumes "/cache" \
  --docker-volumes "/certs/client" \
  --docker-shm-size 0

Для Docker-in-Docker (DinD) важливі параметри: docker-privileged та docker-volumes "/certs/client".

Файл конфігурації буде згенерований таким чином:

/srv/gitlab-runner/config/config.toml
concurrent = 10
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "local"
  url = "https://gitlab.com/"
  id = 41131741
  token = "secret"
  token_obtained_at = 2024-09-11T00:00:52Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:26.1.3"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/certs/client"]
    shm_size = 0
    network_mtu = 0

concurrent — за замовчуванням встановлено значення 1, але я рекомендую збільшити його для можливості запуску кількох пайплайнів одночасно.

DinD є важливим у випадку, коли необхідно запускати Docker-контейнери як частину джобів. Це ізолює контейнер всередині іншого контейнера, запобігає конфліктам і надає доступ до файлового сховища Docker'а.