Янв
07
2010

Синхронизация между dev и live версиями сайта

Немного расскажу про часть своего рабочего процесса над drupal проектами (хотя такую схему, но немного с другими настройками вполне можно применять на других проектах). Итак, задача: есть dev версия сайта, с которой я работаю локально (или же это может быть отдельный сервак). Это рабочая копия проекта, которая находится под системой контроля версий (svn) и все новые фичи или исправления сперва реализуются в этой версии. После того как реализована новая фишка или исправлена ошибка и всё это оттестированно, стоит задача – залить всё на live-сайт. Заливаю, разумеется, через rsync, но чтобы не писать каждый раз  кучу параметров rsync я сделал несколько скриптиков, облегчающих эту задачу. Далее подробнее.
Скриптов у меня получилось 3 (хотя надо бы всё объединить в один скрипт конечно):

sync_up – заливает файлы на live

sync_dl – сливает файлы с live

get_db – получаем дамп базы данных с live сайта

Сразу  скажу, что для работы по моей такой схеме необходим ssh доступ к серверу, иначе Вы просто не сможете воспользоваться командой rsync.

И сразу к делу.

Синхронизация файлов

sync_up

#!/bin/bash
command=»rsync -rlcpv ./ user@example.com:public_html/ –exclude-from=./rsync_exclude»
if [ "$1" = "run" ]
then
printf «\n\tСкрипт будет запущен без ключа –dry-run. Запускать скрипт в этом режиме стоит с осторожностью. \n\t»
read -p «Точно продолжить? (ctrl+c остановит работу скрипта, иначе нажмите любую клавишу)»
printf «\n»
$command
else
printf «\n\tСкрипт будет запущен в тестовом режиме (с ключом –dry-run). \n\tДля запуска скрипта в основном режиме стоит запускать его с ключом ‘run’\n\n»
${command} –dry-run
fi

У sync_dl почти то же самое за исключением второй строчки:

command=»rsync -rlcpv user@example.com:public_html/ ./ –exclude-from=./rsync_exclude_server»

Идея скрипта заключается в том, что я один раз указываю мою команду rsync со всеми нужными ключами и параметрами кроме –dry-run. Я считаю, что перед тем как запускать rsync надо сперва обязательно запустить его в холостом режиме (чтобы он только показал, что будет делать, но не делал сразу), т.е. с ключом –dry-run. Ранее у меня эти скрипты состояли просто из одной команды rsync со всеми ключами и параметрами (в том числе и с –dry-run). И я обычно первый раз запускал скрипт просто так и видел, что будет сделано, а потом открывал файл на редактирование и убирал ключ –dry-run, запускал еще раз скрипт и затем возвращал ключ –dry-run обратно. Согласитесь, что это неудобно). Теперь ничего редактировать не надо. Если мы просто запускаем скрипт ./sync_up, то программа сразу запускается в холостом режиме, выводя при этом справочный текст о том, что это холостой режим и что для запуска в нормальном режиме надо запускать скрипт с ключом run. Т.е. ./sync_up run Причем когда мы запускаем скрипт в этом режиме, то он не сразу запускается, а еще выдаёт предупреждение и подсказку, что его еще можно прервать. Это я на всякий случай сделал, а то мало ли… ;)

Про опции, с которыми я запускаю rsync я уже писал ранее.

Чтобы не вводить каждый раз пароль при соединении с удалённым хостом рекомендую прочитать про настройку ssh без пароля (авторизация по ключам).

Опцией –exclude-from=./rsync_exclude я указываю, чтобы rsync взял список файлов-исключений (которые не надо заливать на удалённый сервер) из файлика rsync_exclude. А в случае работы sync_dl используется файл rsync_exclude_server. В нём я задаю список файлов, которые не надо сливать сервака. Таким образом я могу контролировать чтобы какие-то файлы только сливались с удалённого (например сливать файлы, которые загружает заказчик на свой сайт, но не загружать туда свои тестовые файлы). В случае drupal (а я применяю эту схему на drupal проектах) например я делаю так, чтобы с сервака ко мне сливались дампы базы сделанные модулем backup_migrate, а с рабочей версии чтобы они туда не заливались, а так же например я могу сливать в рабочую копию содержимое папки sites/default/files, но не заливать туда файлы, которые я заливал на тестовый (dev) сайт.

Для примера привожу содержимое моих файлов rsync_exclude и rsync_exclude_server на одном из моих проектов (от проекта к проекту эти файлы могут отличаться).
rsync_exclude

/rsync_exclude
/rsync_exclude_server
/sync_dl
/sync_up
/databases/
/sqls/
/db.sql
/sites/default/files/xmlsitemap/xsm-ru.xml
/sites/default/settings.php
/sites/default/files/languages/
/sites/default/files/backup_migrate/
/.buildpath
/.settings
/.project
.svn
*~

rsync_exclude_server

/rsync_exclude
/cgi-bin/
/sites/default/settings.php
/sites/default/files/xmlsitemap/xsm-ru.xml
*~
.listing
.svn
/error_log
/rsync_exclude
/rsync_exclude_server
/sync_dl
/sync_up
/databases/
/sqls/
/db.sql
/sites/default/settings.php
/sites/default/files/languages/
/.buildpath
/.settings
/.project
.svn
*~

Кстати в этих файлах для игнора можно указывать просто .svn и тогда во всех папках и подпапках будет игнорироваться папка или файл с названием .svn. А если указать, например, /.settings, то будет игнорироваться только файл .settings в корне. Корень будет отсчитываться от того пути, который при вызове rsync является источников источника. Т.е. мы как бы rsync’у указываем «вот эти файлы и папки из источника не бери».

