GitLab + uWSGI + Nginx на FreeBSD
В онлайне есть достаточно информации об установке GitLab на FreeBSD.
Данный пост содержит только часть по настройке uWSGI и Nginx.
Сначала нужно скомпилировать uWSGI с поддержкой Ruby.
Будет быстрее использовать версию из портов:
cd /usr/ports/www/uwsgi make extract cd work/uwsgi-2.x.y.z # Создадим конфиг для одновременного запуска приложений Python и Ruby через uWSGI printf "[uwsgi]\nmain_plugin = python,gevent,rack,rbthreads,fiber\ninherit = base" > buildconf/rackp.ini python uwsgiconfig.py --build rackp # ...или только Ruby python uwsgiconfig.py --build ruby2 # Проверим, что бинарник действительно содержит нужные плагины Python и/или Ruby ./uwsgi --plugins-list cd ../.. make install
Добавление строк конфигурации в /etc/rc.conf:
uwsgi_enable="YES" uwsgi_uid="root" uwsgi_gid="wheel" uwsgi_flags="--processes=0 --die-on-term --emperor-procname \"[uWSGI] Emperor\" --procname-master \"[uWSGI] Root\" --enable-threads --reload-mercy 10 --emperor /usr/local/etc/uwsgi --emperor-pidfile /var/run/uwsgi_emperor.pid --emperor-stats /tmp/uwsgistats.sock --emperor-freq 60 --binary-path /usr/local/bin/uwsgi --disable-logging --daemonize /var/log/uwsgi.log --log-truncate --log-maxsize 5242880 --log-backupname /var/log/uwsgi.log.old"
Данная командная строка позволит uWSGI работать в режиме Emperor с рут правами и запускать вассалов с нужными uids/gids, которые будут состоять из Master процесса и нескольких Worker процессов, если это необходимо.
Изменив пути и названия можно перейти к созданию конфига для вассала по выбранному пути (или рассматривать это как пример, если Вы используете uWSGI в других режимах).
[uwsgi] strict = true plugin = rack uid = git gid = git master = true auto-procname = true memory-report = false processes = 2 enable-threads = true rbthreads = true threads = 3 offload-threads = 3 socket = /home/git/gitlab/tmp/sockets/gitlab.socket chdir = /home/git/gitlab/ post-buffering = 4096 env = RAILS_ENV=production # В системе должен быть установлен Node.js env = EXECJS_RUNTIME=Node rack = /home/git/gitlab/config.ru rbrequire = rubygems rbrequire = bundler/setup ruby-gc-freq = 1 disable-logging = true harakiri = 60 procname = [uWSGI] Vassal GitLab worker procname-master = [uWSGI] Vassal GitLab master
Последним шагом будет настройка корректного перенаправления Nginx-ом запросов к uWSGI и gitlab-workhorse.
Unicorn может стать 4-ым HTTP сервером, если Вы, как и я, уже используете Apache, Nginx и GitLab-Workhorse. Не слишком ли это много? Я решил, что да, поэтому избавился от Unicorn и стал использовать Nginx вместо него. Осталась лишь одна проблема — gitlab-workhorse требуется backend для авторизации, но для этого нельзя использовать уже имеющийся сервер Nginx, т.к. запросы идут по тем же адресам, а значит в итоге получится бесконечная петля. В качестве решения можно создать отдельный виртуальный хост и повесить его на другой порт, все запросы к нему будут проксироваться в uWSGI.
Прежде всего нужно подготовить Nginx, скопировав uwsgi_params-dist в uwsgi_params, затем создать хосты, похожие на эти:
upstream gitlab-workhorse { server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0; } limit_req_zone $binary_remote_addr zone=cibuild:1m rate=2r/m; server { listen 255.255.255.255:80; server_name domain.com; access_log ...; error_log ...; root /home/git/gitlab/public; client_max_body_size 128m; # Редирект всех запросов в gitlab-workhorse location / { # Публичные проекты на главной странице вместо логина rewrite ^/$ /public; try_files $uri @gitlab-workhorse; } # Хак для ограничения запросов от gitlab-ci-multi-runner, # не позволяет засирать production и Nginx логи location ~ ^/ci/api/v1/builds/register\.json$ { access_log /dev/null; limit_req_status 404; # 404 = нет билдов в очереди limit_req zone=cibuild nodelay; log_not_found off; try_files - @gitlab-workhorse; } # Статика location ~ ^/assets/ { gzip_static on; expires max; add_header Cache-Control public; } # Проксирование к GitLab Workhorse location @gitlab-workhorse { gzip off; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_redirect off; proxy_buffering off; proxy_request_buffering off; proxy_http_version 1.1; 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-Proto $scheme; proxy_set_header X-Frame-Options SAMEORIGIN; proxy_pass http://gitlab-workhorse; } } # Бэкенд для GitLab Workhorse server { listen 255.255.255.255:8090; server_name domain.com; root /home/git/gitlab/public; client_max_body_size 128m; location / { gzip off; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_redirect off; proxy_buffering off; proxy_request_buffering off; proxy_http_version 1.1; 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-Proto $scheme; proxy_set_header X-Frame-Options SAMEORIGIN; include uwsgi_params; uwsgi_modifier1 7; uwsgi_pass unix:/home/git/gitlab/tmp/sockets/gitlab.socket; } }
Осталось запустить gitlab-workhorse как демона , используя примерно такую команду, и дело сделано
/usr/bin/su - git -c "/usr/bin/nohup /home/git/gitlab-workhorse/gitlab-workhorse -listenNetwork unix -listenAddr /home/git/gitlab/tmp/sockets/gitlab-workhorse.socket -authBackend http://domain.com:8090 -listenUmask 000 -documentRoot /home/git/gitlab/public >/home/git/gitlab/log/gitlab-workhorse.log 2>&1 &" >/dev/null 2>&1