Pull to refresh

Capistrano и php

Reading time 8 min
Views 31K
image Всем привет. Сегодня я хотел бы ещё раз поговорить о замечательном deploy-ере Capistrano.

Напомню, что Capistrano — это Open Source-ный инструмент для выполнения скриптов на нескольких серверах, который в основном используется для web приложений. Он позволяет автоматизировать процесс развертывания новой версии на одном или нескольких web серверах и включает поддержку таких задач, как например изменение базы данных.

Capistrano написан на Ruby и является «модулем» (или компонентном, не знаю как лучше) фреймворка Ruby on Rails.

Данный топик по большей части является переводом туториала со страницы проекта на github-е с некоторыми дополнениями, изменениями и сокращениями специфичными для php (или для «не RoR»). Здесь не будут рассматриваться вопросы работы с несколькими серверами и базой данных, это всего лишь небольшое пособие для начинающих.

Итак, допустим на нашем локальном компьютере в паке /path/deploy/from находится приложение написанное на языке php. У этого приложения есть git репозиторий находящийся по адресу example.net/project.git с актуальным кодом. Также у нас есть хостинг по адресу example.com с ssh доступом и папкой /path/deploy/to куда мы собираемся залить наши файлы. Мы не хотим постоянно возиться с ftp клиентом и решили потратить несколько часов для того, чтобы разобраться в деплойере capistrano. Давайте приступим.

Установка


Начнем с установки. открываем консоль и вводим:

    $ sudo apt-get install ruby rubygems
    $ sudo gem install capistrano

Поскольку в RoR файлы конфигурации находятся в папке config, capistrano предполагает что у нас она есть. Если её нет, то необходимо её создать:

    $ mkdir /path/deploy/from/config

Если директория в которой вы создаете каталог config, также является корневой директорией сервера, то не забудьте положить в неё файл .htaccess для apache, который запретит просмотр файлов этого каталога, или в конфигурации других web серверов запретить доступ к этому каталогу.

Капификация


Первое что мы должны сделать после установки capistrano это «capify-нуть» наше приложение. «Капификация» — это процесс конфигурации capistrano для развертывания приложения. Он достаточно прост: убедитесь что вы находитесь в корневой директории вашего проекта и введите:

  $ cd /path/deploy/from
  $ capify .

Эта команда создаст два файла:

Capfile — главный файл который нужен capistrano. Подобно тому, как «make» использует «Makefile», а «rake» — «rakefile», Capistrano по умолчанию ищет и загружает «Capfile». Изначально генерируемый Capfile очень прост: все что он делает — загружает «config/deploy.rb»…

config/deploy.rb — файл в котором содержатся «настройки» приложения.
Вообще говоря нам нужно оставить Capfile в покое и вплотную заняться файлом config/deploy.rb. Изначально он будет выглядеть следующим образом:

    set :application, "set your application name here"
    set :repository,  "set your repository location here"

    set :scm, :subversion
    # Or: `accurev`, `bzr`, `vcs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

    role :web, "your web-server here"                          # Your HTTP server, Apache/etc
    role :app, "your app-server here"                          # This may be the same as your `Web` server
    role :db,  "your primary db-server here", :primary => true # This is where Rails migrations will run
    role :db,  "your slave db-server here"

    # If you are using Passenger mod_rails uncomment this:
    # if you're still using the script/reapear helper you will need
    # these http://github.com/rails/irs_process_scripts

    # namespace :deploy do
    #   task :start do ; end
    #   task :stop do ; end
    #   task :restart, :roles => :app, :except => { :no_release => true } do
    #     run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
    #   end
    # end

Нас данный конфиг не устраивает, поэтому мы его перепишем.

Конфигурация


Для начала приложению нужно дать имя. Назовем его «my php application»:

    set :application, "my php application"

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

    set :repository, "ssh://git@example.net/project.git"

