Удаленная доставка NodeJS приложения с помощью Capistrano

Удаленная доставка NodeJS приложения с помощью CapistranoДумаю, каждый разработчик сталкивался с проблемой развертывания своего сайта/приложения на живой сервер. И, думаю, каждый мечтает о такой кнопочки, нажав которую все его изменения попадали бы на сервер.

Capistrano — это инструмент для быстрого развертывания и выполнения задача на удаленной машине. Изначально он был разработан для развертывания проектов на Ruby On Rails, но как оказалось может применяться для чего угодно. С помощью capistrano можно доставлять PHP, Python, NodeJS проекты.

Что нужно чтобы Capistrano работал?

  • Наличие ssh-доступа к серверу.
  • Исходники должны находится под контролем Subversion или Git (возможно что-то еще).

Capistrano замечательно работает на Mac OS X, Linux и Windows и его установка нужна только на локальной машине, машине разработчика. То есть на сервер capistrano устанавливать не нужно.

Для установки на своей машине вам нужны будут Ruby и RubyGems, после чего достаточно:

gem install capistrano

Вот несколько команд для работы с инструментом:

  • capify . — создает папки и файлы с настройками capistrano по умолчанию
  • cap deploy:setup — удаленная настройка файловой структуры для последующей доставки
  • cap deploy — доставка новой версии на сервер
  • cap deploy:rollback — откатывает версию на сервере до предыдущего состояния

Теперь о том как доставлять NodeJS проекты

Сразу целиком покажу пример конфига (config/deploy.rb) для развертывания приложения на сервере.

set :application, "simonenko.su"
set :node_file, "server.coffee"
set :host, "178.79.189.200"
set :repository, "git@github.com:meritt/simonenko.su.git"
set :user, "root"
set :admin_runner, "www"

set :scm, :git
set :branch, "master"
set :deploy_via, :remote_cache
set :deploy_to, "/usr/www/#{application}"
set :keep_releases, 4

role :app, host

namespace :deploy do
  desc "Start application with forever"
  task :start, :roles => :app, :except => { :no_release => true } do
    run "forever start -c coffee #{current_path}/#{node_file}"
  end

  desc "Stop application"
  task :stop, :roles => :app, :except => { :no_release => true } do
    run "forever stop #{current_path}/#{node_file}"
  end

  desc "Restart application"
  task :restart, :roles => :app, :except => { :no_release => true } do
    stop
    sleep 1
    start
  end

  desc "Install npm modules"
  task :npm_install do
    run "cd #{release_path} && npm link"
  end

  desc "Update node_modules symlink"
  task :npm_update_symlink do
    run "rm -rf #{release_path}/node_modules"
    run "ln -s #{shared_path}/node_modules #{release_path}/node_modules"
  end

  desc "Update access to application"
  task :final_options, roles => :app do
    run "chown -R #{admin_runner}:#{admin_runner} #{deploy_to}"
    run "chmod 777 #{release_path}/cache"
  end

  task :symlink_configs, :roles => :app do
    %w[app_config.yml].each do |f|
      run "ln -sf #{shared_path}/config/#{f} #{release_path}/config/#{f}"
    end
  end

  desc "Create folders for nodejs application"
  task :setup_for_nodejs, :roles => :app do
    run "mkdir -p #{deploy_to}"
    run "mkdir -p #{shared_path}/node_modules"
    run "chown -R #{admin_runner}:#{admin_runner} #{deploy_to}"
  end

end

before 'deploy:setup', 'deploy:setup_for_nodejs'

after "deploy:finalize_update", "deploy:cleanup", "deploy:symlink_configs", "deploy:final_options"

after "deploy:update_code", "deploy:npm_update_symlink", "deploy:npm_install"

Остановимся на некоторых настройках подробней.

set :application, "application-name.js"

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

set :node_file, "server.coffee"

Главный файл запуска сервера.

set :host, "87.250.250.11"
set :user, "root"
set :admin_runner, "www-data"

Доступ к удаленному серверу.

set :repository, "git@github.com:meritt/application-name.js.git"
set :scm, :git
set :branch, "master"

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

set :deploy_via, :remote_cache

Позволяет при последующих обновлениях не закачивать целиком репозиторий, а только обновлять его.

Дополнительно, думаю, стоит описать этапы.

task :start, :stop, :restart

Запускает и останавливает приложение с помощью forever — это NodeJS модуль, который следит чтобы node процесс был запущен, и перезапускает его если нужно.

task :npm_install, :npm_update_symlink

Устанавливает npm модули, необходимые для приложения, и обновляет их при необходимости.

task :setup_for_nodejs

Создает начальную файловую структуру для последующей доставки.

Я не стал описывать настройку Apache/Nginx для того чтобы они проксировали работу приложения на 80 порт, думаю это и так понятно как делать. Единственное добавлю, что эти операции стоит добавить в этап :setup_for_nodejs.

Вот и все, обычный процесс для вас будет выглядеть так:

  • capify .
  • создание своего конфига
  • cap deploy:setup

А дальше многократное cap deploy и может иногда cap deploy:rollback.

Немного о возможностях

В этой статье я лишь описал как доставить файлы, установить npm модули и запускать сервер, однако идея развертывания на этом не заканчивается. Немного разобравшись, вы сможете:

  • создавать базу, вносить в нее изменения, заполнять данными по умолчанию
  • запускать фоновые процессы
  • развертывать приложение на нескольких серверах сразу
  • создавать объединенные и сжатые версии стилей и скриптов

и многое другое что вам придет в голову.

Бесплатный совет: потратьте 10-40 минут, создайте своему приложению правила доставки и наслаждайтесь тем, что доставка вашего приложения происходит по нажатию на одну кнопку.

Что ещё почитать?

← Как преобразовать ваши JavaScript фЧто интересного в PHP 5.4 beta 2 и  →