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

Вступление

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

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

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

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

Предпосылки

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

  • Ubuntu 14.04 x64 Droplet

  • Пользователь без полномочий root с именем + deploy + с привилегиями sudo (Initial Настройка сервера с Ubuntu 14.04 объясняет как это настроить.)

  • Приложение Working Rails, размещенное в удаленном репозитории git, готовое к развертыванию

По желанию, для повышенной безопасности вы можете отключить root-вход через SSH и изменить номер порта SSH, как описано в https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [ Начальная настройка сервера с Ubuntu 14.04].

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

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

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

sudo apt-get update

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

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

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

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

Также не забудьте проверить:

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

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

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

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

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

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.

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

source ~/.rvm/scripts/rvm
rvm requirements

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

rvm install 2.2.1
rvm use 2.2.1 --default

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

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

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

gem install rails -V --no-ri --no-rdoc
gem install bundler -V --no-ri --no-rdoc

Были использованы три флага:

  • + -V + (подробный вывод): выводит подробную информацию об установке Gem

  • + - no-ri + - (Пропускает документацию по Ri): не устанавливает Ri Docs, экономит место и ускоряет установку

  • + - no-rdoc + - (пропускает RDocs): не устанавливает RDocs, экономит место и ускоряет установку

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

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

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

ssh-keygen -t rsa

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

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

git clone

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

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

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

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

ssh-keygen -t rsa

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

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

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

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

Gemfile

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:

bundle

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

cap install

Это создаст:

  • + Capfile + в корневом каталоге вашего приложения Rails

  • Файл + deploy.rb + в каталоге + config +

  • Каталог + deploy в каталоге` + config`

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

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 + на следующее, обновив поля, отмеченные красным, параметрами вашего приложения и Droplet:

конфиг / deploy.rb

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

set :repo_url,
set :application,
set :user,
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 и добавьте в него следующее (опять же, заменив его параметрами):

конфиг / nginx.conf

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

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

 root /home//apps//current/public;
 access_log /home//apps//current/log/nginx.access.log;
 error_log /home//apps//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 + и + Request Timeout +.

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

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

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

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

cap production deploy:initial

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

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

В Droplet, Symlink + nginx.conf в каталог` + sites-enabled`:

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

Перезапустите сервис Nginx:

sudo service nginx restart

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

Нормальные Развертывания

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

git add -A
git commit -m "Deploy Message"
git push origin master
cap production deploy

Заключение

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

Related