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 как демона :devil: , используя примерно такую команду, и дело сделано :-)

/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

Оставить комментарий

Оповещать о новых комментариях по RSS