Хостинг mercurial репозиториев с помощью nginx, gunicorn и supervisor
Способов хостинга mercurial репозиториев достаточно, но я сочинил именно такой вариант по следующим причинам:- nginx: мало кушает, быстро работает — скорость
- supervisor: мониторит процесс, перезапускает если что — надёжность
- gunicorn: wsgi, большие возможности по настройке — эффективность
Если вас заинтересовала тема, то конкретные инструкции и конфиги — под катом.
Далее подразумевается, что у вас уже установлены mercurial, nginx, gunicorn и supervisor. Я использую Ubuntu 10.04, для неё mercurial, nginx и supervisor имеются в стандартных репозиториях, а для gunicorn имеется ppa.
В качестве основного скрипта для работы с репозиториями используется hgweb, поставляемый в составе mercurial, от него и танцуем.
Репозитории я храню в каталоге /home/hgdata. Причина — упрощение настройки бекапов. Сохраняется весь /home, и не надо указывать отдельные каталоги, например. Все описываемые скрипты и конфиги хранятся в этом же каталоге, /home/hgdata.
Первый файл — hgweb.config, конфиг самого hgweb, как следует из названия:
Copy Source | Copy HTML
[collections]
/ = /home/hgdata
он говорит hgweb о том, что репозитории хранятся в /home/hgdata, и надо их искать там.Далее, т.к. мы поднимаем wsgi сервер, то меркуриаловский скрипт hgweb надо преобразовать в wsgi. Для этого используется скрипт hgwebapp.py:
Copy Source | Copy HTML
#!/usr/bin/env python
import os
import sys
from mercurial.hgweb.hgwebdir_mod import hgwebdir
from mercurial.hgweb.request import wsgiapplication
os.environ["HGENCODING"] = "UTF-8"
def make_web_app():
return hgwebdir("/home/hgdata/hgweb.config")
def application(environ, start_response):
environ['wsgi.url_scheme'] = environ.get('HTTP_X_URL_SCHEME', 'http')
# nginx wrap proxy headers with HTTP
environ['REMOTE_USER'] = environ.get('HTTP_REMOTE_USER', '')
app = wsgiapplication(make_web_app)
return app(environ, start_response)
Этот скрипт мы уже можем стартануть под gunicorn. Конфиг для gunicorn называется hgweb.conf:Copy Source | Copy HTML
[program:hgweb]
command=/usr/bin/gunicorn -b 127.0.0.1:8080 hgwebapp:application
environment=PYTHONPATH='/home/hgdata'
directory=/home/hgdata
user=www-data
autostart=true
autorestart=true
startsecs=10
redirect_stderr=true
stdout_logfile=/var/log/supervisor/hgweb.gunicorn.log
симлинк на этот конфиг кладём в /etc/supervisor/conf.d и уже можно его запускать. Заходим в «панель управления» supervisor: sudo supervisorctl и даём команду update. supervisor пересмотрит каталог конфигов, найдёт новый и запустит gunicorn-сервер со скриптом hgwebapp. После этого на порту 8080 адреса 127.0.0.1 будет висеть сервер mercurial, и остаётся его выставить наружу посредством nginx.В файл конфига nginx я прописал всё это дело на домен третьего уровня, и у меня он называется так: hg.somewebsite.com
Copy Source | Copy HTML
upstream app_server_hgweb {
server 127.0.0.1:8080 fail_timeout=0;
}
server {
listen X.X.X.X:80;
server_name hg.somewebsite.com;
location / {
auth_basic "Mercurial repository";
auth_basic_user_file /home/hgdata/auth;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header remote_addr $remote_addr;
proxy_set_header remote_user $remote_user;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass app_server_hgweb;
break;
}
}
}
Как видно из конфига, для аутентификации юзеров используется файл /home/hgdata/auth, в нём обычные пары юзер-хеш пароля. Имя юзера передаётся вниз на wsgi сервер, и используется hgweb для того, чтобы определить, какой доступ давать юзеру. Это настраивается в файле hgrc (который лежит в подкаталоге .hg репозитория), в секции web. Прописывается очень просто:
Copy Source | Copy HTML
[web]
contact = Organization name
description = Repository description
style = gitweb
allow_read = user1 user2 user3
allow_push = user1
push_ssl = false
allow_archive = bz2 gz zip
В данном случае заливать в репозиторий может только user1, а читать могут трое. От анонимусов данный репозиторий закрыт. Подробнее по настройкам доступа тут.В заключение нужно создать симлинк с файла /home/hgdata/hg.somewebsite.com в каталог /etc/nginx/sites-enabled и рестартнуть nginx, после этого всё должно работать. Необходимо учесть, что т.к. юзером в конфиге nginx прописан www-data, то www-data должен иметь все права на репозитории в /home/hgdata, иначе он не сможет туда писать.
Вот и всё, репозитории должны быть доступны по http. Надеюсь, данная статья будет полезна в вашей работе. Буду рад услышать замечания и предложения.



комментарии (17)