вторник, 10 марта 2009 г.

Настройка сервера Apache для командной веб-разработки

Дано

Команда разработчиков, Apache, SVN-сервер, несколько рабочих проектов.

Найти

Максимально простой способ организовать рабочие копии каждого программера с возможностью доступа к каждой из них по уникальному URL'у. А еще лучше не ограничивать программистов "одна рабочая копия в одни руки", а предоставлять им возможность для каждой своей ветки создавать собственный виртуальный хост. Не забыть про тестовый сервер, куда будут периодически подтягиваться обновления из trunk.

В идеале хотелось бы, чтобы проект имел следующую структуру:

  • /srv/www/vhosts/example.com
    • www – каталог с актуальной копией рабочей версии (тестовый сервер)
    • vasya – рабочая копия Васи
    • petya – рабочая копия Пети
    • vasya-test – тестовая ветка Васи

При этом каждый разработчик должен иметь возможность создать каталог в корневой директории проекта и автоматически получить к ней доступ по адресу <Имя каталога>.example.com. Все это должно работать без постоянных перезапусков Apache и без необходимости раздать всем root'а.

Решение #1. mod_rewrite

Первое, что приходит в голову — использовать mod_rewrite. К тому же где-то я подобное решение видел в сети, но сейчас не получается его найти. Если автор наткнется на мою записку, с удовольствием поставлю ссылку на оригинал.

Модуль Apache mod_rewrite позволяет преобразовывать запрашиваемые URL по заданным правилам, тем самым создавая виртуальную структуру файлов и каталогов на сервере. За более подробной информацией лучше обратиться к официальному руководству или к любому из его переводов.

Итак, открываем файл настройки виртуальных хостов Apache. В зависимости от вашей системы это может быть либо httpd.conf, либо дополнительный файл, подключаемый из основного. Находим секцию, описывающую виртуальный домен нашего тестового проекта. И корректируем его в соответствии с примером:

<VirtualHost *>
    ServerName example.com
    ServerAlias *.example.com
    DocumentRoot /srv/www/vhosts/example.com

    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond   %{HTTP_HOST}    ^(.*).example.com$
        RewriteRule   ^(.*)$          /%1/$1 [L]
    </IfModule>
<VirtualHost *>

В примере указаны только настройки, относящиеся к организации поддоменов. Рассмотрим их подробнее. ServerName Определяет доменное имя нашего хоста. ServerAlias указывает, что все поддомены должны обрабатываться этим виртуальным хостом. DocumentRoot определяет корневой каталог, в котором будут располагаться рабочие копии.

Дальше самое интересное. Собственно сам код, отвечающий за перенаправление поддоменов в рабочие копии. RewriteEngine On активирует модуль mod_rewrite. RewriteCond позволяет выделить из доменного имени все, что находиться левее example.com. И, наконец, RewriteRule перенаправляет запрос в каталог, соответствующий имени поддомена.

После перезапуска Apache мы получим искомое поведение. Любой пользователь может произвольно создавать поддомены, получать к ним доступ и удалять при необходимости. Установка прав файловой системы даст возможность разграничить доступ к рабочим веткам и каталогу www, выполняющему функции тестового сервера.

Гибкость mod_rewrite предоставляет практически неограниченные возможности по развитию этого метода. Можно, например, настроить автоматическое обрезание префикса www при вычислении имени рабочей копии, проверку существования каталога поддомена, создать несколько алиасов для тестового сервера и многое другое. Но есть и ложка дегтя. mod_rewrite не переопределяет DOCUMENT_ROOT, который отдается скриптам через переменные окружения, для всех поддоменов он равен /srv/www/vhosts/example.com, что может создать определенные трудности. Если же учесть эту особенность при разработке и не использовать переменную окружения DOCUMENT_ROOT, то это решение дает хорошие результаты.

Решение #2. mod_vhost_alias

В стандартная поставка Apache (по крайней мере в OpenSUSE 11.0) содержится модуль mod_vost_alias, который как раз и призван обеспечить динамически создаваемые виртуальные хосты. Подробнее о нем можно почитать здесь и здесь, мы же расмотрим его использование в контексте нашей задачи.

Итак, файл настройки виртуального хоста принимает вид:

<VirtualHost *>
    ServerName example.com
    ServerAlias *.example.com
    DocumentRoot /srv/www/vhosts/example.com

    VirtualDocumentRoot /srv/www/vhosts/example.com/%1
<VirtualHost *>

Как видите, была добавлена только одна инструкция: VirtualDocumentRoot. Она определяет, что из запрошенного имени хоста будет выделяться первая часть и искаться подкаталог с соответствующим названием. Например, для www.example.com будет искаться /srv/www/vhosts/example.com/www, а для vasya.example.com/srv/www/vhosts/example.com/vasya.

В принципе, аналогично использованию mod_rewrite, но без некоторых возможностей. Например, сделать так, чтобы и www.vasya.example.com, и vasya.example.com ссылались на /srv/www/vhosts/example.com/vasya уже нельзя. Более того, переменная окружения DOCUMENT_ROOT также содержит /srv/www/vhosts/example.com для любого из виртуальных поддоменов, что в контексте нашей задачи полностью лишает mod_vhost_alias какого-либо преимущества перед mod_rewrite.

Выводы

Итак, мы рассмотрели два способа создания виртуальных доменов для сервера Apache. При этом оказалось, что оба имеют один недостаток: неверное значение переменной окружения DOCUMENT_ROOT, но использование mod_rewrite дает больше гибкости при настройке отображения доменных имен на каталоги рабочих копий.

Возможно, существуют и другие решения, но мне их найти не удалось. Поэтому пока остановлюсь на mod_rewrite и поудаляю все использования DOCUMENT_ROOT из рабочих проектов.

Комментариев нет: