В итоге мы получим домашний сервер с фейковым доменом, на поддомене которого мы развернём GitLab и настроим работу gitlab-runner'а для деплоя наших веб-проектов.
Я не буду долго разглагольствовать по поводу каждого шага, лишь в крайних случаях буду описывать моменты, с которыми вы можете столкнуться в процессе и пути их решения.
Установка
В качестве основной системы используется Ubuntu Server.
DNSMasq & NGINX
Ставим DNSMasq и NGINX.
sudo apt update
sudo apt install nginx, dnsmasq, dnsutils
Узнаём название нашего контроллера с помощью команды (тут - enp1s0):
ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether d8:9e:f3:92:aa:a8 brd ff:ff:ff:ff:ff:ff
inet 10.13.9.242/24 metric 100 brd 10.13.9.255 scope global dynamic enp1s0
valid_lft 45713sec preferred_lft 45713sec
inet6 fe80::da9e:f3ff:fe92:aaa8/64 scope link
valid_lft forever preferred_lft forever
Настраиваем конфиг DNSMasq `/etc/dnsmasq.d/<имя_нашего_конфига>`. В качестве имени, можно использовать название нашего главного домена, чтобы было удобнее.
Открываем файл и исправляем наш конфиг по образу и подобию:
no-dhcp-interface=<controller> # Не перенастраиваем DHCP, а слушаем наш контроллер
bogus-priv # Запретить пересылать адреса в немаршрутизированные адресные пространства
domain=<domain> # Название домена
expand-hosts # Включаем поддомены
local=/<domain>/ # Локальное название домена
domain-needed # Использовать только полное доменное имя (FQDN)
address=/<domain>/<local_ip> # Запуск функции кеширования для ip-адресов локальных интерфейсов. Если этой опции нет, то для всех
no-resolv # Запрет в чтении файла /etc/resolv.conf или др.файла выполняющего его функцию.
no-poll # Тоже, что и no-resolv
no-hosts # Не использовать файл /etc/hosts для формирования таблицы адресов
# Отдельно стоит поговорить про эти строки,
# тк если ваша рабочая машина использует VPN,
# то у вас могут возникнуть небольшие сложности с подключением.
# Всё решается дополнительной настройкой DNS в вашем VPN-клиенте
server=8.8.8.8 # DNS-сервера для домена
server=8.8.4.4 # DNS-сервера для домена
Перезагружаем DNSMasq service:
sudo systemctl restart dnsmasq.service
Теперь вам нужно настроить использование нашего локального DNS на вашем компьютере. Я покажу, как это сделать для Debian 11.
Достаточно изменить два файла: `/etc/resolv.conf` и `/etc/NetworkManager/NetworkManager.conf`.
sudo nano /etc/resolv.conf
...
# Ваш локальный DNS должен идти самым первым в списке
nameserver <local_dns_ip>
nameserver 127.0.0.1
...
sudo nano /etc/NetworkManager/NetworkManager.conf
...
[main]
dns=none
...
Теперь настроим NGINX, чтобы он принимал наш новый домен. Для этого достаточно создать новый файл конфигурации в папке `/etc/nginx/sites-available`, проверить его, переместить в `/etc/nginx/sites-enabled` и перезапустить NGINX. Приступим!
Создаём новый файл конфигурации `<ваш_домен>.conf`. Да, весьма простая конфигурация, но нам больше и не нужно.
server {
listen 80;
listen [::]:80;
server_name <ваш_домен> www.<ваш_домен>;
}
Проверяем корректность файла:
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Переносим файл.
чтож...
mv /etc/nginx/sites-available/<ваш_домен>.conf /etc/nginx/sites-enabled/
Перезапускаем NGINX:
sudo systemctl reload nginx
Теперь, если вы перейдёте в своём браузере по адресу http://<ваш_домен>, вы увидите стартовую страницу NGINX.
GitLab
Добавляем репозиторий в систему:
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
Устанавливаем GitLab:
sudo apt install gitlab-ee
Настраиваем базовую конфигурацию `/`:
external_url 'example.domain' -> external_url 'http://gitlab.<ваш_домен>'
web_server['external_users'] = [] -> web_server['external_users'] = ['www-data']
nginx['enable'] = true -> nginx['enable'] = false
Скачиваем файл конфигурации GitLab для NGINX. Помещаем его в папку `/etc/nginx/sites-enabled`. В этом файле нужно поправить только строки:
listen 0.0.0.0:80 default_server; -> listen 0.0.0.0:7001;
listen [::]:80 default_server; -> listen [::]:7001;
server_name YOURSERVER_FQDN -> server_name www.<ваш_домен> <ваш_домен>;
Добавляем самые простые строки в базовый конфиг NGINX. (можно и не в него, а в отдельный файл в `/etc/nginx/sites-enabled`).
server {
listen 80;
client_max_body_size 50m;
server_name gitlab.<ваш_домен> www.gitlab.<ваш_домен>;
location / {
proxy_pass http://127.0.0.1:7001;
}
}
Реконфигурируем GitLab:
sudo gitlab-ctl reconfigure
Обновляем NGINX:
sudo systemctl reload nginx
Находим первичный root-пароль в файле `/etc/gitlab/initial_root_password`.
Заходим на нашу страницу, вводим логин root и пароль, который мы нашли до этого, и настраиваем аккаунт администратора.
GitLab Runner
Для начала нам нужно установить Runner. Добавляем репозиторий.
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
Устанавливаем пакет.
sudo apt install gitlab-runner
Теперь получаем регистрационный токен для нашего runner'а. Заходим в админ-панель GitLab через аккаунт администратора в раздел Overview -> Runners и нажимаем Register an instance runner. Копируем токен.
Начинаем процесс регистрации runner'а. Вводим команду:
sudo gitlab-runner register
Вводим url-адрес нашего gitlab'a.
Вводим наш токен.
Вводим краткое описание.
Вводим тэги. Тут я советую создать два runner'a с разными тэгами: один с тэгом shell, который будет выполнять все операции, связанные с терминальными командами, и второй с тэгом docker, который будет отвечать за наши docker-контейнеры. Остальные тэги можно посмотреть в официальной документации.
Проверить наш runner можно на той же странице в админ-панели.
Теперь, чтобы runner мог участвовать в развёртывании веб-проектов на NGINX сервер, нужно сделать лишь пару штрихов: дать ему права на вызов NGINX под sudo и выдать доступ к папкам `sites-available` и `sites-enabled`.
Права выдаются путём создания дополнительного файла в папке `/etc/sudoers.d`, в ней создадим файл `gitlabrunner` и впишем такую строчку:
%gitlab-runner ALL=(ALL:ALL) NOPASSWD: /usr/sbin/nginx
Выдача прав вызова NGINX под sudo нужна, чтобы делать проверку конфигурации файлов при деплое. Вызов `nginx -t` возможен, но он будет заканчиваться всегда с ошибкой.
Далее прописываем команду, чтобы runner имел возможность взаимодействовать с файлами в папках NGINX:
sudo chown root:gitlab-runner -R /etc/nginx/sites-available /etc/nginx/sites-enabled
Вот и всё. Теперь у нас есть полноценная локальная среда разработки.
Вместо заключения скажу лишь, что здесь я попытался описать то, что сделал я, чтобы поднять подобное окружение для своей небольшой команды в закрытой сети для разработки. Текущее решение функционирует уже целый месяц без нареканий и проблем (за исключением GitLab wiki, но как только я решу эту проблему, обязательно дополню статью).
Для тех, кому интересно, что там с GitLab wiki
Не показываются статьи обычным пользователям. Проект виден, на статью отдельно по урлу тоже можно зайти, однако при переходе в раздел wiki из сайдбара показывается только экран добавления новой статьи.
UPD: Оказывается, чтобы GitLab wiki проекта работала корректно, всегда должна присутствовать home страница (а мы начали с красивых заголовков)...
Дополнительно могу сделать небольшую статью, как вся эта система работает на примере небольшого проекта на Django, где в качестве WSGI будет использоваться Gunicorn.
Комментарии (12)
AndrewStephanoff
24.11.2022 21:45Так, на всякий случай, современные браузеры резолвят домены *.localhost на 127.0.0.1, использую эту возможность+docker
nickwaze
25.11.2022 11:17+1"Дополнительно могу сделать небольшую статью, как вся эта система работает на примере небольшого проекта на Django, где в качестве WSGI будет использоваться Gunicorn."
моги
werter_l
27.11.2022 12:21sudo nginx -t && sudo nginx -s reload
/etc/nginx/sites-enabled не пользую - пользую /etc/nginx//conf.d/
baldr
А зачем dnsmasq если можно в /etc/hosts прописать домен?
Здесь нужен симлинк.
eijawa Автор
По поводу symlink: проблема в том, что если был отправлен неправильный конфиг, то NGINX не перезапустится или не запустится (в зависимости от его текущего состояния). В связи с этим, если сделать symlink, то будет всего два варианта развития событий (о деталях можно прочитать в официальной документации):
1. NGINX уже был запущен. В таком случае, если тест провалится, то с сервером ничего не случится (поскольку на команду перезапуска он ответит ошибкой) и он продолжит работать на старом конфиге.
2. NGINX не был запущен. В таком случае, он просто не запустится.
Поэтому, это дело вкуса, но я хотел бы оставить за собой возможность безболезненного перезапуска.
DNSMasq нужен, чтобы можно было после автоматически создавать тестовые стенды на основе конфигов и не прописывать каждый раз новые домены на каждом клиенте. Для этого нужно будет лишь добавить адрес нашего сервера в качестве дополнительного DNS на нашем компьютере (у нас это сделано путём модификации resolv.conf и отключением автоматической генерации конфига NetworkManager'ом).
baldr
Насколько я знаю, папка sites-available сделана исключительно для удобства пользователя и nginx ничего о ней не знает. В ней держат все конфиги, чтобы они были поближе к nginx.
Папка sites-enabled используется внутри nginx.conf: "include /etc/nginx/sites-enabled/*;", поэтому при "nginx -t" он ее и проверяет. Смысл в симлинке - быстрое включение-выключение конфига.
Про dnsmasq понятно - решение лучше hosts, конечно же. Еще очень бы советовал использовать TLS-сертификаты, хоть бы и самоподписанные - на продакшене у вас все равно с https все работает же? А многие сторонние сервисы типа google auth не разрешают даже редирект на http.
kpmy
Если говорить про https.
Недавно писали про вот этот проектик https://github.com/Upinel/localhost.direct
Кажется, идея неплохая.
dinisoft
Перед перезапуском nginx нужно проверять конфиги!
И по результату уже рестартить.
baldr
Именно это и делается в статье, но автор ошибочно считает что файл в sites-available проверяется, хотя по-умолчанию это не так.
mayorovp
Так ведь если вы сделаете
mv
, то случится ровно то же самое. В чём вы видите именно дополнительные проблемы ссылок, которых не происходит при использовании вашего подхода?