Статьи

Разверните приложение Rails на AWS

Векторная иллюстрация персонального компьютера, показывая окно с названием развертывания, изолированных на белом

Как разработчики, мы обычно заботимся о разработке любого приложения. Мы мало думаем о части развертывания, так как считаем, что это ответственность SysAdmins. Но часто у нас нет выделенного SysAdmin, поэтому мы должны надеть шапку SysAdmin и добиться цели. Существует много вариантов развертывания вашего Rails-приложения. Сегодня я расскажу, как развернуть приложение Rails в Amazon Web Services (AWS) с помощью Capistrano.

Мы будем использовать стек Puma + Nginx + PostgreSQL. Puma будет сервером приложений, Nginx — обратным прокси, а PostgreSQL — сервером базы данных. Этот стек также можно использовать в MRI Ruby или JRuby. Большинство шагов остаются одинаковыми для обоих рубинов, но я выделю, где они также различаются.

Если у вас есть существующее приложение, вы можете пропустить следующий раздел и перейти непосредственно к следующему разделу.

Пример приложения Rails

Давайте создадим пример приложения Rails с моделью контакта и CRUD. Приложение использует Rails 4.2 и PostgreSQL:

rails new contactbook -d postgresql

После того, как приложение сгенерировано, создайте модель контактов и CRUD:

 cd contactbook
rails g scaffold Contact name:string address:string city:string phone:string email:string

Установите имя пользователя и пароль вашей базы данных в config/database.yml

 rake db:create && rake db:migrate

Давайте проверим, как это работает:

 rails s

Направьте ваш любимый браузер на http: // localhost: 3000 / contacts и проверьте, все ли работает правильно.

Настройка Puma & Capistrano

Теперь мы настроим приложение для развертывания. Как упоминалось ранее, Puma является сервером приложений, а Capistrano — нашим инструментом развертывания. Capistrano обеспечивает интеграцию для Puma и RVM, поэтому добавьте эти драгоценные камни в Gemfile. Мы также будем использовать гем figaro для сохранения конфигурации приложения, такой как пароль рабочей базы данных и секретный ключ:

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

Установите драгоценные камни через упаковщик:

 bundle install

Пришло время настроить Capistrano, сначала сгенерировав файл конфигурации, следующим образом:

 cap install STAGES=production

Это создаст файлы конфигурации для Capistrano по адресу config / deploy.rb и config / deploy / production.rb . deploy.rb — это основной файл конфигурации, а production.rb содержит параметры среды, такие как IP-адрес сервера, имя пользователя и т. д.

Добавьте следующие строки в Capfile , который находится в корне приложения. По завершении Capfile включает задачи интеграции RVM, Rails и Puma:

 require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/rails/assets' # for asset handling add
require 'capistrano/rails/migrations' # for running migrations
require 'capistrano/puma'

Теперь отредактируйте файл deploy.rb следующим образом:

 lock '3.4.0'

set :application, 'contactbook'
set :repo_url, '[email protected]:devdatta/contactbook.git' # Edit this to match your repository
set :branch, :master
set :deploy_to, '/home/deploy/contactbook'
set :pty, true
set :linked_files, %w{config/database.yml config/application.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}
set :keep_releases, 5
set :rvm_type, :user
set :rvm_ruby_version, 'jruby-1.7.19' # Edit this if you are using MRI Ruby

set :puma_rackup, -> { File.join(current_path, 'config.ru') }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"    #accept array for multi-bind
set :puma_conf, "#{shared_path}/puma.rb"
set :puma_access_log, "#{shared_path}/log/puma_error.log"
set :puma_error_log, "#{shared_path}/log/puma_access.log"
set :puma_role, :app
set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production'))
set :puma_threads, [0, 8]
set :puma_workers, 0
set :puma_worker_timeout, nil
set :puma_init_active_record, true
set :puma_preload_app, false

Мы отредактируем production.rb позже, так как мы еще не знаем IP сервера и другие детали.

Кроме того, создайте config / application.yml, чтобы сохранить любые специфичные для среды параметры в среде разработки. Этот файл используется гемом figaro для загрузки настроек в переменные окружения. Мы создадим тот же файл и на рабочем сервере.

