Поиск по сайту:

Развертывание приложения Rails в Ubuntu 14.04 с помощью Capistrano, Nginx и Puma


Введение

Rails — это фреймворк для веб-приложений с открытым исходным кодом, написанный на Ruby. Он следует философии Конвенция важнее конфигурации, делая предположения о том, что существует «лучший» способ ведения дел. Это позволяет вам писать меньше кода, выполняя больше, не просматривая бесконечные файлы конфигурации.

Nginx — это высокопроизводительный HTTP-сервер, обратный прокси-сервер и балансировщик нагрузки, известный своей ориентацией на параллелизм, стабильность, масштабируемость и низкое потребление памяти. Как и Nginx, Puma — еще один чрезвычайно быстрый и параллельный веб-сервер с очень небольшим объемом памяти, но созданный для веб-приложений Ruby.

Capistrano — это инструмент автоматизации удаленного сервера, ориентированный в основном на веб-приложения Ruby. Он используется для надежного развертывания веб-приложений на любом количестве удаленных компьютеров путем написания сценариев произвольных рабочих процессов через SSH и автоматизации общих задач, таких как предварительная компиляция ресурсов и перезапуск сервера Rails.

В этом руководстве мы установим Ruby и Nginx на дроплет DigitalOcean Ubuntu и настроим Puma и Capistrano в нашем веб-приложении. Nginx будет использоваться для захвата клиентских запросов и передачи их на веб-сервер Puma, на котором работает Rails. Мы будем использовать Capistrano для автоматизации общих задач развертывания, поэтому каждый раз, когда нам нужно развертывать новую версию нашего приложения Rails на сервере, мы можем делать это с помощью нескольких простых команд.

Предпосылки

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

  • Дроплет Ubuntu 14.04 x64
  • Пользователь без полномочий root с именем deploy с привилегиями sudo (начальная настройка сервера с Ubuntu 14.04 объясняет, как это настроить).
  • Рабочее приложение Rails, размещенное в удаленном репозитории git, готовое к развертыванию

При желании для повышения безопасности вы можете отключить вход в систему root через SSH и изменить номер порта SSH, как описано в разделе «Начальная настройка сервера с Ubuntu 14.04».

Предупреждение. После отключения входа в систему с правами root убедитесь, что вы можете использовать SSH для доступа к своей капле в качестве пользователя deploy и использовать sudo для этого пользователя, перед закрытием root Сеанс SSH, который вы открыли для внесения этих изменений.

Все команды в этом руководстве следует запускать от имени пользователя deploy. Если для команды требуется root-доступ, ей будет предшествовать sudo.

Шаг 1 — Установка Nginx

Как только VPS будет защищен, мы можем начать установку пакетов. Обновите индексные файлы пакета:

  1. sudo apt-get update

Затем установите Nginx:

  1. sudo apt-get install curl git-core nginx -y

Шаг 2 — Установка баз данных

Установите базу данных, которую вы будете использовать в своем приложении Rails. Поскольку существует множество баз данных на выбор, мы не будем рассматривать их в этом руководстве. Вы можете увидеть инструкции для основных здесь:

  • Майкл
  • PostgreSQL
  • МонгоБД

Также обязательно ознакомьтесь:

  • Как использовать MySQL с приложением Ruby on Rails в Ubuntu 14.04
  • Как использовать PostgreSQL с приложением Ruby on Rails в Ubuntu 14.04

Шаг 3 — Установка RVM и Ruby

Мы не будем устанавливать Ruby напрямую. Вместо этого мы будем использовать Ruby Version Manager. Их много на выбор (rbenv, chruby и т. д.), но для этого урока мы будем использовать RVM. RVM позволяет вам легко устанавливать и управлять несколькими рубинами в одной системе и использовать правильный в соответствии с вашим приложением. Это значительно упрощает жизнь, когда вам нужно обновить приложение Rails, чтобы использовать более новый ruby.

Перед установкой RVM вам необходимо импортировать ключ RVM GPG:

  1. gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

Затем установите RVM для управления нашими Рубинами:

  1. curl -sSL https://get.rvm.io | bash -s stable

