Многократное развертывание с использованием Capistrano

Capistrano – это написанная на Ruby утилита, созданная в целях надежного и многократного развертывания Rails-приложений на удаленных серверах (хотя можно разворачивать и не только ROR). Для связи с серверами и выполнения серверных команд в ней используется SSH. Эту утилиту очень трудно настроить, но для обычного развертывания она довольно проста в использовании и напоминает форсированую версию Rake, в которой средства Capistrano состоят из набора выполняемых задач. Но в Capistrano задачи обеспечены методами, которые способны вызывать действия на одном или нескольких удаленных серверах.

Подобно Rails, Capistrano довольно своенравная программа, выстраивающая ряд предложений. Первое из них состомт в том, что развертывание производится на системе, основаной на Unix. Второе – что код содержится в хранилище, доступном той машине, с которой ведеться развертывание, и той машине, на которую оно ведется.

Приступим

Как только появиться машина, пригодная для развертывания приложения, сначала её нужно очистить от всего ненужного и приготовить к работе. Если это PC, он должен работать самой последней версии Linux, FreeBSD или Solaris. Если это Mac, то на нем должен быть запущен последний выпуск версии Mac OS X.

Далее нужно установить ряд необходимых компонентов программного обезпечения. На машине потребуються следующие компоненты:

- Веб-сервер (Apache, lighttpd или nginx)

- Сервер баз данных (Mysql, Postgresql, Oracle прочее, что поддерживает ROR)

- Ruby 1.8.4 или поздний выпуск

- RubyGems для управления пакетами, создаными на основе Ruby

- Библиотека Mysql/Ruby (или Pgsql/Ruby, смотря какую базу данных вы поставите и будете использовать)

- Библиотека Ruby Termios

Для установки этих пакетов лучше использовать систему управления пакетов. В Ubuntu Linux – apt-get, в Red Hat – rpm, Mac OS X – MacPorts. Как только упомянутые компоненты будут установлены, нужно будет установить следующие RubyGems: Rake, Rails, Capistrano и Mongrel.

Для ускорения установки этих gem-пакетов используются следующие команды:

  1. # на сервере (серверах), а также на клиентской машине
  2. # (если не установлены ранее)
  3. $ gem install –include-dependencies rake
  4. $ gem install –include-dependencies rails
  5. $ gem install –include-dependencies termios
  6. $ gem install –include-dependencies capistrano
  7. $ gem install –include-dependencies mongrel
  8. $ gem install –include-dependencies mongrel_cluster

Теперь вы располагаете всем необходимым программным обезпечением, которое требуется для запуска стандартных Rails-приложений. Разумеется, если в в приложении используються другие gem-пакеты Ruby, то их также нужно будет установить. В предыдущей статье я рассказывал как настроить mongrel, поэтому тут я это упускаю.

Настройка Capistrano

Чтобы Capistrano начал творить свои чудеса, нужно выполнить следующию команду:

  1. $#cd /projects/rails_demo  # rails_demo – директория нашего приложения
  2. $/projects/rails_demo# capify .
  3. [add] writing `./Capfile’
  4. [add] writing `./config/deploy.rb’
  5. [done] capified!

Из информации, выведенной на экран, видно, что Capistrano устанавливает два файла. Первый из них, /config/deploy.rb, содержит предписания, необходимые для развертывания приложения. Теперь нужно отредактировать файл config/deploy.rb для настройки его под конкретное развертывание. В начало файла нужно добавить оператор require, чтобы включить предписание mongrel_cluster, которое обеспечит беспроблемное развертывание Mongrel:

  1. require "mongrel_cluster/recipes"
  2. # Имя приложения
  3. set :application, "rails_demo"
  4. # Вызов функции set создаст переменную application и присвоит ей значение "rails_demo"
  5.  
  6. # В проекте мы используем только один сервер, выполняющий роль веб-сервиса.
  7. role :web, "example.com" # хост удалённого сервера
  8. set :user, ‘user’ # пользователь удалённого сервера
  9. set :use_sudo, false # не запускать команды под sudo
  10.  
  11. # Директория приложения на удалённом хостинге
  12. set :app_dir, "/home/#{user}/#{application}/" # /home/user/rails_demo/
  13. # Запись "/home/#{user}/#{application}/" аналогична "/home/$user/$application/" в PHP
  14.  
  15. # Директория, куда будет делаться checkout из репозитория
  16. set :deploy_to, "#{app_dir}/deploy" # /home/user/rails_demo/deploy
  17. # Указываем где находится конфигурационный файл Mongrel
  18. set(:mongrel_conf) {"#{current_path}/config/mongrel_cluster.yml"}
  19.  
  20. # Настройки репозитория
  21. set :scm, :subversion # используем subversion
  22. set :scm_user, ‘svn_user’ # имя пользователя репозитория
  23. set :scm_url, "svn://svnhost/trunk/#{application}" # svn://svnhost/trunk/rails_demo/
  24. # Формируем команду svn checkout –username svn_user svn://host/trunk/rails_demo
  25. set :repository, Proc.new { "–username #{scm_user} #{scm_url}"}
  26. # можно выполнить дополнительное задание после работы
  27. # например создать символическую ссылку в папку main на текущий релиз
  28. task :after_symlink, :roles => :web do
  29. run "ln -nfs #{release_path} #{app_dir}/main"
  30. end