Следует помнить одну вещь: исключить config / database.yml и config / application.yml из репозитория Git. Оба файла содержат конфиденциальные данные, которые не следует проверять в системе контроля версий для очевидных проблем безопасности.

Создание экземпляра EC2

С приложением, настроенным и готовым к развертыванию, пришло время запустить новый экземпляр EC2. Войдите в консоль управления EC2 (очевидно, вам необходимо зарегистрировать учетную запись AWS):

рельсы-AWS-1

Нажмите «Запустить экземпляр»:

рельсы-AWS-2

Выберите образ машины Amazon (AMI). Мы будем использовать «Ubuntu Server 14.04 LTS»:

рельсы-AWS-3

Выберите тип экземпляра согласно вашему требованию. Я выбираю «t2.micro», потому что это бесплатно / дешево. Для реального производственного сервера вы бы хотели пойти больше. Нажмите «Далее: Настройка подробностей экземпляра», чтобы продолжить.

рельсы-AWS-4

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

рельсы-AWS-5

Объем хранилища по умолчанию составляет 8 ГБ. Отрегулируйте согласно вашему требованию к месту. Нажмите «Далее: экземпляр тега»

рельсы-AWS-6

Введите имя экземпляра. Нажмите «Далее: Настроить группу безопасности».

рельсы-AWS-7

Нажмите «Добавить правило». Выберите «HTTP» из «Типа». Это необходимо для того, чтобы сервер nginx был доступен из Интернета. Нажмите «Просмотр и запуск»

рельсы-AWS-8

Проверьте правильность всех настроек. Нажмите «Запустить»

рельсы-AWS-9

Выберите или создайте пару ключей для подключения к экземпляру. У вас должен быть закрытый ключ на вашем локальном ящике, чтобы подключиться к экземпляру EC2. Ключ должен находиться в вашем каталоге ~ / .ssh . Установите флажок «Я подтверждаю это…» и нажмите «Запустить экземпляр». Подождите, пока экземпляр запустится.

рельсы-AWS-10

Экземпляр должен быть в рабочем состоянии. Выберите экземпляр и нажмите «Подключиться».

рельсы-AWS-11

Запишите «публичный IP-адрес» (на скриншоте 52.2.139.74. Ваш будет другим). Нам понадобится это для подключения к серверу.

Настройте сервер

Теперь мы подготовили сервер, и пришло время настроить некоторые основные вещи. Прежде всего, SSH на сервер с нашим выбранным закрытым ключом. Замените «Devdatta.pem» полным путем к вашему личному ключу:

 ssh -i "Devdatta.pem" [email protected]

Вы вошли на совершенно новый сервер. Сначала обновите существующие пакеты:

 sudo apt-get update && sudo apt-get -y upgrade

Создайте пользователя с именем deploy

 sudo useradd -d /home/deploy -m deploy

Это создаст пользовательское deploy Приложение будет развернуто в этом каталоге. Установите пароль для пользователя deploy

 sudo passwd deploy

Введите пароль и подтвердите его. Этот пароль потребуется RVM для установки Ruby. Также добавьте пользователя deploy Запустите sudo visudo

 deploy ALL=(ALL:ALL) ALL

Сохраните файл и выйдите.

Поскольку мы будем использовать GitHub для размещения нашего Git-репозитория, пользователю deploy Таким образом, мы сейчас сгенерируем пару ключей для этого пользователя:

 su - deploy
ssh-keygen

Не устанавливайте ключевую фразу для ключа, так как она будет использоваться в качестве ключа развертывания.

 cat .ssh/id_rsa.pub

Скопируйте вывод и установите его как ключ развертывания на GitHub .

Capistrano подключится к серверу через ssh для развертывания в качестве учетной записи deploy Поскольку AWS допускает только аутентификацию с открытым ключом, скопируйте открытый ключ с локального компьютера в учетную запись пользователя deploy В большинстве случаев открытый ключ — это ваш ключ ~/.ssh/id_rsa.pub На сервере:

 nano .ssh/authorized_keys

Вставьте ваш локальный открытый ключ в файл. Сохранить и выйти.

Git требуется для автоматического развертывания через Capistrano, поэтому установите Git на сервер:

 sudo apt-get install git

