При разработке, и тем более поддержке действующего проекта на Symfony 2 одной из задач, которые приходится постоянно делать, это выгрузка изменений на сервер: рабочей или тестовой. Но так как программисты народ достаточно ленивый, чтобы автоматизировать повторяющиеся монотонные задачи, есть достаточное количество инструментов для облегчения данного процесса. Для Symfony2 мы используем Сapifony. Он основан на Capistrano но оптимизирован для Symfony.
Установка
Тут все просто, делается командой $ gem install capifony
. Если у вас не установлен RubyGem, тогда вам необходимо будет обратится к официальной документации.
Далее переходим к проекту который нам необходимо обновлять на серверах, в нашем случае это будет блог $ cd ~/Sites/blog
. Если вы думаете что всегда будет один сервер, не будет к примеру демо сервера или тестового, тогда можно инициализировать Сapifony командой $ capifony .
Т.к. такой случай бывает редко, мы будем использовать несколько серверов и создадим файл $ vim Capfile
с данным содержимым:
load 'deploy' if respond_to?(:namespace) # cap2 differentiator require 'capifony_symfony2' load 'app/config/deploy/deploy'
В данном случае нас интересует только последняя строчка она указывает на файл конфигурации для загрузки на сервера.
Настройка базовой конфигурации
Создаем файл $ vim app/config/deploy/deploy.rb
, все таки не забываем что мы работаем с Ruby, с таким содержимым:
set :stages, %w(prod develop staging) set :default_stage, "develop" set :stage_dir, "app/config/deploy" require 'capistrano/ext/multistage' ssh_options[:forward_agent] = true set :application, "4devs" set :domain, "#{application}.io" # set :deploy_to, "/var/www/#{domain}" set :app_path, "app" set :bin_path, "bin" set :var_path, "var" set :web_path, "web" set :symfony_env_prod, "prod" set :symfony_console, bin_path + "/console" set :log_path, var_path + "/logs" set :cache_path, var_path + "/cache" set :shared_files, ["app/config/parameters.yml"] set :shared_children, [var_path + "/logs", "vendor", web_path + "/uploads"] set :writable_dirs, ["var/cache", "var/logs"] set :webserver_user, "nginx" set :permission_method, :acl set :use_set_permissions, true set :use_composer, true # set :update_vendors, true set :dump_assetic_assets, true set :repository, "git@github.com:4devs/blog.git" set :scm, :git role :web, domain # Your HTTP server, Apache/etc role :app, domain, :primary => true # This may be the same as your `Web` server set :keep_releases, 3 set :use_sudo, false # Be more verbose by uncommenting the following line # logger.level = Logger::MAX_LEVEL
Остановлюсь на некоторых строчках подробнее. В первой строке мы указывает сколько вариантов stages у нас будет, в данном варианте у нас их три это pro, develop и staging. Вторая строчка указывает какой
stage у нас будет по умолчанию, в данном случае это develop, мы не хотим по ошибке обновлять prod сервер, вообще тут указан stage который будет использоваться при команде $ cap develop
, если нам надо будет использовать prod то команда будет выглядеть $ cap prod deploy
. Строка require 'capistrano/ext/multistage’
обязательна, мы подключаем для работы с нескольколькими stages. Дальше идет установка переменных, так как мы используем структуру папок Symfony 3, то нам приходится это указывать, в виде дополнительных переменных.
Строка set :shared_files, ["app/config/parameters.yml”]
указывает на файлы которые не будут обновляться, на сервере они будут в отдельной папке и при обновлении в рабочую директорию просто будет создаваться символическая ссылка, у нас это файл настроек, если в вашем проекте есть еще файлы то их надо будет добавить в данную переменную. Аналогична переменная set :shared_children, [var_path + "/logs", var_path + "/spool", "vendor", web_path + "/uploads"]
только она используется для папок, тут видно что можно использовать перченные заданные нами ранее.
Строкой set :writable_dirs, [var_path + "/cache", var_path + "/logs", var_path + "/spool"]
задаются папки доступные для записи.
Строки set :repository, "git@github.com:4devs/blog.git”
и set :scm, :git
указывают репозиторий и его тип, в каждом stage мы можем указать ветку, для того чтобы соответствовать нашему workflow.
set :keep_releases, 3
указывает столько версий оставлять, на сервре они будут в папке releases под уникальным идентификатором. После релиза лишние будут удаляться, но необходимо добавить команду after "deploy", “deploy:cleanup”
в конец файла. logger.level = Logger::MAX_LEVEL
необходим если при обновлении возникла ошибка чтобы узнать детали.
Настройка для develop stage
Создаем файл $ vim app/config/deploy/develop.rb
с данный содержимым:
server '4devs.io', :app, :web, :primary => true set :domain, "4devs.io" set :user, "andrey" set :deploy_to, "/var/www/#{domain}" set :branch, "develop" set :symfony_env_prod, "dev"
Первая строка указывает на наш сервер. Следущая строка на домен, потом идет пользователь от имени которого мы будет подсоединяться, будет команда по аналогии $ ssh andrey@4devs.io
. на пятой строке указано куда ставить, но на самом деле там будет три папки, и нужно будет настраивать веб сервер на папку /var/www/4devs.io/current. Также вам необходимо настроить авторизацию по SSH ключу на сервер. Строка set :branch, “develop”
указывает какую ветку использовать в репозитории. А set :symfony_env_prod, “dev”
указывает на окружение в Symfony 2 , будут выполняться команды типа $ bin/console {command} —env=dev
.
На данном этапе настройка закончена.
Загрузка на сервер
Сначала нам необходимо создать структуру командой $ cap deploy:setup
. На сервере в папке /var/www/4devs.io будут созданы три папки current, releases и shared. После для обновления сервера воспользуемся командой $ cap deploy
. В зависимости от уровня logger.level нам выведутся необходимые сообщения.
Если все пройдет удачно при минимальном logger.level выведется такое сообщение:
--> Updating code base with checkout strategy --> Creating cache directory................................✔ --> Creating symlinks for shared directories................✔ --> Creating symlinks for shared files......................✔ --> Normalizing asset timestamps............................✔ --> Downloading Composer....................................✔ --> Installing Composer dependencies........................✔ --> Dumping all assets to the filesystem....................✔ --> Warming up cache........................................✔ --> Clear controllers.......................................✔ --> Setting permissions.....................................✔ --> Successfully deployed!
Для большинства проектов такой информации достаточно, но что если нам необходимо в процессе выполнять дополнительные команды?
Дополнительные команды
К примеру в проекте мы используем cronos-bundle и процессе обновления сервера соответсвенно необходимо выполнять команду $ bin/console cronos:replace
В файле $ vim app/config/deploy/deploy.rb
добавлем следующий код:
namespace :cronos do task :replace do desc "Replace Cron Task" run "cd #{latest_release} && #{php_bin} #{symfony_console} cronos:replace --env=#{symfony_env_prod}" end end
и добавляем также строчку after 'deploy:update', ‘cronos:replace’
чтобы наша команда выполнялась в процессе загрузки. Если мы не так часто добавляем задачи, то можно не добавлять данную задачу, а делать все самому командой $ cap cronos:replace
.
Подключаем дополнения
Многие задачи уже написаны до нас, к примеру очистка memcаhed, нам не надо будет писать для типичных задач свои команды, просто подключим расширение например eycap
поставить его командой $ gem install eycap
и добавляем в наш файл app/config/deploy/deploy.rb
строку require "eycap/recipes”
у нас появляются дополнительный набор команд. Можно также посмотреть все доступные команды $ cap -vT
.
Вывод
Настройка Сapifony экономит очень много времени, и позволяет более эффективно использовать ваше время, не писать длинных инструкций, и допускать меньше ошибок. Для дальнейшего ознакомления я рекомендую воспользоваться официальной документацией Сapifony и Сapistrano.