Git/GitHub как решение для развертывания WordPress
В настоящее время я разрабатываю WordPress локально, отправляю код на GitHub с помощью Git, а затем подключаюсь к серверу через SSH и выполняю "git pull" для обновления кода. Является ли это хорошим вариантом для развертывания кода на WordPress сайте (очевидно, в данном случае у меня есть root-доступ к серверу). Я знаю о таких инструментах как Capistrano, но не будет ли это излишним для развертывания WordPress сайта? Как я могу максимально эффективно использовать Git/GitHub в этом случае?

Я использую git для этого и считаю, что он отлично справляется. Несколько рекомендаций:
- Добавьте папку загрузок (wp-content/uploads) в ваш файл
.gitignore
. - Запустите веб-сервер и сервер базы данных на вашей локальной системе разработки, чтобы тестировать изменения перед их отправкой в продакшен.
- Следите за тем, чтобы настройки подключения к базе данных совпадали в dev и prod, или добавьте wp-config.php в
.gitignore
, чтобы избежать перезаписи продакшен-настроек. - Избегайте обновления плагинов в продакшене через админку WordPress — в лучшем случае ваша git-копия перезапишет обновлённые плагины при следующем push/checkout, в худшем возникнут конфликты. Обновляйте плагины через админку на dev-системе, коммитьте, пушите и делайте checkout в prod.
Рассмотрите возможность добавления git-хука
post-receive
для автоматического checkout обновлений в директорию, из которой веб-сервер раздаёт WordPress (например,/var/www
). Это позволит разворачивать только файлы проекта, избегая попадания git-метаданных в корневую директорию веб-сервера, а также даст возможность управлять правами через хук. Пример ниже:#!/bin/sh unset GIT_INDEX_FILE # директория, из которой веб-сервер раздаёт WordPress export GIT_WORK_TREE=/var/www/example.com/ # локальная директория с удалённым git-репозиторием export GIT_DIR=/home/git/repos/example.com.git/ # пользователь ниже для Debian — укажите пользователя и группу вашего веб-сервера sudo git checkout -f sudo chown -R www-data:www-data $GIT_WORK_TREE sudo chmod -R 755 $GIT_WORK_TREE sudo chmod 600 $GIT_WORK_TREE/wp-config.php sudo chmod -R 775 $GIT_WORK_TREE/wp-content

Является ли обратная кавычка после unset GIT_INDEX_FILE
опечаткой?

Джеймс довольно точно описал мой рабочий процесс, за исключением того, что я добавляю файлы темы в git-репозиторий только после того, как настрою тестовый/промежуточный/боевой сайт.
Также я настоятельно рекомендую использовать post-receive хук на удаленном сервере — это избавляет от необходимости входить в систему и выполнять git pull и т.д.

Это, вместе с алиасами SSH, означает, что я могу отправить изменения в репозиторий темы на боевом сервере с помощью 'git push live' и т.п.

Я не знаком с процессом обновления плагинов в WordPress, но что произойдет, если обновление плагина внесет изменения в базу данных? Как эти локальные изменения будут перенесены на production-сервер?

@User это может отличаться от плагина к плагину. Ядро WordPress проверяет версии схемы, поэтому если вы обновляете WordPress не через встроенный механизм обновлений, он выполнит обновления БД отдельно. Мой совет: если вы используете плагины, которые записывают данные в БД, проверяйте админку WordPress, так как обновления схемы обычно обрабатываются там, независимо от способа обновления кода плагина.

Пока я тоже изучаю этот вопрос, я добавил в репозиторий только свою активную тему и кастомные плагины. Вопрос о том, что происходит, когда плагин на сайте обновляется, а затем вы перезаписываете его через pull — это причина, по которой я добавляю в .gitignore все плагины, кроме кастомных. Я также игнорирую папку uploads, потому что медиафайлы на моей dev-машине не обязательно совпадают с production-сервером. Более важный момент, который я хочу поднять: GIT не должен заменять backup-restore. Это две совершенно разные операции. Git не должен быть вашим решением для резервного копирования и восстановления.

Я настоятельно рекомендую настроить Capistrano — это требует немного подготовительной работы в первый раз, но затем вы сможете легко использовать его для новых проектов.
Основные преимущества:
- Возможность развертывания прямо с рабочего компьютера. Может показаться незначительным, но подключение по SSH к удаленному серверу и выполнение git pull всё равно остаётся головной болью.
- Простой откат к предыдущей версии, если это потребуется
- Возможность делать крутые вещи, например, настраивать развертывание для staging/production окружений.
Я добавлю набор скриптов Capistrano, чтобы показать, как я это настраиваю.
Capfile
require 'railsless-deploy'
load 'config/deploy'`
deploy.rb
set :stages, %w(production staging local)
set :default_stage, "staging"
require 'capistrano/ext/multistage'
set :application, "" # название вашего приложения — используется для создания имени директории
set :scm, :git
set :repository, "" # используйте SSH-адрес репозитория от провайдера, например git@github.com:name/repo.git
set :deploy_to, "/var/www/#{application}" # это корневая папка сайта на удалённом сервере
set :deploy_via, :remote_cache # получать напрямую из репозитория
set :copy_exclude, [".git", ".DS_Store", ".gitignore", ".gitmodules", "wp-config.php"]
# заставляет Capistrano запрашивать пароль sudo или другие данные для удалённого сервера
default_run_options[:pty] = true
namespace :tasks do
task :fix_links do
run "ln -nfs #{shared_path}/uploads #{release_path}/wp-content/uploads"
run "ln -nfs #{shared_path}/wp-config.php #{release_path}/wp-config.php"
run "ln -nfs #{shared_path}/blogs.dir #{release_path}/wp-content/blogs.dir"
run "ln -nfs #{shared_path}/.htaccess #{release_path}/.htaccess"
run "sudo chown -R www-data.www-data #{release_path}/"
end
end
after "deploy", "tasks:fix_links"
И, наконец, пример файла окружения (если вы используете multistage, то у вас может быть отдельный файл для каждого окружения: local, staging, production).
config/local.rb
server "", :app #имя хоста
set :branch, 'develop' #выберите ветку для развертывания
set :use_sudo, false #не использовать sudo
set :deploy_to, "/var/www/#{application}" #переопределить путь по умолчанию для развертывания
Эти файлы могут потребовать доработки, и вам понадобятся базовые знания Capistrano, но, надеюсь, они помогут некоторым людям.
Вот первый туториал, который помог мне начать работать с Capistrano и WordPress: http://theme.fm/2011/08/tutorial-deploying-wordpress-with-capistrano-2082/

Если вы используете post-receive хуки в git, они устраняют необходимость подключаться по ssh к удаленному серверу и выполнять git pull

@dirt проблема с post-receive хуком в том, что если у вас нет надежной инфраструктуры CI, один некорректный мерж может положить весь ваш сайт. Вероятность этого возрастает, если над проектом работают несколько разработчиков, у которых есть доступ на коммит в ваш репозиторий. Вот почему лично я предпочитаю деплоить через capistrano, но понимаю, почему другие могут не беспокоиться об этом так сильно.

Я действительно делал презентацию на WordCamp по этой теме. Вместо того, чтобы повторяться, вот скринкаст этой презентации и вот очень простой скрипт для деплоя, который дополняет то, что я обсуждал.
Коротко говоря, я использую GitHub для хранения репозитория и вебхук для деплоя изменений на основе git ref. Это позволяет использовать модель ветвления git Винсента Дриссена и открывает возможности для неограниченного количества веб-серверов, staging-серверов, тестовых серверов и т.д. с автоматизированным деплоем. Я также рассказываю о том, как держать wp-config.php под контролем версий, сохраняя при этом отдельные версии для разработки и продакшена (через переименование файлов и симлинки).

Я знаю, что этот вопрос довольно старый, но так как я не видел такого ответа здесь, хочу поделиться своим подходом к git-настройкам и деплою для однопользовательских сайтов, который отлично работает, в том числе при работе с нескольких устройств, из разных локаций и с несколькими разработчиками (у каждого есть свои локальные репозитории, как это принято в git).
Могу горячо рекомендовать следующую настройку:
Также это описано здесь (если вам нужен дополнительный источник для понимания):
Вкратце система работает (с минимум тремя репозиториями) следующим образом:
- Размещаем сайт на продакшн-хостинге под управлением git,
- Создаем новый bare git-репозиторий на продакшн-хостинге.
- Форкаем из bare-репозитория в локальный git-репозиторий для разработки.
После завершения работы вы пушите изменения в удаленный bare-репозиторий, откуда клонировали. Bare-репозиторий имеет хуки для синхронизации с рабочим репозиторием (в приведенных выше примерах он называется prime).
Для WordPress у меня в репозитории есть такой .gitignore
:
# папка uploads содержит данные, исключаем из исходников
wp-content/uploads/
Все остальное, включая настройки плагинов и тем, я держу под контролем версий. Это позволяет легко отслеживать изменения и проверять код перед выкладкой на продакшен. Также упрощается слияние с удаленными репозиториями, например, с ядром WordPress на Github.
Такая схема отлично работает для большинства моих WordPress-проектов. Bare-репозиторий предотвращает конфликты при пуше изменений. Синхронизация с продакшеном происходит быстро благодаря хукам. При желании можно даже вызывать WordPress-хуки после обновления.
Я не экспериментировал с Github-хуками для улучшения процесса, так как код находится под локальным контролем версий, а не на Github.
Для первоначальной настройки системы потребуется оценить наличие необходимых инструментов на хостинге:
- SSH-доступ
- GIT
- Приватная директория для bare git-репозитория
Первоначальная настройка занимает 1-2 часа, включая развертывание окружения и первый деплой.
На некоторых хостингах может потребоваться закрыть доступ к директории .git
через веб. Пример правил для .htaccess
(работает даже если WordPress установлен в поддиректорию):
Options -Indexes
# редирект для .git и подобных файлов
RedirectMatch 404 ^/\.git(.*)$
# маскируем 403 ошибку для .ht* как 404
<Files ~ "^\.ht">
Order Deny,Allow
Allow from all
Satisfy All
Redirect 404 /
</Files>
RewriteEngine On
RewriteBase /
# перенаправляем все в public и устанавливаем переменную окружения
RewriteCond %{ENV:REDIRECT_sitealias} !set
RewriteRule ^(.*)$ /public/$1 [E=sitealias:set,L]
Коротко: все что вне директории public недоступно из веба. В public может находиться WordPress. Для его .htaccess
:
RewriteEngine On
# маскируем прямой доступ как 404
RewriteCond %{ENV:REDIRECT_sitealias} !set
RewriteRule .* - [L,R=404]
Это предотвращает прямой доступ к public. Часть этого подхода описана здесь: Requests to .htaccess should return 404 instead of 403. Работу переменных окружения нужно проверять индивидуально. Также решите, добавлять ли эти файлы в репозиторий.
На более управляемых хостингах можно реализовать более оптимальные решения. Приведенные примеры ориентированы на shared-хостинги с поддержкой GIT.
Из минусов - некоторые общие проблемы, описанные в других ответах. Например, не самое элегантное решение - правка hosts-файла на разработческой машине для перенаправления запросов к БД на тестовую копию. Это небезопасно из-за хранения учетных данных.
Автоматические бэкапы
Я не заморачиваюсь с этим, так как на удаленных серверах настроены ежедневные инкрементальные бэкапы, которые хранятся в другом месте. Это позволяет восстанавливать и WordPress, и загруженные файлы, и БД, и git-репозиторий. Мои команды для бэкапов:
mysql: mysqldump --host=%s -u %s --password=%s %s| gzip > %s
git : git gc
git bundle
files: tar --force-local -czf %s %s
Рекомендую выносить процессы, связанные с WordPress, за его пределы. Приложение может упасть, но эти процессы должны продолжать работать.
Командная работа
Дополнительный плюс - сайт сразу готов для командной работы. Благодаря bare-репозиторию сложно что-то сломать, а коллеги могут использовать отдельные ветки помимо master/live.