Эта команда использует curl для загрузки сценария установки RVM с https://get.rvm.io. Параметр -sSL состоит из трех флагов:

  • -s указывает curl загружать файл в «автоматическом режиме»
  • -S указывает curl показывать сообщение об ошибке в случае сбоя
  • -L указывает curl следовать всем перенаправлениям HTTP при получении скрипта установки

После загрузки скрипт передается в bash. Опция -s передает stable в качестве аргумента сценарию установки RVM для загрузки и установки стабильной версии RVM.

Примечание. Если вторая команда завершается с ошибкой с сообщением «Ошибка проверки подписи GPG», это означает, что ключ GPG был изменен, просто скопируйте команду из вывода ошибки и запустите ее, чтобы загрузить подписи. Затем запустите команду curl для RVM. Монтаж.

Нам нужно загрузить скрипт RVM (как функцию), чтобы мы могли начать его использовать. Затем нам нужно запустить команду requirements, чтобы автоматически установить необходимые зависимости и файлы для правильной работы RVM и Ruby:

  1. source ~/.rvm/scripts/rvm
  2. rvm requirements

Теперь мы можем установить Ruby по нашему выбору. Мы установим последнюю версию Ruby 2.2.1 (на момент написания статьи) в качестве Ruby по умолчанию:

  1. rvm install 2.2.1
  2. rvm use 2.2.1 --default

Шаг 4 — Установка Rails и Bundler

Как только Ruby настроен, мы можем начать установку Rubygems. Мы начнем с установки гема Rails, который позволит запускать ваше приложение Rails, а затем мы установим bundler, который может читать Gemfile вашего приложения и автоматически устанавливать все необходимые драгоценные камни.

Чтобы установить Rails и Bundler:

  1. gem install rails -V --no-ri --no-rdoc
  2. gem install bundler -V --no-ri --no-rdoc

Использовались три флага:

  • -V (подробный вывод): выводит подробную информацию об установке Gem
  • --no-ri — (пропускает документацию Ri): не устанавливает Ri Docs, экономит место и ускоряет установку
  • --no-rdoc — (пропускает RDocs): не устанавливает RDocs, что экономит место и ускоряет установку

Примечание. Вы также можете установить конкретную версию Rails в соответствии с вашими требованиями, используя флаг -v:

  1. gem install rails -v '4.2.0' -V --no-ri --no-rdoc

Шаг 5 — Настройка ключей SSH

Поскольку мы хотим настроить плавное развертывание, мы будем использовать ключи SSH для авторизации. Сначала пожмите руку GitHub, Bitbucket или любому другому Git Remote, где размещена база кода для вашего приложения Rails:

  1. ssh -T git@github.com
  2. ssh -T git@bitbucket.org

Не беспокойтесь, если вы получите сообщение Отказано в доступе (publickey). Теперь сгенерируйте SSH-ключ (пару открытого и закрытого ключей) для вашего сервера:

  1. ssh-keygen -t rsa

Добавьте только что созданный открытый ключ (~/.ssh/id_rsa.pub) в ключи развертывания вашего репозитория:

  • Инструкции для Github
  • Инструкции для Bitbucket

Если все шаги были выполнены правильно, теперь вы сможете клонировать свой репозиторий git (по протоколу SSH, а не HTTP) без ввода пароля:

  1. git clone git@example.com:username/appname.git

Если вам нужен образец приложения для тестирования, вы можете разветвить следующее тестовое приложение, специально созданное для этого руководства: Образец приложения Rails на GitHub

Команда git clone создаст каталог с тем же именем, что и ваше приложение. Например, будет создан каталог с именем testapp_rails.

Мы клонируем только для того, чтобы проверить, работают ли наши ключи развертывания, нам не нужно клонировать или извлекать наш репозиторий каждый раз, когда мы вносим новые изменения. Мы позволим Капистрано справиться со всем этим за нас. Теперь вы можете удалить этот клонированный каталог, если хотите.

Откройте терминал на локальном компьютере. Если у вас нет ключа SSH для локального компьютера, создайте его и для него. В вашем локальном терминальном сеансе:

  1. ssh-keygen -t rsa

