долгое время у меня не получалось корректно настроить одновременную работу Gitlab и встроенный Container Registry. Сложность состояла в том, что все это хозяйство работало за внешним nginx reverse proxy с настроенным https. С прокси же запросы на сам gitlab шли по http и на сервере сертификатов не было вовсе. Это важно, так как не хотелось одновременно настраивать и обновлять сертификаты на nginx proxy и gitlab.
Просто настроить gitlab за nginx в режиме proxy_pass не представляет никакой сложности. Трудности возникают именно тогда, когда вы хотите использовать встроенный Container Registry.
С registry не получалось корректно настроить работу за прокси.
Команда docker login успешно отрабатывала на сервере, а вот запушить образ в реджистри gitlab никак не получалось. Получал ошибку.
1 |
Error: Status 404 trying to push repository zeroxzed/website |
Проблему я в итоге решил, когда залез во внутренности gitlab
Gitlab и proxy nginx
Если у вас используется только сам gitlab, без встроенного registry, то никаких особых настроек делать не надо. Достаточно выполнить обычную установку gitlab. В качестве EXTERNAL_URL во время установки можно указать адрес с http. Затем, после установки, настраивайте proxy nginx примерно вот так.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
server { listen 443 http2 ssl; server_name gl.test.ru; access_log /var/log/nginx/gl.test.ru-access.log full; error_log /var/log/nginx/gl.test.ru-error.log; ssl_certificate /etc/letsencrypt/live/gl.test.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/gl.test.ru/privkey.pem; limit_conn perip 50; location /.well-known { root /tmp; } location / { proxy_pass http://10.20.50.8:80; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_redirect off; proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Ssl on; } } server { listen 80; server_name gl.test.ru; return 301 https://gl.test.ru$request_uri; } |
На самом сервере с gitlab в /etc/gitlab/gitlab.rb измените параметры.
1 2 3 |
external_url 'https://gl.test.ru' nginx['listen_port'] = 80 nginx['listen_https'] = false |
И после этого дайте команду на переконфигурацию системы.
1 |
gitlab-ctl reconfigure |
После этого gitlab будет нормально работать за nginx proxy. Дальше рассказываю, что надо сделать, чтобы включить и нормально запустить в работу Container Registry за reverse proxy.
Настройка Gitlab registry за reverse nginx proxy
На первый взгляд никаких особенных сложностей быть не должно. Делаем по аналогии настройки, только для registry_nginx и пробуем работать с registry. Но ничего не получится. Будет приведенная выше ошибка. Я покопался в настройках gitlab и понял, в чем проблема.
Если у вас используется одинаковый url для web интерфейса gitlab и registry, то корректная работа за nginx proxу невозможна. Я посмотрел конфигурацию nginx, входящего в состав gitlab. Она живет тут — /var/opt/gitlab/nginx/conf. Там отдельный конфиг для web интерфейса и для registry. Если используются одинаковые доменные имена, то все запросы попадают на конфигурацию веб интерфейса и проксируются на gitlab-workhorse.
Это происходит, потому что директива server_name в обоих конфигах одинаковая. Обрабатывается первым то, что стоит раньше в конфигурации. Я заподозрил это еще раньше, когда 404 ошибки обращений к registry обнаруживал в лог файлах /var/log/gitlab/nginx/gitlab_access.log, тогда как gitlab_registry_access.log были пустые.
Сбивало с толку то, что авторизация docker login при этом отрабатывала корректно, а ошибка возникала только во время push. Судя по всему, процесс авторизации один и тот же, что для registry, что для http доступа. В общем, чтобы все корректно работало, вам нужно разделить на разные домены gitlab и registry.
Я сделал для registry отдельный домен. Настроил для него проксирование, примерно так.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
server { listen 443 http2 ssl; server_name rg.test.ru; access_log /var/log/nginx/rg.test.ru-access.log full; error_log /var/log/nginx/rg.test.ru-error.log; ssl_certificate /etc/letsencrypt/live/rg.test.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/rg.test.ru/privkey.pem; limit_conn perip 50; location /.well-known { root /tmp; } location / { proxy_pass http://10.20.50.8:80; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_redirect off; proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Ssl on; proxy_set_header X-Frame-Options SAMEORIGIN; proxy_cache off; proxy_buffering off; proxy_request_buffering off; proxy_http_version 1.1; } } server { listen 80; server_name rg.test.ru; return 301 https://rg.test.ru$request_uri; } |
Дальше в gitalb.rb добавил параметры, отвечающие за работу registry.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
registry_external_url 'https://rg.test.ru' gitlab_rails['registry_enabled'] = true registry['enable'] = true registry_nginx['enable'] = true registry_nginx['proxy_set_headers'] = { "Host" => "$http_host", "X-Real-IP" => "$remote_addr", "X-Forwarded-For" => "$proxy_add_x_forwarded_for", "X-Forwarded-Proto" => "https", "X-Forwarded-Ssl" => "on" } registry_nginx['listen_port'] = 80 registry_nginx['listen_https'] = false |
Я не уверен, что нужны все эти параметры. Привожу пример с реально работающего сервера и чтобы случайно чего-то не забыть, привожу сразу все, что на нем сейчас активно из настроек. Думаю, заголовки указывать не обязательно. Без них тоже заработает.
После этого перечитывайте конфигурацию gitlab и nginx и проверяйте работу.
Проверка работы gitlab registry
Теперь проверим работу Gitlab Container Registry. Для этого создаем любой проект через web интерфейс. Идем в раздел Packages -> Container Registry. Там увидите краткую инструкцию по работе с реджистри.
Идем на сервер, где будем собирать образы docker. Настраиваем подключение к registry, указав логин с паролем.
1 2 3 4 |
docker login rg.test.ru Username: zeroxzed Password: Login Succeeded |
Создадим тестовый докер образ из Dockerfile.
1 2 |
FROM busybox RUN echo "Test OK" |
Собираем образ и загружаем его в registry.
1 2 |
# docker image build -t rg.serveradmin.ru/zeroxzed/myapp:latest . # docker push rg.test.ru/zeroxzed/myapp:latest |
Указанный образ будет загружен в Registry данного проекта.