В случае, если url для доступа к репозиторию с локальной машины и с сервера различаются (например снаружи ssh имеет другой порт), нужно указать оба адреса:

    set :repository, "ssh://git@example.com:22100/project.git"
    set :local_repository, "ssh://git@example:project.git"

Поскольку мы используем систему контроля версий отличную от Subversion, которая назначена по-умолчанию, необходимо ввести следующую строку:

    set :scm, :git

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

Структура директорий Capistrano


Проект успешно развернутый с Capistrano будет иметь структуру похожую на приведенную ниже ( где [deploy_to] — это каталог куда мы хотим развернуть проект):

    [deploy_to]
    [deploy_to]/releases
    [deploy_to]/releases/20080819001122
    [deploy_to]/releases/...
    [deploy_to]/shared
    [deploy_to]/shared/log
    [deploy_to]/shared/pids
    [deploy_to]/shared/system
    [deploy_to]/current -> [deploy_to]/releases/20100819001122

Каждый раз когда вы будете разворачивать проект в папке «releases» будет создаваться новая директория, в которую будет копироваться его последняя версия. После этого символическая ссылка «current» обновиться и будет указывать на новую директорию. Если структура вашего приложения похожа на структуру приложения в RoR или другого приложения, где корневая директория проекта и web директория отличаются, необходимо убедиться, что сервер настроен именно на эту директорию (в RoR это [deploy_to]/current/public).

Вернемся к конфигурации


