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

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

На то мы и программисты чтобы автоматизировать рутину, поэтому ниже речь пойдет о автоматизации процесса выгрузки обновлений в продакшен, при помощи подсмотренной в рубистов утилиты 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"

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

Итак, никакой рутины, гибко и расширяемо, у нас опять получилось переложить на компьютер часть своей работы. Еще бы научить его кофе готовить и пиво открывать)
Добавлено: 11 Сентября 2013 11:55:10 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...