Привіт, це Kernelka! Сьогодні покажу, як швидко підняти локальний GitLab Runner у Docker на Linux, щоб автоматично збирати й тестувати ваші проєкти на Python та Node.js. Буде мінімум магії, максимум практики і трохи турботи про продуктивність 🚀
Що ви отримаєте
- Працюючий GitLab Runner у контейнері (Docker на Linux)
- Зразок .gitlab-ci.yml для тестів і збірки python в Linux і nodejs в Linux
- Кешування залежностей, артефакти та пара порад для стабільної контейнеризація
Передумови
- Linux-машина з доступом до інтернету
- Встановлений Docker (root або користувач у групі docker)
- Проєкт у GitLab і доступ до його налаштувань (щоб взяти токен для Runner)
Основний How-to
Крок 1. Встановіть Docker
Найшвидше — офіційний інсталер. Відкрийте термінал і виконайте:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
Перевірте, що все ок:
docker run --rm hello-world
Крок 2. Запустіть контейнер GitLab Runner
Створимо директорію для конфігів і піднімемо контейнер з монтуванням Docker-сокета (щоб job-и могли запускати контейнери):
sudo mkdir -p /srv/gitlab-runner/config
sudo 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:alpine
Подивіться логи на старт:
docker logs -f gitlab-runner
Крок 3. Реєстрація Runner у GitLab
У GitLab відкрийте ваш проєкт: Settings → CI/CD → Runners → Registration token. Потім у терміналі виконайте:
docker exec -it gitlab-runner gitlab-runner register
Відповідайте на запитання:
- Enter the GitLab instance URL: https://gitlab.com (або URL вашого self-hosted GitLab)
- Enter the registration token: Поставте ваш токен
- Description: local-docker-runner
- Tags: docker,linux,python,node
- Executor: docker
- Default Docker image: ubuntu:22.04 (або будь-який базовий образ)
За потреби можна вручну підкрутити конфіг:
# /srv/gitlab-runner/config/config.toml
concurrent = 2
[session_server]
session_timeout = 1800
[[runners]]
name = "local-docker-runner"
url = "https://gitlab.com/"
token = "REDACTED"
executor = "docker"
[runners.docker]
tls_verify = false
image = "ubuntu:22.04"
privileged = false
pull_policy = "if-not-present"
shm_size = 0
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
Примітка: якщо у job-і треба будувати Docker-образи, або запускати в Docker-in-Docker, увімкніть privileged = true для цього runner або використовуйте сервіс docker:dind (див. альтернативи нижче).
Крок 4. .gitlab-ci.yml для Python і Node.js
Приклад з окремими job-ами, кешем залежностей і артефактами тестів.
stages:
- test
- build
.default_cache: &default_cache
key: "${CI_COMMIT_REF_SLUG}"
policy: pull-push
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
PIP_DISABLE_PIP_VERSION_CHECK: "1"
NPM_CONFIG_CACHE: "$CI_PROJECT_DIR/.npm"
python:test:
stage: test
image: python:3.11-slim
cache:
<<: *default_cache
paths:
- .cache/pip/
before_script:
- python --version
- python -m pip install --upgrade pip
- |
if [ -f requirements.txt ]; then \
pip install -r requirements.txt; \
fi
script:
- |
if [ -f pytest.ini ] || [ -d tests ]; then \
pip install pytest; \
pytest --maxfail=1 --disable-warnings -q --junitxml=pytest-report.xml; \
else \
echo "No tests found"; \
fi
artifacts:
when: always
paths:
- pytest-report.xml
reports:
junit: pytest-report.xml
node:test:
stage: test
image: node:20
cache:
<<: *default_cache
paths:
- .npm/
- node_modules/
before_script:
- node -v
- npm -v
- |
if [ -f package-lock.json ]; then \
npm ci; \
elif [ -f package.json ]; then \
npm install; \
fi
script:
- |
if npm run | grep -q " test"; then \
npm test --silent || npm test; \
else \
echo "No npm test script"; \
fi
artifacts:
when: always
paths:
- coverage/
node:build:
stage: build
image: node:20
needs: ["node:test"]
cache:
<<: *default_cache
paths:
- .npm/
- node_modules/
script:
- |
if npm run | grep -q " build"; then \
npm run build; \
else \
echo "No build script"; \
fi
artifacts:
paths:
- dist/
Цей пайплайн запускає тести для Python і Node.js, кешує pip та npm, зберігає артефакти та результати тестів.
Альтернативні способи
Shell executor (без контейнерів)
Можна зареєструвати runner з executor=shell. Плюс — мінімальні накладні витрати; мінус — вам треба самостійно тримати на хості всі потрібні версії Python/Node.js. Використовуйте лише на виділених машинах.
Docker executor vs Docker-in-Docker
- Docker executor з монтуванням /var/run/docker.sock — швидкий і простий для більшості CI (тести, збірка артефактів).
- Docker-in-Docker (служба
docker:dind+privileged) — коли потрібно будувати Docker-образи всередині job-ів. Приклад фрагмента:
build:image:
stage: build
image: docker:24.0
services:
- name: docker:24.0-dind
command: ["--tls=false"]
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
script:
- docker build -t myapp:${CI_COMMIT_SHORT_SHA} .
- docker save myapp:${CI_COMMIT_SHORT_SHA} -o image.tar
artifacts:
paths:
- image.tar
Podman як альтернатива Docker
Якщо ви живете у Red Hat/Fedora-світі — розгляньте Podman. GitLab Runner підтримує його через docker-compat режим, але уважно тестуйте, бо деякі edge-кейси відрізняються.
GUI-спосіб
- У GitLab зайдіть у ваш проєкт → Settings → CI/CD → Runners → Expand. Скопіюйте Registration token (GUI-частина найважливіша тут).
- Для керування контейнерами з GUI можна використати Portainer: запустіть
portainer/portainer-ceу Docker і додавайте/перезапускайте Runner одним кліком. - Логи job-ів дивіться у вкладці Pipelines в інтерфейсі GitLab. Там же видно артефакти та звіти тестів.
FAQ
Runner зареєстровано, але job-и «pending»
Переконайтеся, що теги збігаються. Якщо у job-і зазначені теги, а у runner — інші, GitLab не віддасть завдання. Можна тимчасово прибрати теги з job-у для перевірки.
permission denied: /var/run/docker.sock
Для контейнеризованого Runner обов’язково монтуйте сокет Docker і не забороняйте доступ:
# Перезапуск з правильними volume
sudo docker rm -f gitlab-runner
sudo 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:alpine
docker:dind не стартує або не будує образ
- Додайте
privileged = trueдля runner у config.toml або використовуйтеservices: docker:dindз--tls=false. - Переконайтесь у відповідності версій образів docker: клієнт і dind повинні збігатися.
Кеш не працює/не пришвидшує збірку
- Перевірте
cache:key(реком.${CI_COMMIT_REF_SLUG}або стабільний ключ для main). - Правильно вказуйте шляхи:
.cache/pip/,.npm/,node_modules/.
Де дивитися логи Runner?
docker logs -f gitlab-runner
Також у GitLab → Pipelines → конкретний job → вкладка Log.
Порада від Kernelka
Тримайте runner «тонким»: образи для job-ів задавайте у .gitlab-ci.yml, а не як «default image» для всього runner. Так легше оновлювати середовища під конкретні пайплайни і уникати дивних конфліктів залежностей. І не соромтеся додавати маленькі smoke-тести — швидкі перевірки ловлять великі проблеми 😉
Підсумок
- Підняли GitLab Runner у Docker на Linux і зареєстрували його в GitLab
- Налаштували CI для python в Linux і nodejs в Linux із кешем та артефактами
- Розібрали альтернативи: shell executor, Docker-in-Docker, Podman
- Отримали відповіді на типові помилки та чекліст стабільності

Прокоментувати
На сайті відображається лише твоє ім'я та коментар. Електронна пошта зберігається виключно для зв'язку з тобою за потреби та в жодному разі не передається стороннім особам.