Стабильно
Запуск GitLab Runner с исполнителем Docker
Как запустить GitLab Runner с исполнителем Docker для GitLab на собственном сервере, отделить служебный трафик CI от браузерного доступа и устранить ошибки реестра пакетов.
Шаги
Выполняйте по порядку.
- 01Разделить браузерный и служебный трафик CIНаправляйте браузерный доступ пользователей через BusinessProxy, а для GitLab Runner и контейнеров заданий используйте закрытый служебный маршрут.
- 02Запустить и зарегистрировать GitLab RunnerХраните конфигурацию вне контейнера, закрепите версию образа, используйте отдельную сеть Docker и вводите токен только по запросу команды регистрации.
- 03Организовать внутренний HTTPSПринимайте HTTPS-соединения на внутреннем TLS-прокси и передавайте запросы в HTTP-сервис GitLab, не открывая дополнительный порт сервера.
- 04Переключить без прерывания заданийСначала проверьте TLS-прокси, перенесите основной сетевой псевдоним, обновите все записи GitLab Runner и сохраните копию для отката.
- 05Проверить и диагностировать публикациюОтличайте ошибки DNS и TLS от ошибок авторизации GitLab, затем проверьте настройку с помощью реального задания для реестра пакетов.
Справочник
Детали реализации для настройки и проверки.
- Параметр external_url остаётся основным HTTPS-адресом GitLab, например https://gitlab.example.com.
- Контейнер GitLab может продолжать принимать соединения на HTTP-порту 80 внутри закрытой сети Docker.
- Получение заданий GitLab Runner, клонирование репозиториев и обращения к реестру пакетов проходят по закрытому внутреннему HTTPS-маршруту и не зависят от многофакторной проверки в браузере или сессии App Gateway.
Браузер -> BusinessProxy App Gateway -> GitLab HTTP :80
Runner/задание -> внутренний TLS-прокси :443 -> GitLab HTTP :80- Внутри сети Docker имя gitlab.example.com назначено только TLS-прокси.
- GitLab сохраняет отдельный служебный псевдоним, например gitlab, чтобы TLS-прокси обращался к http://gitlab:80.
- Не публикуйте TLS-прокси через параметры -p или ports: это внутренний адрес для CI, а не ещё одна публичная точка входа GitLab.
docker network create gitlab-internal
docker network connect --alias gitlab gitlab-internal gitlab
docker run -d --name gitlab-runner \
--restart unless-stopped \
--network gitlab-internal \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:alpine-v<проверенная-версия>- Подключение сокета Docker даёт GitLab Runner полный контроль над узлом Docker. Используйте выделенный сервер, назначайте GitLab Runner только доверенным проектам и разрешайте ему выполнять задания только для защищённых веток и тегов.
- Задайте политику перезапуска и следите за свободным местом: образы контейнеров и кэш сборок накапливаются на сервере.
- Не выполняйте docker network create или docker network connect, если сеть или подключение уже существуют. Сначала проверьте текущие сетевые псевдонимы и сохраните те, которые не относятся к этой настройке.
events {}
http {
upstream gitlab_backend { server gitlab:80; }
server {
listen 443 ssl;
server_name gitlab.example.com;
ssl_certificate /certs/fullchain.pem;
ssl_certificate_key /certs/privkey.pem;
client_max_body_size 0;
location / {
proxy_pass http://gitlab_backend;
proxy_http_version 1.1;
proxy_set_header Host gitlab.example.com;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
}- Заголовки Authorization, JOB-TOKEN и DEPLOY-TOKEN должны доходить до GitLab без изменений. Не переопределяйте их в конфигурации TLS-прокси.
- После обновления сертификата проверяйте конфигурацию nginx перед его перезагрузкой. Не используйте просроченный сертификат или сертификат для другого имени.
docker run -d --name gitlab-internal-tls \
--restart unless-stopped \
--network gitlab-internal \
--network-alias gitlab-internal-tls \
-v /srv/gitlab-internal-tls/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /secure/certs/gitlab.example.com:/certs:ro \
nginx:1.27-alpine- Не добавляйте -p 443:443. GitLab Runner и контейнеры заданий подключаются к TLS-прокси по сети gitlab-internal.
- После продления сертификата автоматически проверяйте конфигурацию командой nginx -t и перезагружайте nginx командой nginx -s reload. Заранее предупреждайте администратора об окончании срока действия сертификата.
curl --resolve gitlab.example.com:443:<sidecar-ip> \
https://gitlab.example.com/users/sign_in
docker network inspect gitlab-internal- Не добавляйте -k к предварительной проверке: тест должен проверить имя и доверие к сертификату.
- После переноса псевдонима перезапустите TLS-прокси, чтобы он заново определил адрес GitLab с учётом итоговой конфигурации сети.
- Ожидаемые ответы GitLab: страница HTML с кодом 200, обычное перенаправление или код 401 для защищённого адреса API, но не страница ошибки BusinessProxy.
docker exec -it gitlab-runner gitlab-runner register \
--url https://gitlab.example.com \
--executor docker \
--docker-image node:22-alpine \
--description private-docker-runner- Вводите токен аутентификации только по запросу команды регистрации и ограничьте права доступа к полученному файлу config.toml.
- Не выводите токен аутентификации или полный файл config.toml в журналы CI и обращения в поддержку.
[[runners]]
url = "https://gitlab.example.com"
clone_url = "https://gitlab.example.com"
executor = "docker"
[runners.docker]
image = "node:22-alpine"
network_mode = "gitlab-internal"- В рабочей конфигурации также есть токен аутентификации GitLab Runner; в примере он намеренно не показан.
- Обновите все записи в config.toml. Даже одна устаревшая запись может продолжить получать задания или клонировать репозитории по неправильному маршруту.
docker exec gitlab-runner getent hosts gitlab.example.com
docker exec gitlab-runner gitlab-runner verify
docker run --rm --network gitlab-internal curlimages/curl:<проверенная-версия> \
-I https://gitlab.example.com/users/sign_in- Внутри сети gitlab-internal имя должно указывать только на адрес TLS-прокси.
- Запустите тестовый конвейер CI, который клонирует репозиторий и публикует или скачивает пакет. Считайте настройку подтверждённой только после успешного завершения задания.
- Проверьте сетевые псевдонимы каждого контейнера в gitlab-internal и удалите основной псевдоним у контейнера GitLab, принимающего только HTTP.
- Назначьте основной псевдоним TLS-прокси и перезапустите GitLab Runner после изменения config.toml.
- Не меняйте external_url на HTTP и не отключайте проверку сертификата, чтобы скрыть ошибку маршрутизации.
- Ошибка x509 или несовпадение имени узла: исправьте имена в поле SAN сертификата, цепочку доверия или файл сертификата, подключённый к контейнеру; не отключайте проверку TLS.
- 401 Unauthorized: DNS и TLS работают; проверьте CI_JOB_TOKEN, токен развёртывания, права проекта и политику реестра пакетов.
- 404 Not Found: проверьте идентификатор проекта, путь пакета, используемый адрес API и включён ли реестр пакетов для проекта.
- POST /api/v4/jobs/request возвращает 204: GitLab Runner работает, но в GitLab нет подходящего задания, ожидающего выполнения.
- GitLab Runner получает задание, но клонирование или npm publish завершается ошибкой: убедитесь, что к сети gitlab-internal подключены также вспомогательные контейнеры и контейнеры заданий, а не только контейнер GitLab Runner.
- Оставляйте TLS-прокси доступным только внутри сети, подключайте файлы ключей только для чтения и перезагружайте конфигурацию только после успешного выполнения nginx -t.
- Подключайте GitLab Runner только к доверенным проектам, защищайте задания публикации и заменяйте токен аутентификации GitLab Runner при подозрении на его раскрытие.
- Следите за сроком действия сертификата, ошибками получения заданий, сбоями при публикации и загрузке пакетов, а также за свободным местом на диске сервера.
- Сохраняйте резервный способ административного доступа и заранее проверенную копию предыдущей конфигурации GitLab Runner.