Хостинг 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. Надеюсь, данная статья будет полезна в вашей работе. Буду рад услышать замечания и предложения.

    Комментарии 18

      –3
      Я хостю репозиторий в апаче/wsgi. На скорость мне плевать, а всякие апаческие вкусности (макросы конфигурации, например) оказались кстати. Ну и на скорость плевать, в принципе, не так быстро пишем :-)
        0
        Так статья про хостинг репозиториев — допустим, 100 или больше :-)
        0
        Здорово, осталось дать доступ по ssh:// и прикрутить возможность использовать ssh ключи, и будет вообще бенч :) Спасибо, статья понравилась!
          0
          По ssh я git юзаю, а это для Windows-девелоперов.
            0
            Дык, Windows-девелоперы, тоже люди :)
              0
              угу :-)
              0
              Я под Win использую и git и mercurial по ssh. Где-то должны быть проблемы?
                0
                Насколько я понимаю, вопрос риторический :-)
                  0
                  Просто некоторые недооценивают Windows в качестве платформы для web разработки.
                    0
                    ↑ статья не про это
                      0
                      Я про вашу переписку выше.
              0
              0
              А вы с таким сталкивались в рамках одной софтовой компании? 100 или больше активных репозиториев?
                +1
                Ну у нас не 100 конечно, но гораздо больше одного.
                0
                Репозитории как грибы растут, после того, как компания 3-4 года успешно работает на рынке, и выпускает определенное количество продуктов ежегодно.
                  0
                  У нас в компании порядка 30 свиновых репозиториев и еще с 10 hg'шных.
                  +1
                  А у нас на работе код хостится на RhodeCode. В принципе удобно…
                    0
                    Поддерживаю, использую rh с самого начала его существования, он правда не очень быстро развиваются, но сейчас использовать вполне так можно, особенно после введения груп и многочисленных исправлений с интеграцией ldap.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое