Поскольку система WordPress является PHP-приложением, она обычно развертывается при помощи достаточно старого метода – загрузки файлов по FTP.
Конечно, в природе существуют некоторые инструменты для развертывания, однако зачастую они требуют знаний в сфере Ruby. К примеру, один из достаточно популярных, мощных инструментов – Capistrano, — поставляется вместе с многочисленными связанными с Ruby/Rails возможностями. Как мне кажется, обычному PHP-разработчику, не знакомому с Ruby, будет довольно сложно установить Capistrano.
Так какие же варианты у нас, как у разработчиков WordPress, имеются?
В этом руководстве я познакомлю вас с Mina – небольшим, легким инструментом, который позволяет добиться быстрого развертывания и автоматизации серверных задач.
- Почему мы нуждаемся в автоматическом развертывании?
- Что представляет собой Mina?
- Шаг 1. Готовим подходящую структуру сервера для Mina.
- Шаг 2. Установка Mina
- Развертывание WordPress с помощью Mina
- Шаг 1. Устанавливаем Mina в WordPress
- Шаг 2. Настраиваем config/deploy.rb
- Развертывание с помощью Mina
- Шаг 1. Подготовка
- Шаг 2. Развертывание
- Шаг 3. Откат
- Далее
Почему мы нуждаемся в автоматическом развертывании?
Автоматическое развертывание позволяет нам сэкономить время, которое обычно уходит на выполнение однотипных задач каждый раз, когда мы начинаем развертывать свой собственный проект на WordPress. Также оно помогает минимизировать время простоя в процессе развертывания и устранить человеческие ошибки: нехватку важных файлов, загрузку неправильных файлов и т.д.
К автоматическому процессу могут быть привлечены сразу несколько разработчиков одной команды, что позволяет создать уникальный метод развертывания. Одна из компаний (не будем называть ее имя) практически обанкротилась из-за отсутствия продуманного процесса развертывания. Автоматизированный метод развертывания обычно связан с системой управления исходным кодом: Git, SVN, Mercurial и т.д.
В пределах этого руководства мы будем использовать Git. Если у вас уже есть Git репозиторий, вы можете использовать его; в противном случае создайте его бесплатно с помощью BitBucket или GitLab. Эти службы позволяют создавать приватные Git репозитории.
Перед тем, как пойти дальше, давайте убедимся в том, что мы имеем следующее:
- SSH соединение
- Git репозиторий
- Oermission для редактирования и изменения конфигурации веб-сервера
Примечание: я предполагаю, что у вас запущен WordPress на Apache с установленным модулем Apache PHP. Если вы используете PHP с FPM или CGI, то в таком случае вам придется самостоятельно проводить параллели с теми примерами, которые мы приводим.
Развертывание с помощью хуков Git
Общая идея заключается в том, что когда мы запускаем сервер, то Git вызывает URL, связанный с PHP-скриптом, который выполняет развертывание путем получения (или слияния) самого свежего кода из репозитория.
Такой способ прекрасно работает, однако он содержит в себе одну дыру: мы открываем секретную дверь на сервере. Если кто-либо узнает URL, то он сможет вручную инициировать развертывание. Другая опасность такого подхода – мы должны создать функции для очистки, отката, блокировки (чтобы убедиться в том, что запущен только один процесс развертывания) и т.д.
Кодирование этих функций аналогично повторному изобретению колеса. Так почему бы нам не воспользоваться уже существующими инструментами?
Что представляет собой Mina?
Mina – эффективный и быстрый инструмент развертывания; вы будете удивлены, как быстро выполняется процесс развертывания с помощью Mina. Веб-сайт Mina говорит следующее:
«Действительно быстрый инструмент развертывания и серверной автоматизации. Чертовски быстрый».
Проще говоря, вот как работает Mina: вместо того, чтобы входить на сервер и вбивать последовательность команд для развертывания, Mina генерирует shell-скрипт, который является набором данных команд.
- Создаем новую директорию.
- Помещаем свежий код в данную директорию.
- Делаем символьные ссылки к общим ресурсам.
- Переносим публичную директорию в нашу новую директорию.
- Очищаем старые данные.
Mina загружает shell-скрипт на сервер и выполняет его. Процесс генерации скрипта, представленный выше, выполняется на вашей локальной машине.
Все задачи Mina представляют собой обычную последовательность shell-команд. Поскольку это всего лишь shell-команды, у вас нет доступа к фантастическому хелперу Ruby, который присутствует в Capistrano или Vlad.
Также можно рассматривать Mina следующим образом: Mina представляет ваши shell-команды, которые требуются вам для запуска на удаленной машине, в виде блоков кода (которые называются задачами).
Шаг 1. Готовим подходящую структуру сервера для Mina.
Mina требует для своей работы определенной структуры директорий для нового сайта. Вам нужно будет изменить директорию public для вашего веб-сервера. Предположим, что текущая структура директорий сервера является следующей:
/var/www/yourdomain.com/ # The public directory where your WordPress sits |- index.php |- wp-admin |- wp-content |- wp-includes |- wp-login.php |- wp-activate.php |- ….
yourdomain.com указывает на /var/www/yourdomain.com/, и файл index.php, который находится внутри директории, выполняется и отвечает на ваш запрос. Для Mina вам нужно будет немного изменить структуру каталогов.
Mina ожидает увидеть следующую структуру:
/var/www/yourdomain.com/ # The deploy_to path |- releases/ # Holds releases, one subdir per release | |- 1/ # Each of WordPress deployment sit here | |- 2/ # Each of WordPress deployment sit here | |- 3/ # Each of WordPress deployment sit here | |- ... |- shared/ # Holds files shared between releases: such as log file, config,… | |- logs/ # Log files are usually stored here | - ... |- current/ # A symlink to the current release in releases, this will be new public folder
Mina добавляет три директории:
- releases: каждое развертывание будет сохраняться в отдельных директориях внутри этой папки, что позволит вам обслуживать версию 1, версию 2, версию 3 и т.д.
- shared: содержит общие файлы/папки, которые совместно используются в многочисленных развертываниях. Как пример: wp-content/uploads. В каждом развертывании мы будем иметь новую папку wp-content/uploads, которая отличается от предыдущей папки wp-content/uploads. Таким образом, мы будем использовать общую директорию: shared/wp-content/uploads. Соответственно, /var/www/yourdomain.com/releases/7/wp-contents/uploads – это символьная ссылка, указывающая на /var/www/yourdomain.com/shared/wp-content/uploads.
- current: указывает на текущий релиз. Пример: /var/www/yourdomain.com/current ссылается на /var/www/yourdomain.com/releases/7.
Yourdomain.com теперь должен указывать на /var/www/yourdomain.com/current вместо /var/www/yourdomain.com. Веб-сервер будет запускать файл /var/www/yourdomain.com/current/index.php, когда вы посетите http://yourdomain.com. Нам нужно заново сконфигурировать веб-сервер (Apache, Nginx) для привязки docroot (или public directory) к директории current.
Изменяем DocumentRoot для Apache
Открываем /etc/httpd/conf/httpd.conf, ищем в нем строку DocumentRoot и меняем ее на:
DocumentRoot /var/www/yourdomain.com/current
Изменяем Document Root для Nginx
Редактируем /etc/nginx/nginx.conf и обновляем определение root:
server { server_name log.axcoto.com www.log.axcoto.com; root /srv/http/domain/log.axcoto.com/current/; # … }
Шаг 2. Установка Mina
Mina основана на Ruby, поэтому вам понадобится установить Ruby. Установка достаточно простая. Если вы работаете с OS X или Linux, то в таком случае у вас, возможно, уже будет установлен Ruby; иначе вы можете следовать разным руководствам по установке Ruby.
Для установки Ruby запустите следующее:
$ gem install mina
Убедитесь в том, что Ruby запущен должным образом:
$ mina -V
Вы должны увидеть что-то подобное:
Mina, version v0.3.0
Развертывание WordPress с помощью Mina
Один из аспектов, который делает PHP-приложений менее защищенными, заключается в установке некорректных прав доступа.
Возьмем для примера WordPress: допустим, я хочу загрузить плагин или тему, чтобы попробовать их. Соответственно, я загружаю их в консоли WordPress. Если я или один из администраторов сайта потеряем пароль от своего аккаунта, а кто-то другой получит его, то в таком случае этот человек может загрузить PHP-файл и запустить его в виде плагина, взломав не только сам сайт, но и весь сервер.
Эти люди могут прочитать файлы в /etc, изучить серверную конфигурацию, а затем запустить shell-команды через PHP.
Я думаю, мы должны рассматривать экземпляр WordPress как сборку, открытую только для чтения. Установку плагинов и тем мы можем проводить путем локального добавления файлов и повторного развертывания с помощью Mina. Развертывание с помощью Mina – недорогой и быстрый способ. На моем сервере 512MB RAM DigitalOcean такое развертывание занимает менее 30 секунд.
Для загруженного пользователями контента (изображений, аудио и т.д.) мы будем использовать символьные ссылки, ведущие за пределы директории с исходным кодом. В идеале мы можем сконфигурировать сервер так, чтобы предотвратить выполнение любого PHP-скрипта внутри папки с загруженным пользователем контентом, однако это выходит за рамки нашего руководства.
На данный момент мы попытаемся использовать Mina для быстрого развертывания, а также добавления темы или плагина, причем сделаем это локально, т.е. мы сможем избежать установки прав доступа для записи в данные директории.
Шаг 1. Устанавливаем Mina в WordPress
Как было сказано в самом начале нашего руководства, у вас должен иметься Git репозиторий для вашего WP-сайта. Нам понадобится следующее:
- Ваш проект WordPress должен находиться в ~/Site/wordpress.
- Ваш git репозиторий WordPress должен быть следующим: git@bitbucket.org/yourname/wordpress.
- Вы можете получить доступ к вашему серверу через ssh с аккаунтом yourname на yourdomain.com.
Если ваш исходный код WordPress не содержится в Git репозитории, давайте исправим это прямо сейчас; иначе перейдите к следующему шагу.
$ cd ~/Site/wordpress $ git init $ git remote add origin git@bitbucket.org:kureikain/wordpress.git $ git add . $ git push origin master
Запустите команду ниже, чтобы начать настройку Mina для вашего проекта.
$ mina init
В итоге мы получим папку config с единственным файлом deploy.rb внутри нее.
$ ls config wp-blog-header.php wp-load.php index.php wp-comments-post.php wp-login.php latest.tar.gz wp-config-sample.php wp-mail.php license.txt wp-content wp-settings.php readme.html wp-cron.php wp-signup.php wp-activate.php wp-includes wp-trackback.php wp-admin wp-links-opml.php xmlrpc.php $ ls config deploy.rb
Шаг 2. Настраиваем config/deploy.rb
Теперь давайте откроем config/deploy.rb и определим некоторую конфигурацию:
Файл deploy.rb содержит в себе конфигурацию развертывания, а также набор задач Mina. Каждая задача заключена в блок task :taskname. Внутри каждой задачи мы можем вызывать другую задачу с помощью invoke. Чтобы запустить команду на сервере, достаточно определить ее в queue.
К примеру, задача может иметь следующий вид:
task :down do invoke :maintenance_on invoke :restart queue 'rm -rf /tmp/cache' end
Учитывая это, давайте перейдем к редактированию файла deploy.rb.
Удаляем неиспользуемые строки
Закомментируйте следующие строки, поскольку мы не будем использовать их:
#require 'mina/bundler' #require 'mina/rails'
Настраиваем определение сервера
Стандартный код имеет следующий вид:
set :user, 'username' set :domain, 'foobar.com' set :deploy_to, '/var/www/foobar.com' set :repository, 'git://...' set :branch, 'master'
- domain – это доменное имя вашего WordPress-сайта
- deploy_to – где вы хотите расположить ваш проект WordPress
- repository – адрес вашего Git-репозитория
- branch – ветвь развертывания. Git поддерживает много ветвей, и многие люди обычно используют ветвь deploy для развертывания.
Давайте обновим нашу конфигурацию сервера:
set :domain, 'yourdomain.com' set :deploy_to, '/var/www/yourdomain.com' set :repository, 'https://kureikain@bitbucket.org/kureikain/wordpress.git' set :branch, 'master' set :user, 'your_username' # Username in the server to SSH to.
Убедитесь в том, что вы у вас есть доступ к repository на вашей удаленной машине.
Затем мы обработаем папку wp-content/uploads. Эта папка содержит загруженный пользователями контент. Каждый раз при развертывании эта папка будет отличаться от той, которую мы в настоящее время используем, поскольку недавно развернутый код находится в разных папках внутри releases.
Если мы оставим эту новую папку, то мы потеряем весь старый контент. Также мы должны использовать символьную ссылку, чтобы указать на старый контент, содержащийся в другом месте. После развертывания мы обновим ссылку, чтобы она указывала на корректный контент.
Ищем следующее:
set :shared_paths, ['config/database.yml', 'log']
И меняем на:
set :shared_paths, [ 'wp-content/uploads']
shared_paths – это набор общих ресурсов (файлов/папок) для разных версий. Он может отличаться в пределах того или иного релиза. Как и файлы журнала, контент, загруженный пользователями, должен находиться в shared_paths. Если этого не сделать, мы можем потерять данные с выходом каждого нового релиза.
К примеру, когда пользователь загружает файл, WordPress сохраняет его по адресу /var/www/yourdomain.com/current/wp-content/upload/2014/01/29/picture.png. Однако /var/www/yourdomain.com/current – это символьная ссылка, указывающая на /var/www/yourdomain.com/releases/4/, т.е. на наш текущий релиз. Таким образом, актуальный файл будет располагаться по адресу: /var/www/yourdomain.com/releases/4/wp-content/upload/2014/01/29/picture.png.
Теперь, если вы выпустите новый релиз, current будет указывать на /var/www/yourdomain.com/releases/5. Файл /var/www/yourdomain.com/current/wp-content/upload/2014/01/29/picture.png больше не располагается по данному пути, поскольку /var/www/yourdomain.com/releases/5/wp-content/uploads – новая папка, в которой нет контента.
Мы должны поместить ее в shared_paths, и Mina создаст символьную ссылку, связывающую /www/yourdomain.com/releases/5/wp-content/uploads с www/yourdomain.com/shared/wp-content/uploads.
Настраиваем нашу задачу Setup
Это задача, которую мы будем запускать в самом начале для подготовки нашей серверной среды. Выглядит она в стандартном виде следующим образом:
task :setup => :environment do queue! %[mkdir -p "#{deploy_to}/shared/log"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"] queue! %[mkdir -p "#{deploy_to}/shared/config"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"] queue! %[touch "#{deploy_to}/shared/config/database.yml"] queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."] end
Давайте изменим ее на:
task :setup => :environment do queue! %[mkdir -p "#{deploy_to}/shared/wp-content/uploads"] end
Наша задача setup просто создает папку wp-content/uploads.
Настраиваем задачу Deploy
Стандартная задача Deploy выглядит следующим образом:
task :deploy => :environment do deploy do # Put things that will set up an empty directory into a fully set-up # instance of your project. invoke :'git:clone' invoke :'deploy:link_shared_paths' invoke :'bundle:install' invoke :'rails:db_migrate' invoke :'rails:assets_precompile' to :launch do queue "touch #{deploy_to}/tmp/restart.txt" end end end
Нам не нужно все то, что имеет отношение к Rails. Кроме того, поскольку развертывание WordPress не требует рестарта веб-сервера или PHP-процесса, нам надо лишь вызвать задачи git:clone и deploy:link_shared_paths.
Давайте изменим стандартную задачу на:
task :deploy => :environment do deploy do # Put things that will set up an empty directory into a fully set-up # instance of your project. invoke :'git:clone' invoke :'deploy:link_shared_paths' end end
Настраиваем задачу Rollback
Поскольку Mina не предлагает никакого официального метода для выполнения отката, мы создадим задачу для нашего собственного процесса отката. Задача отката будет удалять текущий релиз и перенаправлять существующую символьную ссылку на предыдущий релиз. Добавьте эту задачу в конец файла deploy.rb:
desc "Rollback to previous verison." task :rollback => :environment do queue %[echo "----> Start to rollback"] queue %[if [ $(ls #{deploy_to}/releases | wc -l) -gt 1 ]; then echo "---->Relink to previos release" && unlink #{deploy_to}/current && ln -s #{deploy_to}/releases/"$(ls #{deploy_to}/releases | tail -2 | head -1)" #{deploy_to}/current && echo "Remove old releases" && rm -rf #{deploy_to}/releases/"$(ls #{deploy_to}/releases | tail -1)" && echo "$(ls #{deploy_to}/releases | tail -1)" > #{deploy_to}/last_version && echo "Done. Rollback to v$(cat #{deploy_to}/last_version)" ; else echo "No more release to rollback" ; fi] end
Код выше выглядит достаточно сложным, однако в действительно он представляет собой короткую версию следующего кода. Я разбил его по строкам и привел аннотацию к каждой команде:
# Проверяем, есть ли у нас более 1 релиза if [ $(ls /var/www/yourdomain.com/releases | wc -l) -gt 1 ] then echo "---->Relink to previos release" # Удаляем текущую символьную ссылку unlink /var/www/yourdomain.com/current # Связываемся с предыдущим релизом ln -s /var/www/yourdomain.com/releases/"$(ls /var/www/yourdomain.com/releases | tail -2 | head -1)" /var/www/yourdomain.com/current echo "Remove old releases" # Удаляем последний релиз, который мы уже откатили rm -rf /var/www/yourdomain.com/releases/"$(ls /var/www/yourdomain.com/releases | tail -1)" # Заносим текущую версию в файл last_version echo "$(ls /var/www/yourdomain.com/releases | tail -1)" > /var/www/yourdomain.com/last_version # Выводим некоторую информацию пользователям echo "Done. Rollback to v$(cat /var/www/yourdomain.com/last_version)" else # Если у нас нет более 1 релиза, то мы не можем сделать откат echo "No more release to rollback" fi
Итак, мы настроили сервер, отредактировали задачи setup, deploy и rollback. Теперь давайте перейдем к использованию Mina.
Развертывание с помощью Mina
В этой части я покажу вам, как запустить Mina для настройки сервера, развертывания сервера и выполнения отката. Mina — это утилита с интерфейсом командной строки. У вас должен быть доступ к терминалу. Каждая задача Mina будет вызываться из терминала.
Шаг 1. Подготовка
Мы будем делать этот шаг только один раз, когда мы подготавливаем развертывание на сервере. Соединяемся через SSH с сервером и создаем директорию deploy_to. В нашем случае она содержится по адресу: /var/www/yourdomain.com.
$ ssh your_name@yourdomain.com # on your remote machine (after you connected via SSH), run this $ sudo mkdir -p /var/www/yourdomain.com $ sudo chown -R your_name /var/www/yourdomain.com
При запуске команды chown мы изменим владельца /var/www/yourdomain.com на your_name. Таким образом, сервер не сможет ничего записать в эту директорию. Наш WordPress-сайт станет более защищенным. Затем на локальной машине запускаем mina setup. Мы увидим следующее:
$ mina setup -----> Setting up /var/www/yourdomain.com total 16 drwxr-xr-x 4 kurei root 4096 Jan 27 22:51 . drwxr-xr-x 3 root root 4096 Jan 27 00:16 .. drwxr-xr-x 2 kurei users 4096 Jan 27 22:51 releases drwxr-xr-x 2 kurei users 4096 Jan 27 22:51 shared -----> Done. Elapsed time: 1.00 seconds
Если вы хотите проверить, что именно создала Mina на вашем сервере, выполните следующий код:
$ cd /var/www/yourdomain.com $ ls releases shared $ ls shared/wp-content uploads
На данном этапе у нас есть почти все, что нам нужно. Помните, что директория загрузок хранит в себе контент, загружаемый пользователями. Веб-сервер должен быть в состоянии вести запись в эту папку. Мы должны определить, какой пользователь вашего Apache/Nginx (или PHP FPM Process в зависимости от настроек вашего сервера) в данный момент используется, после чего изменить владельца папки загрузок на него, чтобы разрешить серверу запись в эту папку. Если вы откроете ваш конфигурационный файл Apache или Nginx, то вы сможете найти пользователя:
# For Apache, open /etc/httpd/conf/httpd.conf User www Group www # For Nginx, open /etc/nginx/nginx.conf user http http; worker_processes 2;
Предположим, что Apache запущен для пользователя www:
ssh your_username@yourdomain.com sudo chown -R www /var/www/yourdomain.com/wp-content/uploads
Шаг 2. Развертывание
Всякий раз, когда мы хотим развернуть код, нам понадобится использовать следующую задачу.
Вот как выглядит сам процесс:
- Обновляем код
- Фиксируем изменения
- Передаем код на Git сервер
Давайте проведем развертывание.
$ mina deploy
Через несколько секунд оно завершится. Вот пример вывода результатов развертывания:
$ mina deploy -----> Creating a temporary build path -----> Fetching new git commits -----> Using git branch 'master' Cloning into '.'... done. -----> Using this git commit kureikain (347d9b3): > Update new config/deploy -----> Symlinking shared paths -----> Build finished -----> Moving build to releases/2 -----> Updating the current symlink -----> Launching -----> Done. Deployed v2 Elapsed time: 1.00 seconds
Шаг 3. Откат
Если релиз содержит критические ошибки или мы просто хотим откатить код к предыдущей версии по каким-либо причинам, то в таком случае можно выполнить следующий код:
$ mina rollback
Вывод будет иметь следующий вид:
----> Start to rollback ----> Relink to previous release Remove old releases Done. Rollback to v2 Connection to axcoto.com closed. Elapsed time: 0.00 seconds
Далее
В следующей части мы посмотрим на WP-CLI. В частности, мы изучим, как использовать WP-CLI, а также как выполнять общие задачи администрирования, такие как обновление WordPress, установка тем, плагинов и т.д. через WP-CLI с помощью задач Mina. Мы также посмотрим на то, как сделать нашу сборку WordPress более безопасной.
Источник: code.tutsplus.com/articles
Чем больше я узнаю нового, чем больше убеждаюсь, что я ничего толком и не знаю ;)
Возьмем наш сайт на заметку, так как темы WordPress и их редактирование в последнее время мне интересны. А здесь есть что почитать.
С уважением, александр Афанасьев.
Немного не понял смысла всего этого.
Деплоймент (deployment, развёртывание) – установка (или обновление) программного обеспечения (в нашем случае – веб-сайта) на целевом оборудовании. Говоря просто – процесс, в результате которого сайт, который работал на машине разработчика, начал работать на специально под него выделенном оборудовании и программном обеспечении.