Как только будут внесены эти исправления, можно приступать к развертыванию. Если вы все правильно сделали, то набрав команду cap -T вы должны увидеть возможные ваши команды

  1. $ cap -T
  2. cap deploy                    # Deploys your project.
  3. cap deploy:check              # Test deployment dependencies.
  4. cap deploy:cleanup            # Clean up old releases.
  5. cap deploy:cold               # Deploys and starts a `cold’ application.
  6. cap deploy:migrate            # Run the migrate rake task.
  7. cap deploy:migrations         # Deploy and run pending migrations.
  8. cap deploy:pending            # Displays the commits since your last deploy.
  9. cap deploy:pending:diff       # Displays the `diff’ since your last deploy.
  10. cap deploy:restart            # Restart the Mongrel processes on the app serv…
  11. cap deploy:rollback           # Rolls back to a previous version and restarts.
  12. cap deploy:rollback:code      # Rolls back to the previously deployed version.
  13. cap deploy:setup              # Prepares one or more servers for deployment.
  14. cap deploy:start              # Start the Mongrel processes on the app server…
  15. cap deploy:stop               # Stop the Mongrel processes on the app server …
  16. cap deploy:symlink            # Updates the symlink to the most recently depl…
  17. cap deploy:update             # Copies your project and updates the symlink.
  18. cap deploy:update_code        # Copies your project to the remote servers.
  19. cap deploy:upload             # Copy files to the currently deployed version.
  20. cap deploy:web:disable        # Present a maintenance page to visitors.
  21. cap deploy:web:enable         # Makes the application web-accessible again.
  22. cap invoke                    # Invoke a single command on the remote servers.
  23. cap mongrel:cluster:configure # Configure Mongrel processes on the app server.
  24. cap mongrel:cluster:restart   # Restart the Mongrel processes on the app serv…
  25. cap mongrel:cluster:start     # Start Mongrel processes on the app server.
  26. cap mongrel:cluster:status    # Check the status of the Mongrel processes on …
  27. cap mongrel:cluster:stop      # Stop the Mongrel processes on the app server.
  28. cap shell                     # Begin an interactive Capistrano session.

Выполняем команду

  1. $ cap deploy:setup

Это сделает начальную инициализацию, создание папок на сервере. Следующий шаг

  1. $ cap deploy:cold

