Рецепт полностью рабочий и протестирован на Windows 7 c использованием denwer. Рецепт предполагает, что у Вас есть базовые навыки работы с Git. Как основной репозиторий в рецепте используется github.com.


Установка.

Установите последнюю версию Ruby. Скачать установщик Ruby можно по ссылке: http://rubyinstaller.org/downloads/. После установки обязательно убедитесь, что в Path попал путь к Ruby (Свойства "Мой компьютер" -> Дополнительные параметры системы -> Параметры среды -> Системные параметры -> C:\Ruby200-x64\bin;........).

Установите RubyGems. Скачать его можно по ссылке: https://rubygems.org/pages/download. Распакуйте архив с RubyGems в удобное для Вас место. Откройте командную строку и перейдите к директории в которую распаковали RubyGems. Например, мы распаковали RubyGems в папку с:/rubygems-2.4.5:

cd c:/
cd rubygems-2.4.5

И выполните команду установки:

ruby setup.rb install
gem update --system

Теперь перейдем к установке Сapistrano:

gem install capistrano --version 2.15.5

Очередь установки Capifony:

gem install capifony

Установим capistrano_rsync_with_remote_cache для удобной работы с scm (subversion, git):

gem install capistrano_rsync_with_remote_cache

Capistrano предполагает, что у нас в корне проекта уже есть папка config, так как в Ruby файлы конфигурации находятся именно в этой папке, но у нас ее нет. Необходимо создать ее, например наше приложение находится в папке d:/web/home/deploy.test.local/www.

d:
cd /web/home/deploy.test.local/www
mkdir config

Создать папку config можно с помощью проводника Windows, без использования консоли.

Если папка в которой был создан каталог config является корневой папкой для сервера, то необходимо создать в ней файл .htaccess для Apache, который будет запрещать просмотр содержимого каталога. Пример файл .htaccess:

Options All -Indexes

Капификация

Первое что нам необходимо сделать после установки Capistrano - это выполнить команду capify . для нашего приложения. Команда выполнит настройку конфигураций Сapistrano для дальнейшего развертывания приложения на сервере. Перед выполнением команды необходимо убедиться, что Вы находитесь в корневой папке Вашего приложения и введите команду в консоле:

capify .

Команда capify . создаст два файла:

Capfile - главный файл который нужен Capistrano. По умолчанию Capistrano ищет и загружает именно Capfile. В своем исходном виде генерируемый Capfile очень прост: он загружает файл config/deploy.rb. Больше нам о нем знать ничего не нужно, на этом этапе оставим его и перейдем ко второму файлу.

config/deploy.rb - файл конфигурации деплоя нашего приложения.

В первоначальном виде файл 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 app":

set :application, "my php app"

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

set :repository,  "https://userName:userPassword@github.com/userName/repoName.git"

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

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

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

Так как мы используем Git (по-умолчанию это Subversion), необходимо добавить следующую строку:

set :scm, :git

Теперь укажем Capistrano папку на сервере в которую необходимо развернуть наше приложение. Рассмотрим структуру файлов и папок которую Capistrano использует для публикации приложений для более подробного понимания.

Успешно развернутое приложение с Capistrano будет иметь следующую структуру (где deployTo - это каталог в который мы будем разворачивать приложение):

deployTo
deployTo/releases
deployTo/releases/12345678901234
deployTo/releases/...
deployTo/shared
deployTo/shared/log
deployTo/shared/pids
deployTo/shared/system
deployTo/current -> [deploy_to]/releases/12345678901234

Каждый раз при развертывании проекта, будет создана новая директория с последней версией приложения в папке releases. После чего символическая ссылка current будет указывать на только что созданную директорию с актуальной версией приложения. Если архитектура Вашего приложения такая же как архитектура приложений в Ruby on Rails, где web директория и корневая папка проекта различны, необходимо удостовериться, что сервер настроен именно на эту директорию (в Ruby on Rails это deployTo/current/public).

Вернемся к нашему конфиг файлу. Укажем папку публикации нашего приложения на сервере. По умолчанию это папка /u/apps/#{application} (где #{application} - это имя нашего приложения, которое указано в переменной :application). У нас директория отличается от заданной по умолчанию директории, поэтому укажем её явно, например будем разворачивать приложение в папку /var/www/userSrvName/data/deployTest:

set :deploy_to, "/var/www/userSrvName/data/deployTest"

Укажем имя пользователя для ssh или ftp доступа.

set :user, "userName"

Укажем количество хранимых релизов на сервере (количество хранимых копий в папке releases):

set :keep_releases, 3

Укажем имя пользователя для доступа к репозиторию. Некоторые vcs не поддерживают данный параметр. Если система контроля версий которую используете Вы не поддерживает этот параметр, то нужно указать имя пользователя в параметре :repository так как это реализовано выше.

set :scm_username, "userName"

Опция ниже по существу сохраняет клон вашего приложения на сервере, а затем просто затягивает только изменения.

set :repository_cache, "git_cache"

Если Вам необходимо дать Capistrano использовать sudo доступ для выполнения операций, то поставьте true:

set :use_sudo, false

Укажем протокол копирования данных:

set :via, "scp"

Укажем ветку проекта из которой будет браться код для деплоя приложения.

set :branch, "master"

Укажем что необходимо сохранить на сервере кэш последней версии и при новом деплое, скачивать только обновления:

set :deploy_via, :remote_cache

Запретим копировать указанные файлы или каталоги:

set :copy_exclude, [".git"]

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

role :web, "example.com" 

Настройки ssh. Вы можете сами настроить соединение по ssh, но в данном рецепте мы его отключим:

set :ssh_options, {
    config: false
    #Other options...
}

Пробуем