Если вы используете JRuby, установите виртуальную машину Java (JVM):

 sudo apt-get install openjdk-7-jdk

Установка Nginx

Сначала установите Nginx, который является нашим обратным прокси:

 sudo apt-get install nginx

Теперь настройте сайт по умолчанию как наше требование. Откройте файл конфигурации сайта:

 sudo nano /etc/nginx/sites-available/default

Закомментируйте существующий контент и вставьте следующее в файл.

 upstream app {
  # Path to Puma SOCK file, as defined previously
  server unix:/home/deploy/contactbook/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80;
  server_name localhost;

  root /home/deploy/contactbook/public;

  try_files $uri/index.html $uri @app;

  location / {
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Connection '';
    proxy_pass http://app;
  }

  location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

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

Сохраните файл и выйдите. Мы настроили nginx в качестве обратного прокси-сервера для перенаправления HTTP-запросов на сервер приложений Puma через сокет UNIX. Мы пока не будем перезапускать nginx, так как приложение готово. Давайте установим PostgreSQL сейчас.

Установка PostgreSQL

 sudo apt-get install postgresql postgresql-contrib libpq-dev

После установки postgreSQL создайте производственную базу данных и ее пользователя:

 sudo -u postgres createuser -s contactbook

Установите пароль пользователя из консоли psql

 sudo -u postgres psql

После входа в консоль измените пароль:

 postgres=# \password contactbook

Введите новый пароль и подтвердите его. Выйдите из консоли с помощью \q Пришло время создать базу данных для нашего приложения:

 sudo -u postgres createdb -O contactbook contactbook_production

Установка RVM & Ruby

Мы будем использовать RVM для установки желаемой версии Ruby:

 su - deploy
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable

Это установит RVM в домашний каталог пользователя deploy Выйдите из системы и войдите снова, чтобы загрузить RVM в оболочку пользователя deploy Выйдите из системы с помощью Ctrl + D и войдите снова с помощью su - deploy

Теперь установите Ruby:

Для использования MRI Ruby — rvm install ruby

Для JRuby — rvm install jruby

После установки Ruby перейдите на установленную версию:

 rvm use jruby

ИЛИ

 rvm use ruby

Установить пакет:

 gem install bundler --no-ri --no-rdoc

Создайте каталоги и файлы, необходимые для Capistrano. Мы создадим файлы database.yml и application.yml для хранения настроек базы данных и других специфических данных среды:

 mkdir contactbook
mkdir -p contactbook/shared/config
nano contactbook/shared/config/database.yml

Вставьте следующее в database.yml :

 production:
  adapter: postgresql
  encoding: unicode
  database: contactbook_production
  username: contactbook
  password: contactbook
  host: localhost
  port: 5432

После этого создайте application.yml

 nano contactbook/shared/config/application.yml

и добавьте следующее:

 SECRET_KEY_BASE: "8a2ff74119cb2b8f14a85dd6e213fa24d8540fc34dcaa7ef8a35c246ae452bfa8702767d19086461ac911e1435481c22663fbd65c97f21f6a91b3fce7687ce63"

Измените секрет на новый, используя команду rake secret

Хорошо, мы почти закончили с сервером. Вернитесь на свой локальный компьютер, чтобы начать развертывание с Capistrano. Отредактируйте файл config / deploy / production.rb, чтобы установить IP-адрес сервера. Откройте файл и вставьте следующее в файл. Измените IP-адрес в соответствии с IP-адресом вашего сервера:

 server '52.2.139.74', user: 'deploy', roles: %w{web app db}

Теперь давайте начнем развертывание с использованием Capistrano:

 cap production deploy

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

 sudo service nginx restart

Откройте браузер и укажите его / контактам . Приложение должно работать правильно.

рельсы-AWS-12

Заворачивать

Сегодня мы узнали, как развернуть приложение Rails на AWS с Capistrano. Наше приложение, будучи простым, не использует дополнительные сервисы, такие как фоновые задания, поэтому сегодня я не рассматривал это. Но установка и настройка таких сервисов могут потребоваться для сложных приложений. Но это на другой день.

Ваши комментарии и мнения всегда приветствуются.