Статьи

Развертывание проектов PHP с помощью Webistrano

В моей предыдущей статье я говорил об установке Webistrano. Теперь давайте начнем его использовать.

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

Упомянутая ниже настройка описывает только развертывание в тестовом проекте. Развертывание на производстве будет аналогичным, и к концу статьи вы должны понимать, каких отличий он потребует. Если у вас есть какие-либо вопросы или предложения, напишите мне по электронной почте или оставьте комментарий ниже.

Создание нового проекта

Начнем с создания нового проекта. Поскольку он будет основан на PHP, тип проекта, который мы хотим выбрать, является чистым типом . Введите свое имя и описание, и все готово.

Webistrano позволяет вам настроить параметры конфигурации для каждого из ваших проектов, например, путь svn, путь развертывания и т. Д. Вы можете просмотреть полный список параметров конфигурации на вики-страницах Webistrano github .

Посмотрите на проект, который вы создали, вы увидите базовую конфигурацию для всех переменных:

Конфигурация проекта

Вот где происходит волшебство.

Поскольку все наши проекты настраиваются в основном одинаково, я хотел бы убедиться, что по умолчанию в каждом новом проекте используется один и тот же пользователь SVN , ** метод развертывания ** и т. Д. Это сведет к минимуму любые возможные ошибки и скорость до процесса. Чтобы это настроить, нам нужно погрузиться в кодовую базу Webistrano.

Файл с настройками по умолчанию называется lib/webistrano/template/base.rb

$ vim lib/webistrano/template/base.rb

Теперь отредактируйте ваши настройки в соответствии с вашими потребностями:

:deploy_via => ':export',
:scm_username => 'webistrano',
:scm_password => 'xyz',
:user => 'webistrano',
:password => 'xyzx',
:deploy_to => '/var/www/vhosts/project.com',

Для того, чтобы этот конфигурационный файл начал работать, вам придется перезапустить вашу дворнягу

$ su - webistrano
$ mongrel_rails stop
$ mongrel_rails start -e production -d -p 3000

Все эти настройки могут быть перезаписаны на каждом из этапов, если мы захотим позже — через пользовательский интерфейс Webistrano .

Создание этапов

Следующим шагом является создание этапов для проекта. Этапы должны отражать вашу среду . Для моей цели я собираюсь создать только тестовый этап.

Настройка стадии тестирования

Добавить свой первый этап действительно просто!

Каждому этапу нужен хост или группа хостов, на которых он будет развернут. Для этой статьи я просто собираюсь использовать локальный сервер.

Нажмите на хосты и добавьте новый IP-адрес хоста или DNS — 127.0.0.1

Теперь вернитесь к тестовой стадии вашего проекта и добавьте новый хост

Добавление нового хоста для сцены

Возможно, вы захотите добавить хосты в качестве своих доменов, чтобы избежать путаницы в будущем

И последнее, прежде чем мы сможем начать развертывание, это изменить путь SVN. Для этого мы перезапишем конфигурацию Webistrano по умолчанию с использованием конкретной конфигурации Stage . Вы можете переписать все настройки здесь, а также создавать новые. Для нашей цели мы просто собираемся создать хранилище

Этап конкретной конфигурации

Вы можете настроить практически все!

На всех этапах тестирования я разрешаю пользователям вводить свой собственный путь (скорее всего, это магистральный канал), но для производства я уверен, что он будет заполнен при развертывании. Production всегда будет развертывать стабильные теги, поэтому я хочу, чтобы пользователи были уверены, что они развернули правильный тег.

развертывание

Теперь вы готовы к базовому развертыванию. Capistrano извлекает / экспортирует код из вашего хранилища кода и помещает его в папку с именем revisions по указанному вами пути. Каждое развертывание будет иметь свою собственную папку с именем, являющимся датой и временем развертывания. Capistrano удалит старые ревизии автоматически.