Добавьте свой локальный SSH-ключ в файл Авторизованные ключи вашего дроплета (не забудьте заменить номер порта вашим настроенным номером порта):

  1. cat ~/.ssh/id_rsa.pub | ssh -p your_port_num deploy@your_server_ip 'cat >> ~/.ssh/authorized_keys'

Шаг 6 — Добавление конфигураций развертывания в приложение Rails

На локальном компьютере создайте файлы конфигурации для Nginx и Capistrano в приложении Rails. Начните с добавления этих строк в Gemfile в приложении Rails:


group :development do
    gem 'capistrano',         require: false
    gem 'capistrano-rvm',     require: false
    gem 'capistrano-rails',   require: false
    gem 'capistrano-bundler', require: false
    gem 'capistrano3-puma',   require: false
end

gem 'puma'

Используйте bundler для установки драгоценных камней, которые вы только что указали в своем Gemfile. Введите следующую команду, чтобы связать ваше приложение Rails:

  1. bundle

После объединения выполните следующую команду для настройки Capistrano:

  1. cap install

Это создаст:

  • Capfile в корневом каталоге вашего приложения Rails
  • Файл
  • deploy.rb в каталоге config
  • Каталог
  • deploy в каталоге config

Замените содержимое вашего Capfile следующим:

# Load DSL and Setup Up Stages
require 'capistrano/setup'
require 'capistrano/deploy'

require 'capistrano/rails'
require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/puma'

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Этот Capfile загружает некоторые предопределенные задачи в файлы конфигурации Capistrano, чтобы упростить развертывание, например автоматически:

  • Выбор правильного Ruby
  • Предварительная компиляция ресурсов
  • Клонирование репозитория Git в нужное место
  • Установка новых зависимостей при изменении Gemfile

Замените содержимое config/deploy.rb следующим, обновив поля, отмеченные красным, с параметрами вашего приложения и дроплета:


# Change these
server 'your_server_ip', port: your_port_num, roles: [:web, :app, :db], primary: true

set :repo_url,        'git@example.com:username/appname.git'
set :application,     'appname'
set :user,            'deploy'
set :puma_threads,    [4, 16]
set :puma_workers,    0

