Развертывание WordPress на dev, stage и production серверах
Мне необходимо организовать dev/stage/production окружения (на отдельных серверах) для сайта на WordPress. Обычно я использую git, но с WordPress это не работает из-за сильной зависимости конфигурации практически всего от базы данных.
Вопрос: как вы решаете эту проблему? Быстрый поиск показал несколько плагинов - это единственный вариант? Какие плагины лучше всего справляются с задачей с точки зрения удобства, скорости, надежности и интерфейса?

У меня есть настройка, которой я очень горжусь, и она отлично работает для моей команды.
Общая структура
Я храню всю установку под git. Все изменения, будь то обновление системы, добавление/обновление плагина, добавление/обновление темы, проходят через один и тот же рабочий процесс. Изменения можно откатить в любой момент. У меня есть сервер развертывания (старый настольный компьютер P4), на котором работает gitosis, но вы также можете использовать github или gitolite. В git у меня есть две "особые" ветки: master
и develop
(подробнее объяснено ниже). Мои продакшен- и стейджинг-серверы работают в облаке.
Среды разработки
Каждый разработчик запускает свой собственный сервер разработки на своем компьютере. Что касается баз данных, необходимость в реальных данных возникает крайне редко. Мы в основном используем тестовые данные для тестирования тем. В остальных случаях экспорт и импорт покрывают большинство потребностей. Если работа с БД критична, вы можете настроить репликацию или организовать синхронизацию по запросу. Когда я впервые настраивал эту структуру, я думал, что это будет критично, поэтому начал писать набор инструментов для этого, но, к моему удивлению, они действительно не понадобились. (примечание: так как они не были необходимы, я не стал их дорабатывать, поэтому в них есть баги, например, они заменяют домен в сериализованных данных).
Стейджинг-среда
Когда коммиты отправляются из ветки develop
в gitosis, они автоматически развертываются на нашем стейджинг-сервере. База данных стейджинга является слейвом для продакшен-базы данных.
Продакшен-среда
Когда коммиты отправляются в gitosis в ветку master
, они автоматически развертываются на продакшен-сервере.
Проблема с wp-config.php
Нужно, чтобы wp-config.php
был уникальным для каждого сервера, но при этом оставался под контролем версий. Мое решение — использовать .gitignore
для игнорирования wp-config.php
и хранить версии для стейджинга и продакшена под разными именами. Затем на каждом сервере я создаю симлинк, например wp-config.php -> wp-config-production.php
. Каждый пользователь хранит свою БД со своими учетными данными и своими (неотслеживаемыми) настройками в wp-config.php.
Другие заметки
Я использую Rackspace Cloud, что просто замечательно и недорого. С ним я могу держать стейджинг- и продакшен-серверы идентичными. Сейчас я также пишу плагины, использующие их API, что позволяет мне управлять сервисами прямо из WordPress — это прекрасно.
Каталоги кеша, загружаемых файлов и т. д. добавлены в .gitignore. При желании можно настроить cron-задачу для периодического сохранения загрузок и отправки их в gitosis, но мне это никогда не казалось необходимым.
Структура master/develop частично повторяет модель ветвления Vincent Driessen. Я также использую его расширение git — git-flow, и я очень рекомендую его.
У меня уже больше года работает около 10 разработчиков с этой структурой, и это просто мечта. Надежная, безопасная, быстрая, функциональная и гибкая — большего и не нужно!

Я собираюсь настроить установку WordPress аналогичным образом (но мы используем SVN) и хотел подтвердить ваш процесс обновления плагинов и WP: выполнить обновление и проверить на dev, зафиксировать изменения, развернуть их на staging, проверить, развернуть на продакшене. Если кратко, вы никогда не выполняете обновление установки WP непосредственно на живом сервере, а вносите изменения через обновления в репозитории?

А как насчёт изменений в базе данных, которые вносит процедура обновления? Как они применяются к рабочей БД?

Этот рабочий процесс верен, @paullb, и вам не нужно беспокоиться об обновлениях БД. WordPress устроен так, что обновления запускаются после обнаружения изменений, поэтому это работает точно так же, как и при ручном обновлении (ядра или плагинов)!

