вторник, 3 августа 2010 г.

Способы развертывания приложения на сервере из системы контроля версий

Опишу основные способы, которые можно использовать, развертывая свое приложение на сервере или, как принято говорить, на production из svn, git, cvs или другой системы контроля версий. Везде я буду говорить явно о svn, но принцип подходит к любой другой.
Сам процесс развертывания может быть как очень простым, так и очень сложным. Одно из самых простых развертываний - это копирование html файлов проекта, ну а к самым сложным можно отнести обновление какой-нибудь крупной поисковой системы. Такое обновление может идти не один день.
В целом мой текст относится к обновлению относительно простых сайтов, использующих один сервер и, возможно, несколько серверов БД.

1) Ручной копирование с локального компьютера на сервер. Тут возможны варианты, когда делается экспорт проекта, чтобы файлы самой svn не попали в сборку, либо копирование вместе с этими файлами. Вариант явно не ахти, некошерно.

2) Обновление приложения напрямую из репозитория. В данном случае проект чекаутиться или экспортируется прямо из репозитория в папку приложения. В случае чекаута можно обновлять приложение частично, используя команду svn update. Наиболее рационально обновлять его из стабильной ветки(branch). Но для небольших самоуверенных проектов можно и из основной ветки приложения. Преимущества в том, что быстро и просто. Недостатки в том, что старая версия приложения может не сохраняться, либо этот процесс происходит вручную. В общем, данный вариант кошернее ручного копирования, но все же не подходит для сколь-нибудь серьезного применения, в силу своей негибкости, большого простора для ошибок и неунифицированности.

3) Использование системы, предназначенной для обновления приложения. Лично у меня есть опыт использования только одной такой системы - Capistrano. В целом данная система унифицирует процесс, описанный в пункте 2, не позволяя допустить базовых ошибок, в тоже время давая большой простор для действий. Отличительной особенностью тут является версионирование сборок и возможность отката к старой версии.
Создается несколько папок: current, releases и shared. В current всегда находится текущая версия сборки, в релизах находятся папки сборок(имя папки - дата сборки), в shared можно сохранить общие данные для релизов или сборок. При обновлении, Capistrano, используя определенную стратегию создания сборки, создает новую папку в releases, выполняет саму сборку и после успешного выполнения обновляет ссылку папки current. Происходит это с использованием символьных ссылок(symlink), то есть current папка является ссылкой на один из релизов. Причем обновление происходит транзакционно и в случае ошибок, релиз не создается и соответственно ссылку на текущий релиз не меняется.
Capistrano предоставляет несколько стратегий обновления по умолчанию, среди которых знакомый нам checkout и export. В данном случае в папку релиза сбрасывается текущее содержание проекта из репозитория. Вариант с экспортом проекта кажется наиболее безопасным, ведь в данном случае сохраняется полная копия всего проекта.
Бывает, что такой вариант неприемлем или попросту не нужен. Поэтому возможно создание чекаута на сервере в папке shared, обновление этой версии и копирование в папку ревизии. Здесь, как минимум, экономия во времени, т.к. приложение не скачивается каждый раз из репозитория целиком. Причем можно не копировать всю получившуюся сборку целиком, а только нужные её части. Например, в проекте существуют тысячи картинок, которые не хотелось бы копировать в каждую версию сборки(накладно с точки зрения занимаемого пространства и времени копирования). Тогда можно создать symlink на папку картинок и она будет браться из последней ревизии. К тому же крайне удобно таким образом симлинкить конфигурационные файлы, например конфигурационный файл БД. Ведь обычно такие файлы не хранят в репозитории, а создают уже на месте, либо хранят их заготовку.
После обновления, Capistrano может выполнять различные задачи, например, миграцию схемы БД или прогонку тестов(ведь надо быть уверенным, что сборка валидна). Много простора для фантазии, если вы владеете языком Ruby. 
В общем, можно создавать любые задачи для Capistrano и выполнять их со своего локального компьютера(обновление сборки тоже делается с локального компьютера). Это конечно же очень удобно.


Учтите, что если в сборку попадают файлы системы контроля версий и на сервере не установлен запрет на чтение этих файлов(например, запрет на чтение "*.svn"), то это может привести к получению злоумышленников части исходных кодов вашей системы. А там вполне могут быть ценные пароли, либо информация, помогающая осуществлению взлома. Эта тема поднималась на Хабре http://habrahabr.ru/blogs/infosecurity/70330/ и стала сенсационной, хотя по сути является банальным недосмотром и следствием чьей-то лени.