# Don't change these unless you know what you're doing
set :pty,             true
set :use_sudo,        false
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log,  "#{release_path}/log/puma.access.log"
set :ssh_options,     { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true  # Change to false when not using ActiveRecord

## Defaults:
# set :scm,           :git
# set :branch,        :master
# set :format,        :pretty
# set :log_level,     :debug
# set :keep_releases, 5

## Linked Files & Directories (Default None):
# set :linked_files, %w{config/database.yml}
# set :linked_dirs,  %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

namespace :puma do
  desc 'Create Directories for Puma Pids and Socket'
  task :make_dirs do
    on roles(:app) do
      execute "mkdir #{shared_path}/tmp/sockets -p"
      execute "mkdir #{shared_path}/tmp/pids -p"
    end
  end

  before :start, :make_dirs
end

namespace :deploy do
  desc "Make sure local git is in sync with remote."
  task :check_revision do
    on roles(:app) do
      unless `git rev-parse HEAD` == `git rev-parse origin/master`
        puts "WARNING: HEAD is not the same as origin/master"
        puts "Run `git push` to sync changes."
        exit
      end
    end
  end

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      before 'deploy:restart', 'puma:start'
      invoke 'deploy'
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end

  before :starting,     :check_revision
  after  :finishing,    :compile_assets
  after  :finishing,    :cleanup
  after  :finishing,    :restart
end

# ps aux | grep puma    # Get puma pid
# kill -s SIGUSR2 pid   # Restart puma
# kill -s SIGTERM pid   # Stop puma

Этот файл deploy.rb содержит несколько нормальных настроек по умолчанию, которые работают «из коробки», чтобы помочь вам управлять выпусками приложений и автоматически выполнять некоторые задачи при развертывании:

  • Использует production в качестве среды по умолчанию для вашего приложения Rails
  • Автоматическое управление несколькими версиями вашего приложения
  • Использует оптимизированные параметры SSH
  • Проверяет, обновлены ли ваши пульты git.
  • Управляет журналами вашего приложения
  • Предварительно загружает приложение в память при управлении работниками Puma.
  • Запускает (или перезапускает) сервер Puma после завершения развертывания.
  • Открывает сокет для сервера Puma в определенном месте вашей версии.

Вы можете изменить все параметры в зависимости от ваших требований. Теперь нужно настроить Nginx. Создайте config/nginx.conf в каталоге вашего проекта Rails и добавьте в него следующее (опять же, заменив ваши параметры):


upstream puma {
  server unix:///home/deploy/apps/appname/shared/tmp/sockets/appname-puma.sock;
}

server {
  listen 80 default_server deferred;
  # server_name example.com;

  root /home/deploy/apps/appname/current/public;
  access_log /home/deploy/apps/appname/current/log/nginx.access.log;
  error_log /home/deploy/apps/appname/current/log/nginx.error.log info;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @puma;
  location @puma {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}

Как и в предыдущем файле, этот nginx.conf содержит настройки по умолчанию, которые готовы к работе с конфигурациями в вашем файле deploy.rb. Это прослушивает трафик на порту 80 и передает запрос в ваш сокет Puma, записывает журналы nginx в «текущий» выпуск вашего приложения, сжимает все активы и кэширует их в браузере с максимальным сроком действия, обслуживает HTML-страницы в общедоступном как статические файлы и устанавливает максимальные значения Client Body Size и Время ожидания запроса по умолчанию.

Шаг 7 — Развертывание вашего приложения Rails

Если вы используете свое собственное приложение Rails, зафиксируйте только что внесенные изменения и отправьте их на удаленный компьютер с вашего локального компьютера:

  1. git add -A
  2. git commit -m "Set up Puma, Nginx & Capistrano"
  3. git push origin master

Примечание. Если вы впервые используете GitHub из этой системы, вам может потребоваться ввести следующие команды с вашим именем пользователя и адресом электронной почты GitHub:

  1. git config --global user.name 'Your Name'
  2. git config --global user.email you@example.com

Опять же, с вашего локального компьютера выполните первое развертывание:

  1. cap production deploy:initial

Это переместит ваше приложение Rails в Droplet, установит все необходимые драгоценные камни для вашего приложения и запустит веб-сервер Puma. Это может занять от 5 до 15 минут в зависимости от количества Gems, которое использует ваше приложение. По мере выполнения этого процесса вы будете видеть отладочные сообщения.

Если все пойдет гладко, теперь мы готовы подключить ваш веб-сервер Puma к обратному прокси-серверу Nginx.

В дроплете создайте символическую ссылку nginx.conf на каталог sites-enabled:

  1. sudo rm /etc/nginx/sites-enabled/default
  2. sudo ln -nfs "/home/deploy/apps/appname/current/config/nginx.conf" "/etc/nginx/sites-enabled/appname"

Перезапустите службу Nginx:

  1. sudo service nginx restart

Теперь вы сможете указать в веб-браузере IP-адрес своего сервера и увидеть свое приложение Rails в действии!

Обычные развертывания

Всякий раз, когда вы вносите изменения в свое приложение и хотите развернуть новую версию на сервере, зафиксируйте изменения, отправьте их на удаленный git, как обычно, и выполните команду deploy:

  1. git add -A
  2. git commit -m "Deploy Message"
  3. git push origin master
  4. cap production deploy

Примечание. Если вы внесете изменения в файл config/nginx.conf, вам придется перезагрузить или перезапустить службу Nginx на сервере после развертывания приложения:

  1. sudo service nginx restart

Заключение

Итак, к настоящему моменту вы будете запускать приложение Rails на своем дроплете с Puma в качестве веб-сервера, а также Nginx и Capistrano с базовыми настройками. Теперь вы должны взглянуть на другие документы, которые могут помочь вам оптимизировать ваши конфигурации, чтобы получить максимальную отдачу от вашего приложения Rails:

  • Конфигурации Puma
  • Puma DSL в Капистрано
  • Предварительная компиляция локальных активов в Capistrano
  • Автоматически перезапускать рабочие процессы Puma в зависимости от объема оперативной памяти.
  • Оптимизация Nginx для высоких нагрузок