В конце каждого развертывания Capistrano создает символическую ссылку на последнюю ревизию в виде папки с именем current. Это означает, что отменить ваши изменения (если не происходит изменений в базе данных) так же просто, как уничтожить ссылку и перейти к предыдущей ревизии. Таким образом, вам не нужно беспокоиться о долгих проверках, все версии приложения доступны под рукой.

С этой простой настройкой вы сможете развернуть приложения одним щелчком мыши. Но если этого недостаточно, и вы хотите автоматизировать определенные процессы, читайте о Receipies

Рецепты

Самый мощный инструмент развертывания Capistrano / Webistrano — это рецепты. Мы используем Plesk на всех наших серверах, поэтому пример рецепта, о котором я собираюсь рассказать, учитывает его.

Вот пустой шаблон для нового рецепта

namespace :deploy do
  do smth...
end

Capistrano использует пространства имен в качестве инструмента, который позволяет авторам отличать свои задачи от других задач с тем же именем. Как упомянуто в документации Capistrano

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

namespace :deploy do
  namespace :web do
    task :enable, :roles => :web do
      # ...
    end
  end
end

Это послужит основой для нашего рецепта развертывания.

Что касается автоматизации, есть несколько вещей, которые я хотел бы сделать, каждый раз, когда я делаю развертывание:

Установка правильных разрешений и очистка

Если вы решили получить свой код через svn checkout, ваш код на сервере будет полон .svnпапок. Это может вызвать угрозу безопасности, и вы, вероятно, захотите избавиться от них. Чтобы сделать это, запустите задачу finalize_update в своем рецепте и добавьте строку ниже:

namespace :deploy do
  task :finalize_update do
    run "rm -rf 'find #{latest_release} -type d -name .svn'"
  end
end

Теперь вы видите, что можете использовать runлюбые команды bash, которые вам нужны. Если вам нужно запустить их как root, используйте sudoвместо этого.

Еще несколько вещей, которые я хотел бы добавить, — убедиться, что папка кеша имеет права rw, так как там создаются наши умные шаблоны:

sudo "chmod -R 777 #{latest_release}/cache"

Обновление БД

Как для тестовой, так и для реальной среды мы можем захотеть запускать сценарии db автоматически. Разработчики будут обязаны поддерживать сценарии обновления базы данных. Например, при первом создании сайта сценарий будет содержать CREATE DATABASEоператор, но позже он будет содержать только ОБНОВЛЕНИЯ, это будет означать, что все изменения в БД версионированы.

Для целей рецепта развертывания я добавляю функцию, которая проверяет, существует ли удаленный файл, и возвращает true или false.

def remote\_file\_exists?(full_path)
  'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
end

Теперь для сценариев БД я собираюсь создать папку с именем install в корне приложения. Если разработчик создал файл db.sql в нем, я хочу, чтобы mysql запустил его

install_db_path = "#{latest_release}/install/db.sql"
if remote_file_exists?(install_db_path)
  run "mysql -u #{mysql_user} -p#{mysql_password} -h localhost #{mysql_database} < #{latest_release}/install/db.sql"
end

Чтобы использовать этот сценарий, я буду создавать mysql_user, mysql_databaseи mysql_passwordв моей стадии конфигурации, и заполнить его с правильными значениями.

Управление активами

Поскольку код извлекается / экспортируется при каждом развертывании, вы хотите, чтобы загруженные пользователем ресурсы оставались неизменными и имели ссылки между ревизиями. Capistrano использует переменную shared_pathдля таких случаев. В нашем случае мы храним все скрытые ресурсы в корне приложения в папке ресурсов, а общедоступные — в wwwroot / resources, следовательно, развертывание:

run "ln -nfs #{shared_path}/assets #{latest_release}/resources/"
run "ln -nfs #{shared_path}/assets/wwwroot #{latest_release}/wwwroot/resources/"

В тестовой среде я также хочу запустить скрипт rsync. Я удалю это для рецепта живой среды:

