Подписка

Автоматизация деплоя на продакшен сервера

Обновление кода на продакшене (или деплой) одна из рутинных операций которые приходится выполнять время от времени, и в зависимости от сложности архитектуры может превратиться или в просто, или в ужасно нудный процесс.

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

Установка

Capistrano распространяется в виде ruby gem'a, поэтому для установки сначала ставим gems:

aptitude install gems

после чего с гемов устанавливаем Capistrano

gem install capistrano

Что нам стоит деплой процесс построить

Инструкции прописываются в файле Capfile, который обычно лежит в корне проекта и содержит шаги и разнообразные функции использующиеся при деплое (или для автоматизации еще каких-нибудь нудных задач).

Давайте сконфигурируем обновление проекта, содержащего PHP/Nodejs код, хранящийся в git, при том что на продакшене PHP и NodeJS бегают на разных серверах. Итак, для обновления всей системы необходимо:

Сервер 1:
обновить php код из git
Сервер 2:
1. Остановить старый NodeJS сервер
2. Обновить NodeJS из git
3. Запустить новый NodeJS сервер

Начнем с конфигурации серверов. Так как Capistrano мы "одолжили" в рубистов, то естественно и Capfile прийдется писать на руби, но ничего страшного в этом нет, для наших плотских задач высоких знаний не потребуется.

Пропишем параметры доступа к обеим серверам:

set :application, "DeployMe"
role :app_server, "myserver.com"
role :nodejs_server, "myserver2.com"
set :user, "nakko"

В первой строке указали название приложения, в строках 2, 3 хосты серверов, а в 4-ой имя пользователя которым будем авторизироваться. Пароли не указаны, потому что дурное дело хранить ssh пароли в конфигурационных файлах, поэтому будем использовать авторизацию по публичному ключу (настройка ssh public key авторизации).

Теперь создадим задачу для обновления php кода:

desc "Update appserver"
task :update_appserver, :roles => :app_server do
     puts "Updating php sources"
     run "cd /var/www/myproject && git pull"
     puts "Done"
end

Задача "update_appserver" выполнит все входящие в нее команды на сервере (или серверах) заданных в app_server. Для обновления в нашем случае просто выполняется git pull в определенной папке (Capistrano умеет более "умно" работать с git, больше тут).

Очередь обновить NodeJS

desc "Update nodejs"
task :update_nodejs, :roles => :nodejs_server do
     puts "Stoping old instance"
     pid = capture("echo $(ps aux | grep '[s]erver.js' | awk '{print $2}' | head -n 1)").strip
     run "kill #{pid}" if pid != ""
     puts "Updating code"
     run "cd /var/www/node && git pull"
     puts "Starting new instance"
     run "node /var/www/node/server.js &"
     puts "Done"
end

Пройдемся по использованных командах:

puts - вывести строку (например для индикации текущего этапа деплоя)
run - выполнить команду на сервере
capture - выполнить команду и вернуть результат, мы использовали для получения идентификатора процесса nodejs сервера для последующей остановки.

И напоследок сделаем задачу которая будет выполнять полное обновление:

desc "Update all"
task :update do
     update_appserver
     update_nodejs
end

Тепер выполняем в консоли

cap update
и наслаждаемся процессом.

Как видите никаких высоких материй.

Но самое вкусное то, что в ролях которые мы задавали в самом начале можно указать не один, а несколько серверов, тоесть не только

role :app_server, "myserver.com"

но и

role :app_server, "myserver.com", "myserver10.com", "myserver11.com", "myserver12.com"

В таком случае команды будут выполнены параллельно на всех серверах.

Итак, никакой рутины, гибко и расширяемо, у нас опять получилось переложить на компьютер часть своей работы. Еще бы научить его кофе готовить и пиво открывать)

На самом деле Capistrano умеет намного больше чем перечисленные 3 команды, поэтому кого заинтересовало - вики проекта.

В тему:

Если пост понравился - нажмите на +1 - мне будет приятно.

@kkooler

@kkooler

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

Следить за блогом

RSS канал Twitter