@MatthewBoynes, привет. Ты всё ещё используешь этот рабочий процесс в своей разработке? Если да, то я собираюсь применить его в своём проекте. Спасибо :)

Я не использую, но только потому, что это неприменимо к проектам, над которыми я сейчас работаю — в основном это проекты, размещённые на WordPress.com VIP. Если бы это было применимо, я бы всё ещё использовал этот подход (и, по факту, компания, в которой я работал ранее, продолжает его использовать).

Отличный материал. Как вы управляете изменениями в существующих записях на staging? Как вы переносите правки в продакшен?

@MatthewBoynes А как насчёт настроек плагинов? Они тоже хранятся в базе данных, но мы хотим протестировать их локально перед изменением на продакшене (и нам бы не хотелось менять их дважды, так как это чревато ошибками).

У меня не получилось использовать вариант с symlink для config.php; это не сработало с vvv.

Во-первых, важно подумать что именно вы собираетесь контролировать с помощью системы управления версиями. Я бы рекомендовал не помещать всю директорию WordPress под контроль версий. Наиболее логичным представляется добавление в систему управления версиями папки wp-content/themes/YourThemeName. Для крупного сайта со множеством сложных плагинов можно рассмотреть включение в систему управления версиями и папки wp-content/plugins. Если уж совсем необходимо, можно включить и wp-content/uploads. Ответы ниже будут немного отличаться в зависимости от того, что именно вы контролируете.
Исходя из этого, вот что я использую:
Локальная среда: Настройте LAMP-стек на своем компьютере. Используйте тот же URL, что и на сайте разработки. Применяйте VirtualHosts и записи в файле .hosts для имитации среды разработки с точки зрения URL. Если вы контролируете только тему, подумайте об использовании SSHFS для связи с wp-content/plugins и wp-content/uploads. Подумайте об использовании базы данных с вашей установки для разработки, если только вы не занимаетесь действительно сложной работой.
Среда разработки: Проверьте рабочую копию вашего репозитория в среде WordPress. Настройте POST-COMMIT-хук в SVN для обновления этого репозитория после каждого коммита. Это позволит поддерживать его в актуальном состоянии. (Можно считать это упрощенной формой непрерывной интеграции.)
Продакшн-среда: Используйте именованный тег версии, представляющий финальный кандидат. Когда потребуется использовать новую версию, переключите тег и обновите репозиторий.

Среда разработки идеально подходит для тестирования ночных сборок, и git wordpress обновляется автоматически каждые 30 минут. Кроме того, она децентрализована и лучше работает для команд. Я не знаю никого, кто перешел на git/hg и вернулся обратно к использованию svn.

Просто интересно, почему вы не помещаете весь каталог WP под систему контроля версий. Это выглядит как узкое место в рабочем процессе. Размещение WP в репозитории дает всем разработчикам одинаковую кодовую базу и версию WP. Это также обеспечивает согласованность между средами. Смотрите ссылку Wyck (в его ответе) на условные файлы wp-config.

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

Я делаю это с помощью git и mercurial, главное убедиться, что вы используете приватный репозиторий.
Вариант 1.
Единственная проблема — это файл config.php, который можно настроить так, чтобы git игнорировал его при пуше или перед инициализацией.
Используйте .gitignore
или git update-index --assume-unchanged config.php
(перед использованием команды assume-unchanged лучше почитать о ней подробнее)
Вариант 2.
Добавьте условие в config.php, которое проверяет URL и применяет нужные учетные данные, например: "если URL сервера = dev, используй учетные данные A, иначе — учетные данные B" и т. д.
Марк объясняет это лучше: http://markjaquith.wordpress.com/2011/06/24/wordpress-local-dev-tips/
P.S. Также можно раздавать файлы напрямую из удаленного репозитория вместо традиционного "файлового сервера". (Очень скучное видео, которое я записал на эту тему: http://www.youtube.com/watch?v=8ZEiFi4thDI)