Попробуем взаимодействие Capistrano с нашим сервером. Для начала создадим базовую структуру папок выполнив команду (мы должны находиться в корне проекта, если ничего не меняли и не закрывали, то там и находимся):

cap deploy:setup

При выполнении cap deploy:setup команды Capistrano подключится к нашему серверу и последовательно выполнит ряд команд mkdir для создания базовой структуры (заранее убедитесь,что у директории в которую вы собираетесь разворачивать приложение все в порядке с правами доступа).

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

cap deploy:check

Команда cap deploy:check проверит готовность локального и удаленного серверов и выведет нам соответствующее сообщение. Если что-то пойдет не так, то Вы получите сообщение об ошибке (например, что у вас нет прав на выполнение записи в папку или т.п..).

Можно попробовать отправить код на сервер (Код уже должен быть в указанном выше репозитории и в указанной выше ветке, соответственно ветка должна быть создана). Это будет не полноценный деплой, а просто тест загрузки кода на сервер, убедимся, что все впорядке:

cap deploy:update

Команда cap deploy:update загружает код из репозитория на сервер и устанавливает символическую ссылку current на новую папку.


Deploy приложения.

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

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

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

Теперь автоматизируем наш деплой приложения:

after "deploy:update", "deploy:moveToSrv"
namespace :deploy do
    task :moveToSrv do 
        run "cp -r /var/www/userSrvName/data/deployTest/current/* /var/www/userSrvName/data/deployTest/current/.[a-zA-Z0-9]* /var/www/userSrvName/data/www/example.com/";
    end
    task :start do ; end
    task :stop do ; end      
    task :restart do ; end      
end

Здесь мы указали, что после команды update нужно вызвать команду moveToSrv, которая копирует файлы из текущей версии релиза непосредственно в папку сайта. Вы сами можете добавить необходимые команды исходя из данного примера.

Итого конечный файл имеет вид:

set :application, "my php app"
set :repository,  "https://userName:userPassword@github.com/userName/repoName.git"
set :scm, :git
set :deploy_to, "/var/www/userSrvName/data/deployTest"
set :user, "userName"
set :keep_releases, 3
set :scm_username, "userName"
set :repository_cache, "git_cache"
set :use_sudo, false
set :via, "scp"
set :branch, "master"
set :deploy_via, :remote_cache
#set :copy_exclude, [".git", ".gitignore", "log", "public", "REVISION"]
set :copy_exclude, [".git"]

role :web, "example.com"                          # Your HTTP server, Apache/etc

after "deploy:update", "deploy:moveToSrv"

namespace :deploy do
    task :moveToSrv do 
        run "cp -r /var/www/userSrvName/data/deployTest/current/* /var/www/userSrvName/data/deployTest/current/.[a-zA-Z0-9]* /var/www/userSrvName/data/www/example.com/";
    end
    task :start do ; end
    task :stop do ; end      
    task :restart do ; end   
end

set :ssh_options, {
    config: false
}

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

cap deploy:update

или

cap deploy

Все, наше приложение из указанного репозитория и указанной ветки переехало на наш сайт (example.com), теперь нам не надо больше копировать файлы по ftp. Есть одна проблема данного рецепта, он не развертывает изменения в структуре БД, но при желании и это можно решить.


Деплой приложения на тестовый сервер/домен (multistage)

Часто в разработке необходимо перед деплоем приложения протестировать его на тестовом сервере или поддомене. Для этого используется расширение capistrano-ext, с помощью которого появляется возможность использовать отдельные конфиг файлы и выполнять деплой для нужного сервера из определенной ветки.

Что бы установить расширение нужно в консоле ввести команду:

gem install capistrano-ext

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

mkdir deploy

Папку deploy можно создать из проводника Windows, без использования консоли.

Теперь помещаем в папку deploy свои конфиг файлы, например production.rb (загрузка кода из ветки мастер на "боевой" сервер) и develop.rb (загрузка кода из ветки develop на тестовый сервер), настраиваем их согласно инструкций выше. И пропишем в файл /path/deploy/from/config/deploy.rb две строки:

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

Осталось создать базовую структуру для новых конфиг файлов:

cap production deploy:setup

и

cap develop deploy:setup

Теперь мы можем выполнять деплой приложения с помощью команд cap production deploy (на "боевой" сервер) и cap develop deploy (на тестовый сервер). Если у Вас есть необходимость использовать ещё один конфиг, просто создайте его в каталоге deploy, настройте и добавьте его имя в переменную :stages:

set :stages, %w(test production develop)

Теперь при выполнении команды cap deploy, Capistrano предупредит, что нужно задать рецепт с помощью которого будет выполнятся деплой приложения и остановит выполнение. Для избежания таких ситуаций можно задать рецепт деплоя по умолчанию, для этого необходимо задать переменную default_stage, например по умолчанию будет выполняться деплой приложения на тестовый сервер из ветки develop:

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

После этих изменения, команда cap deploy будет равнозначна команде cap develop deploy


Дополнительно

Команды Capistrano. Возможно Вам пригодятся несколько следующих команд:

Вывести список возможных опций.

cap -h

Вывести список всех опций и подробное описание к каждой из них.

cap -H

Вывести список всех задач и краткое описанием к каждой из них.

cap -T

Вывести подробную информацию о заданной задаче.

cap -e deploy:moveToSrv

Возможные ошибки и способы их решения.

При вызове команды gem install capistrano-ext или gem install capistrano --version 2.15.5 появляется ошибка:

ERROR:  Could not find a valid gem 'capistrano-ext' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect retur
ned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://rubygems.org/latest_specs.4.8.gz)

Выполните команду в консоле:

gem sources --add http://rubygems.org/