install_rsync_path = "#{latest_release}/install/rsync.sh"
if remote_file_exists?(install_rsync_path)
  run install_rsync_path
end

library.sh читает файлы conf для нашей платформы и ищет определения библиотек, т.е.

# !/bin/bash
# Migrating all the media files over to the current directories
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -n "$1" ]; then
  username=`echo $1 | tr '[:upper:]' '[:lower:]'`
else
  username=`whoami`
fi

echo "Linking Framework from your ini file"
framework_path=$(sed -n 's/.*framework_dir *= *([^ ]*.*)/\1/p' < $DIR/../application/conf/$username.ini | tr -d '"')
echo "You chose Framework: ln -s ${framework_path} $DIR/../lib/Framework"
ln -s ${framework_path} ${DIR}/../lib/Framework

echo "Linking Smarty from your ini file"
smarty_path=$(sed -n 's/.*smarty_dir *= *([^ ]*.*)/\1/p' < $DIR/../application/conf/$username.ini | tr -d '"')
echo "You chose Smarty: ln -s ${smarty_path} $DIR/../lib/Smarty"
ln -s ${smarty_path} ${DIR}/../lib/Smarty

с staging.conf, содержащим:

[lib]
vanilla_dir   = "/var/www/libs/Vanilla/trunk"
smarty_dir    = "/var/www/libs/Smarty/3.0.8/"

Вы можете изменить шаблон sed в соответствии с вашими потребностями.

Исправление проблемы с разрешениями Plesk

Webistrano настроен для входа на каждый из серверов как пользователь с именем webistrano. Это вызовет проблемы с любыми установками Plesk , поскольку Plesk не позволяет никому, кроме владельцев, записывать в httpdocs. Эту проблему можно решить, если добавить Webistrano в группу Plesk psaservи изменить разрешения httpdocs до начала развертывания. Вот как это сделать:

before "deploy", :change_permissions
before "deploy:migrations", :change_permissions
desc "Change permissions"
task :change_permissions, :roles => [ :web ] do
  sudo "chmod g+w #{deploy_to}"
end

Вывод

Это всего лишь небольшой тизер того, что Webistrano может сделать для вашего развертывания. Вы можете использовать его, чтобы минимизировать ваши файлы JS и CSS, перезаписать конфигурации вашей среды переменными, указанными в ваших конфигурациях webistrano, развертывания на нескольких хостах. Мир это твоя устрица. Пожалуйста, найдите полный рецепт ниже:

def remote_file_exists?(full_path)
  'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
end

namespace :deploy do
  task :finalize_update do
    run "rm -rf `find #{latest_release} -type d -name .svn`"
    sudo "chmod -R 777 #{latest_release}/cache"
    run "ln -nfs #{shared_path}/assets #{latest_release}/resources/"
    run "ln -nfs #{shared_path}/assets/wwwroot #{latest\_release}/wwwroot/resources/"
    install_db_path = "#{latest_release}/install/db.sql"

    if remote_file_exists?(install_db_path)
        run "mysql -u #{mysql_user} -p#{mysql_password} -h localhost #{mysql_database} < #{latest_release}/install/db.sql"
    end

    install_rsync_path = "#{latest_release}/install/rsync.sh"
    if remote_file_exists?(install_rsync_path)
        run install_rsync_path
    end

    # linking libraries
    install_libraries_path = "#{latest_release}/install/libraries.sh"
    if remote_file_exists?(install_libraries_path)
        run "#{latest_release}/install/libraries.sh staging"
    end
  end

  task :apache_graceful do
    if( restart_apache )
        logger.info "Graceful restart apache"
        sudo "/etc/init.d/httpd graceful"
    end
  end

end

after "deploy:update", "deploy:cleanup"
before "deploy", :change_permissions
before "deploy:migrations", :change_permissions

desc "Change permissions"
task :change_permissions, :roles => [ :web ] do
    sudo "chmod g+w #{deploy_to}"
end