После запуска этой команды произойдет развертывание приложения на сервер, а затем будет запущенны копии Mongrel:

  1. * executing `deploy:cold’
  2.   * executing `deploy:update’
  3.  ** transaction: start
  4.   * executing `deploy:update_code’
  5.     executing locally: "svn info –username leopard http://10.108.9.142/svn/rails_films/rails_films/  -rHEAD"
  6.   * executing "svn checkout -q  -r12 –username leopard http://10.108.9.142/svn/rails_films/rails_films/ /var/www/rails/rails_films/deploy/releases/20090121085418 && (echo 12 > /var/www/rails/rails_films/deploy/releases/20090121085418/REVISION)"
  7.     servers: ["10.108.9.141"]
  8.     [10.108.9.141] executing command
  9.     command finished
  10.   * executing `deploy:finalize_update’
  11.   * executing "chmod -R g+w /var/www/rails/rails_films/deploy/releases/20090121085418"
  12.     servers: ["10.108.9.141"]
  13.     [10.108.9.141] executing command
  14.     command finished
  15.   * executing "rm -rf /var/www/rails/rails_demo/deploy/releases/20090121085418/log /var/www/rails/rails_demo/deploy/releases/20090121085418/public/system /var/www/rails/rails_demo/deploy/releases/20090121085418/tmp/pids &&\\\n      mkdir -p /var/www/rails/rails_demo/deploy/releases/20090121085418/public &&\\\n      mkdir -p /var/www/rails/rails_demo/deploy/releases/20090121085418/tmp &&\\\n      ln -s /var/www/rails/rails_demo/deploy/shared/log /var/www/rails/rails_demo/deploy/releases/20090121085418/log &&\\\n      ln -s /var/www/rails/rails_demo/deploy/shared/system /var/www/rails/rails_demo/deploy/releases/20090121085418/public/system &&\\\n      ln -s /var/www/rails/rails_demo/deploy/shared/pids /var/www/rails/rails_demo/deploy/releases/20090121085418/tmp/pids"
  16.     servers: ["10.108.9.141"]
  17.     [10.108.9.141] executing command
  18.     command finished
  19.   * executing "find /var/www/rails/rails_demo/deploy/releases/20090121085418/public/images /var/www/rails/rails_demo/deploy/releases/20090121085418/public/stylesheets /var/www/rails/rails_demo/deploy/releases/20090121085418/public/javascripts -exec touch -t 200901210854.19 {} ‘;’; true"
  20.     servers: ["10.108.9.141"]
  21.     [10.108.9.141] executing command
  22.     command finished
  23.   * executing `deploy:symlink’
  24.   * executing "rm -f /var/www/rails/rails_demo/deploy/current && ln -s /var/www/rails/rails_demo/deploy/releases/20090121085418 /var/www/rails/rails_demo/deploy/current"
  25.     servers: ["10.108.9.141"]
  26.     [10.108.9.141] executing command
  27.     command finished
  28.   * executing `after_symlink’
  29.   * executing "ln -nfs /var/www/rails/rails_demo/deploy/releases/20090121085418 /var/www/rails/rails_demo//main"
  30.     servers: ["10.108.9.141"]
  31.     [10.108.9.141] executing command
  32.     command finished
  33.  ** transaction: commit
  34.   * executing `deploy:migrate’
  35.   * executing "ls -xt /var/www/rails/rails_demo/deploy/releases"
  36.     servers: ["10.108.9.141"]
  37.     [10.108.9.141] executing command
  38.     command finished
  39.   * executing "cd /var/www/rails/rails_demo/deploy/releases/20090121085418; rake RAILS_ENV=production  db:migrate"
  40.     servers: ["10.108.9.141"]
  41.     [10.108.9.141] executing command
  42.  ** [out :: 10.108.9.141] (in /var/www/rails/rails_demo/deploy/releases/20090121085418)
  43.  ** [out :: 10.108.9.141] Loaded suite /usr/bin/rake
  44.  ** [out :: 10.108.9.141] Started
  45.  ** [out :: 10.108.9.141]
  46.  ** [out :: 10.108.9.141] Finished in 0.000285 seconds.
  47.  ** [out :: 10.108.9.141]
  48.  ** [out :: 10.108.9.141] 0 tests, 0 assertions, 0 failures, 0 errors
  49.     command finished
  50.   * executing `deploy:start’
  51.   * executing `mongrel:cluster:start’
  52.   * executing "mongrel_rails cluster::start -C /var/www/rails/rails_demo/deploy/current/config/mongrel_cluster.yml"
  53.     servers: ["10.108.9.141"]
  54.     [10.108.9.141] executing command
  55.  ** [out :: 10.108.9.141] starting port 3000
  56.  ** [out :: 10.108.9.141] starting port 3001
  57.     command finished

Как видим db:migrate происходит тоже автоматически. Что бы проверить, запустился ли Mongrel (хотя по логам и так видно что все хорошо), выполняем на сервера:

  1. $ curl -I http://127.0.0.1:3000
  2. HTTP/1.1 200 OK
  3. Connection: close
  4. Date: Wed, 21 Jan 2009 09:07:42 GMT
  5. Set-Cookie: _rails_demo_session=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D–b005599b2682d41b58913b29b3a6d90b9df0a6a1; path=/; HttpOnly
  6. Status: 200 OK
  7. ETag: "9e83fd09513c147745f5eb696352e9e7"
  8. X-Runtime: 30ms
  9. Content-Type: text/html; charset=UTF-8
  10. Content-Length: 1392
  11. Server: Mongrel 1.1.5
  12. Cache-Control: private, max-age=0, must-revalidate

И в заключение

Ваш сервер готов. Что бы обновить приложение на сервере, обновите хранилище (например Subversion) и выполнить команду cap deploy:update на локальной компьютере, что и произведет повторное развертывание. Если по каким то причинам нужно будет вернуться на шаг назад, к предыдущей версии приложения, можно использовать следующую команду – cap deploy:rollback. Так же можно управлять запуском, остановкой, а так же перегрузкой Mongrel через Capistrano. При каждом новом развертывании на сервере появляеться новая версия приложения, обновляться соответствующие ссылки и перезапускаются экземпляры Mongrel.

Все. Удачи!

21. января 2009 by Alexey Vasiliev
Categories: Ruby, Ruby on Rails, разработка | Tags: , , | 3 комментария

Comments (3)

  1. Ну наконец-то более-менее приличный туториал на русском языке :) буду советовать новичкам

  2. 2DEkart
    Пожалуйста, по вопросам обращайтесь, будем их решать. Софтина очень понравилась, настраивал и запускал уже на многих машинах :)

  3. Спасибо, действительно интересный материал. Добавлю в закладки, скоро разворачивать проект ;)