Как стать автором
Обновить

Хостинг mercurial репозиториев с помощью nginx, gunicorn и supervisor

Системы управления версиями
imageСпособов хостинга mercurial репозиториев достаточно, но я сочинил именно такой вариант по следующим причинам:
  1. nginx: мало кушает, быстро работает — скорость
  2. supervisor: мониторит процесс, перезапускает если что — надёжность
  3. gunicorn: wsgi, большие возможности по настройке — эффективность
Кроме того, т.к. я разрабатываю на django, и сайты запускаю под этой же связкой, есть и четвёртая причина — унификация, а она очень полезная вещь.

Если вас заинтересовала тема, то конкретные инструкции и конфиги — под катом.

Далее подразумевается, что у вас уже установлены 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<br/>[collections]<br/>/ = /home/hgdata <br/>
он говорит hgweb о том, что репозитории хранятся в /home/hgdata, и надо их искать там.

Далее, т.к. мы поднимаем wsgi сервер, то меркуриаловский скрипт hgweb надо преобразовать в wsgi. Для этого используется скрипт hgwebapp.py:
Copy Source | Copy HTML<br/>#!/usr/bin/env python<br/>import os<br/>import sys<br/>from mercurial.hgweb.hgwebdir_mod import hgwebdir<br/>from mercurial.hgweb.request import wsgiapplication<br/>os.environ["HGENCODING"] = "UTF-8"<br/>def make_web_app():<br/> return hgwebdir("/home/hgdata/hgweb.config")<br/>def application(environ, start_response):<br/> environ['wsgi.url_scheme'] = environ.get('HTTP_X_URL_SCHEME', 'http')<br/> # nginx wrap proxy headers with HTTP<br/> environ['REMOTE_USER'] = environ.get('HTTP_REMOTE_USER', '')<br/> app = wsgiapplication(make_web_app)<br/> return app(environ, start_response) <br/>
Этот скрипт мы уже можем стартануть под gunicorn. Конфиг для gunicorn называется hgweb.conf:
Copy Source | Copy HTML<br/>[program:hgweb]<br/>command=/usr/bin/gunicorn -b 127.0.0.1:8080 hgwebapp:application<br/>environment=PYTHONPATH='/home/hgdata'<br/>directory=/home/hgdata<br/>user=www-data<br/>autostart=true<br/>autorestart=true<br/>startsecs=10<br/>redirect_stderr=true<br/>stdout_logfile=/var/log/supervisor/hgweb.gunicorn.log<br/>
симлинк на этот конфиг кладём в /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<br/>upstream app_server_hgweb {<br/> server 127.0.0.1:8080 fail_timeout=0;<br/>}<br/>server {<br/> listen X.X.X.X:80;<br/> server_name hg.somewebsite.com;<br/> location / {<br/> auth_basic "Mercurial repository";<br/> auth_basic_user_file /home/hgdata/auth;<br/> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;<br/> proxy_set_header Host $http_host;<br/> proxy_set_header remote_addr $remote_addr;<br/> proxy_set_header remote_user $remote_user;<br/> proxy_redirect off;<br/> if (!-f $request_filename) {<br/> proxy_pass app_server_hgweb;<br/> break;<br/> }<br/> }<br/>}<br/>
Как видно из конфига, для аутентификации юзеров используется файл /home/hgdata/auth, в нём обычные пары юзер-хеш пароля. Имя юзера передаётся вниз на wsgi сервер, и используется hgweb для того, чтобы определить, какой доступ давать юзеру.

Это настраивается в файле hgrc (который лежит в подкаталоге .hg репозитория), в секции web. Прописывается очень просто:
Copy Source | Copy HTML<br/>[web]<br/>contact = Organization name<br/>description = Repository description<br/>style = gitweb<br/>allow_read = user1 user2 user3<br/>allow_push = user1<br/>push_ssl = false<br/>allow_archive = bz2 gz zip <br/>
В данном случае заливать в репозиторий может только user1, а читать могут трое. От анонимусов данный репозиторий закрыт. Подробнее по настройкам доступа тут.

В заключение нужно создать симлинк с файла /home/hgdata/hg.somewebsite.com в каталог /etc/nginx/sites-enabled и рестартнуть nginx, после этого всё должно работать. Необходимо учесть, что т.к. юзером в конфиге nginx прописан www-data, то www-data должен иметь все права на репозитории в /home/hgdata, иначе он не сможет туда писать.

Вот и всё, репозитории должны быть доступны по http. Надеюсь, данная статья будет полезна в вашей работе. Буду рад услышать замечания и предложения.
Теги:mercurialsupervisornginxgunicorn
Хабы: Системы управления версиями
Всего голосов 13: ↑13 и ↓0 +13
Просмотры3.7K

Похожие публикации

Программист отдела управления данными
от 60 000 до 107 000 ₽ТатнефтьАльметьевск
Python developer
от 150 000 до 150 000 ₽C.NordСанкт-ПетербургМожно удаленно
Старший системный администратор Linux/DevOps
до 250 000 ₽Онлайн-кинотеатр iviМоскваМожно удаленно
Ruby разработчик
от 150 000 до 300 000 ₽ZemomediaСанкт-ПетербургМожно удаленно
Инженер отдела управления данными
от 59 000 ₽ТатнефтьАльметьевскМожно удаленно

Лучшие публикации за сутки