Итак нам нужно указать куда на сервере мы хотим развернуть приложение. По умочанию это папка "/u/apps/#{application}" (где #{application} это имя которое мы указали выше в переменной ":application"). Поскольку наша директория отличается от директории по умолчанию, укажем её явно:

    set :deploy_to "/path/deploy/to"

Теперь нужно указать где находятся наши сервера. Вообще говоря Capistrano по умолчанию использует три роли для развертывания Rails приложений: web, app и db. Подробное описание этих ролей можно найти в оригинальной статье. Поскольку у нас только один сервер и функциональность ролей нам не нужна, можно использовать следующий синтаксис:

    server "example.com"

Дополнительные настройки


Теперь посмотрим на некоторые дополнительные переменные, которые могут вам пригодиться.
  • set :user, "foo"
    Указывает имя пользователя для ssh или ftp доступа, если вы подключаетесь к серверу под именем отличным от имени под которым вы залогинены на ваш локальный компьютер.
  • set :password, "password"
    Устанавливает пароль для подключения к серверу. Не рекомендуется.
  • set :scm_username, "foo"
    Указывает имя пользователя, для доступа к репозиторию, если вы подключаетесь к нему под именем отличным от имени под которым вы залогинены на локальном компьютере. Не все vcs поддерживают этот параметр. Если ваша система контроля версий не поддерживает, то необходимо указать это имя в параметре ":repository" так как это сделано выше.
  • set :use_sudo, false
    Назначено по умолчанию. Если вы хотите дать Capistrano sudo доступ для выполнения каких-либо операций, поставьте true
  • set :via, "scp"
    Устанавливает протокол, по которому будут копироваться данные.
  • set :branch, "master"
    Указывает ветку проекта из которой будет браться код.
  • set :deploy_via, :remote_cache
    Сохраняет кэш последней версии на сервере и при новом deploy-е скачивает только обновления. Наверняка вы захотите установить этот параметр.

Команды Capistrano


После того, как мы написали свой рецепт, можно задать Capistrano несколько вопросов:
  • $ cap -h
    Выведет список возможных опций.
  • $ cap -H
    Выведет список всех опций с подробным описанием каждой из них.
  • $ cap -T
    Выведет список всех task-ов (или задач) с кратким описанием каждого из них.
  • $ cap -e deploy:web_disable
    Покажет подробную информацию о конкретной задаче.

Setup


Попробуем воспользоваться капистрано для взаимодействия с сервером. Для начала нам нужно создать базовую структуру дерикторий:

    $ cap deploy:setup

При запуске этой команды капистрано подключится к серверу и выполнит серию команд «mkdir». Заранее убедитесь, что у вас все в порядке с правами доступа на директорию в которую вы разворачиваете проект.

Проверка зависимостей


Теперь, когда у нас есть каркас, мы можем спросить у капистрано, есть ли у нас все, что нужно для продолжения разворачивания проекта:

    $ cap deploy:check

Капистрано проверит локальный и удаленный сервера на наличие необходимых вещей. Если чего-то не хватает, вы получите сообщение об ошибке, например, что у вас нет прав на какую-либо операцию, что на сервере не установлен git и т.п.

Отправка кода на сервер


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

    $ cap deploy:update

Эта команда скачивает код из репозитория на сервер и обновляет симлинк «current».

Deploy


Наконец мы подобрались непосредственно к деплою. В действительности команда deploy всего лишь обертка, над несколькими другими командами, которая просто выполняет их последовательно. Как это происходит можно посмотреть на следующей схеме:

image

Поскольку команды deploy:update и deploy:finalize_update специфичны для приложений написаных на ruby on rails, нам нужно переопределить их. Помимо этих двух команд рекомендую переопределить команды deploy:start и deploy:stop, поскольку они тоже заточены для RoR и в случае их запуска могут привести к ошибке (на самом деле есть и другие специфичные команды, но мы переопределяем только самые основные):

  namespace :deploy do
    task :start do
    end
    task :stop do
    end
    task :restart do
    end
    task :finalize_update do
    end
  end

В принципе, теперь команда deploy ничем не отличается от команды deploy:update, но вы можете изменить это, прописав специфичные для вашего приложения действия в необходимых task-ах.

Теперь деплойер готов к работе. Для тех, кому описанных возможностей не достаточно, рекомендую ознакомиться с разделом DSL Documentation на страничке wiki проекта и внимательно почитать вывод команды «cap -e» для каждого стандартного task-а. Прочитав их вы без труда сможете писать конструкции например такого вида:

  after "deploy", "deploy:cleanup"

Если добавить такую строку в рецепт, то после каждого деплоя автоматически будет выполняться чистка директории /path/deploy/to/releases (по умолчанию удаляются все релизы, кроме 5 последних).

Multistage


У себя в разработке мы также используем расширение capistrano-ext, которое позволяет делать так называемый multistage. Предположим у вас есть тестовый и рабочий сервера. Вы можете написать отдельный конфиг для каждого из них и выполнять deploy только для нужного сервера.
Для установки расширения в командной строке наберите:

    $ gem install capistrano-ext

Далее в папке /path/deploy/from/config/ создаем новый каталог:

    $ mkdir /path/deploy/from/config/deploy

и помещаем в него свои рецепты: например production.rb и staging.rb. Всё что нам нужно для конфигурации — это написать в файл /path/deploy/from/config/deploy.rb две строки:

    set :stages, %w(staging production)
    require 'capistrano/ext/multistage'

Теперь вы можете выполнять деплой с помощью команд «cap production deploy» и «cap staging deploy». Если вам нужен ещё один конфиг, просто положите его в каталог deploy и добавьте его имя в переменную :stages:

    set :stages, %w(staging production develop)

Если вы попробуете просто выполнить команду «cap deploy», capistrano предупредит, что необходимо указать рецепт по которому нужно выполнять деплой и прервет работу. Для того, чтобы использовать какой-либо рецепт по-умочанию, можно определить переменную «default_stage»:

    set :stages, %w(staging production develop)
    set :default_stage, "develop"
    require 'capistrano/ext/multistage'

Теперь команда «cap deploy» будет эквивалентна команде «cap develop deploy».

На этом всё, спасибо за внимание.

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

оригинальный туториал
статья о multistage
help.github.com/capistrano
Tags:
Hubs:
+38
Comments 15
Comments Comments 15

Articles