Рецепт полностью рабочий и протестирован на Windows 7 c использованием denwer. Рецепт предполагает, что у Вас есть базовые навыки работы с Git. Как основной репозиторий в рецепте используется github.com.
Внимание! На момент написания статьи уже был выпущен Capistrano 3, но в рецепте будет использоваться Capistrano 2.
Установка.
Установите последнюю версию 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/
Комментарии
Супер, а что по поводу БД. Как можно автоматически изменять структуру БД? Есть какие то примеры решения этой проблемы?
ОтветитьЕсли Вы используете Yii, то можете почитать статью: Yii Framework. Миграции
ОтветитьСпасибо, лучше поздно чем никогда), Yii не использую, но подумываю над этим.
ОтветитьОтличная статья, спасибо автору!
ОтветитьА я через хуки git развертываю https://intsystem.org/server/gitolite-avtodeploj-dev-ili-kak-ya-rabotayu-s-git/ ничуть не хуже же, разве нет? Хотя, чесно сказать, это все потому что я никак не осилю капистрано(
ОтветитьДа, так тоже можно делать, но мы остановились на варианте с capistrano, хотя и так тоже пробовали. Уже и не помню почему отказались :)
ОтветитьСпасибо, классная статья!!! Ставил на убунту, с первого раза вываливала ошибки, что не может создать папки, оказалось, что capistrano работает по ssh, а у меня на серваке он не было поднят. Расшарил и все заработало!
ОтветитьАвтору респект, спас))
ОтветитьОбновил случайно capistrano до 3.5
ОтветитьДеплой перестал работать, пришлось вернутся на версию 2.15.5
Удаляю капистрано 3.5:
biperch@biperch-Work:~$ sudo gem uninstall capistrano
Select gem to uninstall:
1. capistrano-2.15.5
2. capistrano-2.15.7
3. capistrano-3.5.0
4. All versions
> 3
You have requested to uninstall the gem:
capistrano-3.5.0
capistrano-maintenance-1.0.0 depends on capistrano (>= 3.0)
If you remove this gem, these dependencies will not be met.
Continue with Uninstall? [yN] y
Successfully uninstalled capistrano-3.5.0
Теперь устанавливаем version 2.15.5:
biperch@biperch-Work:~$ sudo gem install capistrano --version 2.15.5
Successfully installed capistrano-2.15.5
Parsing documentation for capistrano-2.15.5
Done installing documentation for capistrano after 1 seconds
1 gem installed
Всем удачи!!))
Отличная статья. Особенно порадовало то, что можно сделать мультидоменный деплой. Супер!
ОтветитьПри подключении к серверу выдало ошибку:
Ответить[deploy:update_code] exception while rolling back: Capistrano::ConnectionError, connection failed for: my-site.com (ArgumentError: Value(s) have been set to nil: password)
connection failed for: my-site.com (ArgumentError: Value(s) have been set to nil: password)
Решение:
Запускаем gem net-ssh, у меня ее не было
Устанавливаем
sudo gem install net-ssh --version 3.1.1
Если есть, то откатываем до 3-й версии
sudo gem uninstall net-ssh
Выбираем версию для удаления (в нашем случае 4-я версия)
Запускаем deploy и радуемся
Спасибо помогло, для windows выполнил команду:
Ответитьgem install net-ssh --version 3.1.1
gem естественно есть в переменных среды
Подскажите, при высове команды cap develop deploy получаю такую ошибку:
Ответить[mydomain.name] executing command
*** [err :: mydomain.name] find: `/var/www/username/data/deployCat/dev/rel
eases/20161010094843/public/images': No such file or directory
*** [err :: mydomain.name] find: `/var/www/username/data/deployCat/dev/rel
eases/20161010094843/public/stylesheets': No such file or directory
*** [err :: mydomain.name] find: `/var/www/username/data/deployCat/dev/rel
eases/20161010094843/public/javascripts': No such file or directory
Попробуйте сделать следующее:
Ответить1) Удалите все из каталога /var/www/username/data/deployCat/dev/
2) Выполните команду: cap develop deploy:setup
3) Выполните команду: cap develop deploy
Спасибо, помогло
ОтветитьЕще для корректной работы у пользователя должен быть доступ к SSH выполнения команд переноса файлов.
ОтветитьДобрый вечер. Подскажите пожалуйста, после выполнения команды:
Получаю ошибку:
Ответить
Здравствуйте.
ОтветитьПохоже, что у вас нет папки /var/www/username/data/deployTest/dev/releases/ или не подготовлена структура для решения этой ошибки (failed: "sh -c 'rsync -lrpt --exclude=\".git\...) попробуйте выполнить следующие команды по очереди:
Спасибо за быстрый ответ, помогло. Из-за спешки получилось дольше. Пропустил эти команды, думал и так сойдет. Получается они создают структуру папок. Еще раз спасибо, после выполнения все заработало
Ответить