Получение базы данных с удалённого

Как я ранее упоминал: у меня три скрипта. Про первых два я уже сказал. Остался скрипт get_db. Он довольно прост:

#!/bin/bash
ssh user@example.com mysqldump –user=USERNAME –pass=PASSWORD DATABASENAME > db_dump_from_live.sql

где USERNAME, PASSWORD и DATABASENAME – это данные для mysql на удалённом (live) серваке
Т.е. мы соединяемся по ssh с удалённым сервером и запускаем команду (для команды ssh можно параметром передавать команды для запуска на удалённом), которая на выходе выдаёт дамп базы, который мы, в свою очередь, направляем в какой-то наш локальный файл (т.е. на live мы никаких дампов базы не оставляем).

Теперь, чтобы развернуть эту базу у себя на dev сайте, то просто запускаем

mysql –user=DEV_USERNAME –pass=DEV_PASSWORD DEV_DATABASENAME

А если у вас, как и у меня, установлен на dev модуль drush (это если вы еще и с drupal работаете как и я =) )
Затем в приглашении mysql консоли вводим:

source db_dump_from_live.sql

Кстати, я все эти скрипты храню и запускаю от корня рабочей версии сайта. Файлы игноров и дампов базы данных лежат тут же. Всё это я держу в svn. Кроме файла get_db, потому что в нём открыто хранится информация о данных доступа к базе данных на live сайте. И если вы будете этот файл держать под системой контроля версий, то кто-нибудь, кто получит доступ к вашему svn репозиторию сможет получить эти данные.
Есть решение проблемы: установить и на удалённом сервере drush и тогда ваш файл ./get_db будет иметь вид:

#!/bin/bash
ssh user@example.com «cd public_html/; drush sql dump» > db_dump_from_live.sql

Этот вариант предпочтительнее, хотя и требует небольших действий на сервере.

Итоги

Ну вот вобщем-то и всё. Вот такой вот кусочек моего процесса )

Кстати напомню, что после создания файла со скриптами необходимо им установить права на выполнение. Для этого в консоли можно написать: <b>chmod u+x get_db sync_up sync_dl</b>.

Если говорить о разработке на drupal, то у меня не решён пока что вопрос по синхронизации базы данных между dev и live версиями. Это, имхо, один из недостатков друпаля, что он хранит все настройки в базе. Поэтому мне приходится изменения, сделанные через админку (т.е. в базе), а не в файлах дублировать на live сайте ручками. Вобщем над этой темой я еще работаю.

Ближайшей задачей по улучшению этого всего, думаю, будет сборка этих трёх скриптов в один.

Мне будет интересно прочитать Ваше мнение об организации такого вот рабочего процесса.

tags: , , , , ,
posted in web by yas375

Follow comments via the RSS Feed | Оставить комментарий | Trackback URL

3 Comments to "Синхронизация между dev и live версиями сайта"

  1. ShkilionOK wrote:

    Виктор, а почему нельзя поставить и production (или live) под контроль SVN? Черепашка делает все то же самое, только в интерактивном режиме.
    и не понял, зачем каждый раз базу синхронизировать? Какая для необходимость в этом для staging’а?

  2. yas wrote:

    ну live держать под svn не очень хорошо. могут быть проблемы с безопасностью (http://habrahabr.ru/blogs/infosecurity/70330/). плюс получается, что тогда для каждого клиентского сайта создавать еще и аккаунт к нашему svn? мы рассматривали такой вариант работы, но всё же пришли к тому, что это не очень хорошо. на live должно быть всё чистенько и аккуратно. Тем более, что в svn я могу и какую-то инфу хранить, которой на live быть не должно. А именно скрипты вспомогательные, дамп базы…
    базу каждый раз я не синхронизирую. Но иногда удобно забрать базу с клиентского сайта и у себя её развернуть. например приходит задача, что клиент хочет, чтобы когда на странице выводится 30 статей, то должен быть paging. Ну и мне надо его включить, оформить (если до этого не делался paging), ну и проверить. Так проще забрать базу клиента и у себя развернуть, чтобы не надо было создавать кучу тестового материала. А иногда может быть, что клиент жалуется на какие-то глюки на живом сайте, тогда тоже удобнее развернуть полную копию сайта для тестирования и исправления.
    Ну и еще один момент: я дамп базы в svn храню. С каждым более-менее крупным каким-то изменением на сайте я бэкаплю и базу. Просто с drupal у меня были когда-то случаи, когда сайт просто падал, база ложилась (уже не помню из-за чего, т.к. давно это было). Ну и после того у меня выработалась какая-то параноя и я бэкаплю дамп базы теперь периодически )
    Плюс т.к. друпаль все настройки хранит в базе. То в случае если клиент чего-нибудь наменяет в настройках на сайте и там что-нибудь не понятно вдруг сломается (или например он удалит views какой-нибудь большой с сложный), то мне будет проще вытянуть из svn определённую ревизию, развернуть у себя и сравнить в ручную настройки в админке (ну или сделать у себя экспорт, а на live импорт необходимого views’а). Таких ситуаций у меня, правда, еще не было, но я уже подстраховался =)

  3. Alex wrote:

    Очень толковая статья, бились над аналогичной проблемой, пришли к такому же практически решению, правда у нас платформа 1С-Битрикс. С БД вопрос открыт тоже к сожалению :(.

Leave Your Comment