Настройка И Развертывание Сервера: Rvm,Rails,Puma,Nginx,Mina.



Фон На создание этой статьи меня побудил недавний публикация о развертывании .

В вышеприведенной статье описан метод развертывания проекта на базе rbenv, я же опишу ситуацию с rvm и настройку выскочки.



Цели и требования

Итак, дано: простейшее приложение RubyOnRails. В случае развертывания своего проекта я поставил перед собой следующие задачи:
  • ОС Ubuntu LTS 14.04;
  • веб-сервер Nginx;
  • сервер приложений Puma;
  • Использование RVM для установки необходимой версии Ruby;
  • Автоматический запуск приложения при запуске VPS-сервера, возможность управления приложением как сервисом;
  • Автоматизация процесса развертывания с помощью mina;
Почему Убунту? Я просто привык к нему (точнее к его производному — Linux Mint).

Почему пума, а не единорог или пассажир? Я слышал хорошие отзывы о Puma, но у Unicron ужасный сайт. Пассажир, на мой взгляд, нарушает принцип единой ответственности — я хочу иметь веб-сервер и сервер приложений.

Почему РВМ? Я к этому привык — он у меня установлен на локальной машине, и я хочу увидеть его и в продакшене.

Почему мина? Это действительно проще, чем капистрано, и в то же время быстрее.

Скорость достигается за счет того, что capistrano создает для каждой задачи отдельное SSH-соединение.

Мина генерирует сценарий оболочки и выполняет его в рамках одного соединения.

В данном случае задачу легко разделить на 3 этапа:

  1. Убедитесь, что приложение запускается корректно (пока без автоматизации);
  2. Настройте сервер так, чтобы наше Rails-приложение работало как полноценный сервис;
  3. Исходя из этого, настройте автоматическое развертывание с помощью min.


Первый старт

На сервере создан пользователь веб-приложения, от имени которого будет запускаться наше приложение.

Установлен rvm (в данном примере только для пользователя веб-приложения), Ruby нужной нам версии, nginx и так далее.

Gemfile содержит следующую строку:

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   

# .

gem 'puma', group: :production # .



Предварительная настройка мины Добавьте следующую строку в Gemfile:

gem 'mina', group: :development

Затем генерируем файл конфигурации командой:

mina init

Затем приведем созданный файл config/deploy.rb к следующему виду: config/deploy.rb

require 'mina/bundler' require 'mina/rails' require 'mina/git' set :domain, 'awesome_address' set :user, 'webapp' set :deploy_to, '/home/webapp/awesome' set :repository, ' https://github.com/awesome_user/awesome.git ' set :branch, 'master' set :shared_paths, ['config/database.yml', 'config/secrets.yml', 'config/puma.rb', 'log'] task :setup => :environment do queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"] queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"] queue! %[mkdir -p "#{deploy_to}/#{shared_path}/puma"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/puma"] queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"] queue! %[touch "#{deploy_to}/#{shared_path}/config/secrets.yml"] queue! %[touch "#{deploy_to}/#{shared_path}/config/puma.rb"] queue %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml', 'secrets.yml' and puma.rb."] end desc "Deploys the current version to the server." task :deploy => :environment do deploy do # Put things that will set up an empty directory into a fully set-up # instance of your project. invoke :' git:clone ' invoke :' deploy:link_shared_paths ' invoke :' bundle:install ' #invoke :' rails:db_migrate ' #invoke :' rails:assets_precompile ' #invoke :' deploy:cleanup ' end end

Этот файл содержит закомментированные строки кода, отвечающие за выполнение рутинных операций по развертыванию проекта.

Пока мы будем выполнять эти действия вручную.

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

Затем запускаем команду:

mina setup

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

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

Ниже приведен пример минимальной конфигурации для puma. puma.рб

environment "production" bind " unix:///home/webapp/awesome/shared/puma/puma.sock " pidfile "/home/webapp/awesome/shared/puma/puma.pid" state_path "/home/webapp/awesome/shared/puma/puma.state" activate_control_app

Также я сознательно не храню файл puma.rb в контроле версий, потому что.

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

На заметку, просто создайте в приложении файл config/puma.sample.rb с примером.

Теперь приступим к «развертыванию» нашего приложения:

mina deploy

После выполнения этой команды на сервере появится символическая ссылка /home/webapp/awesome/current на папку с кодом нашего проекта.

Настройка nginx Давайте создадим файл /etc/nginx/sites-available/awesome со следующим содержимым: потрясающий

upstream awesome { server unix:///home/webapp/awesome/shared/puma/puma.sock ; } server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; root /home/webapp/awesome/current/public; server_name localhost; location / { proxy_pass http://awesome ; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ~* ^/assets/ { # Per RFC2616 - 1 year maximum expiry expires 1y; add_header Cache-Control public; # Some browsers still send conditional-GET requests if there's a # Last-Modified header or an ETag header even if they haven't # reached the expiry date sent in the Expires header. add_header Last-Modified ""; add_header ETag ""; break; } }

Затем мы создадим символическую ссылку:

cd /etc/nginx/sites-enabled/ ln -s .

/sites-available/awesome awesome

И перезапускаем nginx:

service nginx restart

Ручной запуск приложения Теперь подготовим и запустим наш проект. Мы готовы:

cd /home/webapp/awesome/current bash --login rvm use ruby-2.2.1 bundle install --without development:test --path .

/vendor/bundle --deployment RAILS_ENV=production bundle exec rake db:migrate RAILS_ENV=production bundle exec rake assets:precompile

Запустим:

bundle exec puma -C config/puma.rb

Открываем проект в браузере — всё должно работать.



Приложение как услуга

Чтобы приложение работало как служба и запускалось при старте/перезагрузке системы, необходимо создать скрипт init.d или конфигурацию выскочки.

Я выбрал выскочку, потому что полученный файл намного короче и его легче понять.

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

rvm alias create awesome ruby-2.2.1@default

Затем мы создаем конфигурацию выскочки /etc/init/awesome.conf: Awesome.conf

description "Awesome puma service" # This starts upon bootup and stops on shutdown start on runlevel [2345] stop on runlevel [06] setuid webapp setgid webapp respawn respawn limit 3 30 script cd /home/webapp/awesome/current /home/webapp/.

rvm/wrappers/awesome/bundle exec puma -C config/puma.rb end script

И теперь мы можем сделать это:

start awesome stop awesome restart awesome status awesome



Окончательная автоматизация

Поскольку развертывание будет происходить от имени пользователя веб-приложения, а для перезапуска сервиса нужны права суперпользователя, то добавим соответствующую строку в sudoers. Давайте запустим команду:

visudo

Добавлять:

webapp ALL=(ALL) NOPASSWD: /sbin/start awesome, /sbin/stop awesome, /sbin/restart awesome, /sbin/status awesome

И мы экономим.

И снова мина В таких случаях mina предлагает использовать собственный модуль mina/rvm, но rvm дает нам возможность создавать псевдонимы для версий Ruby и гемсетов — оберток.

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

set :bundle_bin, '/home/webapp/.

rvm/wrappers/awesome/bundle'

Добавим еще задачу на перезапуск сервера:

desc "Restart the puma web server." task :restart do queue 'sudo restart awesome' end

Добавив все это и раскомментировав нужные строки в задаче развертывания, получим следующее: Deploy.rb

require 'mina/bundler' require 'mina/rails' require 'mina/git' set :domain, 'awesome_address' set :user, 'webapp' set :deploy_to, '/home/webapp/awesome' set :repository, ' https://github.com/awesome_user/awesome.git ' set :branch, 'master' set :bundle_bin, '/home/webapp/.

rvm/wrappers/awesome/bundle' set :shared_paths, ['config/database.yml', 'config/secrets.yml', 'config/puma.rb', 'log'] task :setup => :environment do queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"] queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"] queue! %[mkdir -p "#{deploy_to}/#{shared_path}/puma"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/puma"] queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"] queue! %[touch "#{deploy_to}/#{shared_path}/config/secrets.yml"] queue! %[touch "#{deploy_to}/#{shared_path}/config/puma.rb"] queue %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml', 'secrets.yml' and puma.rb."] end desc "Deploys the current version to the server." task :deploy => :environment do deploy do # Put things that will set up an empty directory into a fully set-up # instance of your project. invoke :' git:clone ' invoke :' deploy:link_shared_paths ' invoke :' bundle:install ' invoke :' rails:db_migrate ' invoke :' rails:assets_precompile ' invoke :' deploy:cleanup ' to :launch do invoke :'restart' end end end desc "Restart the puma web server." task :restart do queue 'sudo restart awesome' end

Все готово! Теперь мы можем снова запустить развертывание проекта и посмотреть на результат:

mina deploy



Альтернативы

В качестве альтернативы можно рассмотреть Пума-джунгли .

Это шаблоны скриптов upstart и init.d, которые корректно работают с rbenv, rvm и другими менеджерами версий.

В случае с rvm необходимо убедиться, что версия Ruby и gemset, если они используются, определены правильно — для этого можно использовать файлы .

ruby-version и .

ruby-gemset. Вы можете поместить их в систему контроля версий, а можете создать во время развертывания через mina. Вам также придется использовать библиотеку mina/rvm и создать задачу для установки правильной версии Ruby и Gemset. Все вместе это может выглядеть так: Deploy.rb

# .

# Rvm ruby version and gemset rvm = { ruby_version: 'ruby-2.2.1', ruby_gemset: 'default' } task :environment do invoke :"rvm:use[#{rvm[:ruby_version]}@#{rvm[:ruby_gemset]}]" end # .

desc "Creates appropriate .

ruby-version and .

ruby-gemset files." task :'rvm:dot_files' do queue! %[echo "#{rvm[:ruby_version]}" > .

ruby-version] queue! %[echo "#{rvm[:ruby_gemset]}" > .

ruby-gemset] end task :setup => :environment do # .

end task :deploy => :environment do deploy do invoke :'git:clone' invoke :'rvm:dot_files' # .

end end # .





Конец

На этом моя публикация заканчивается.

Надеюсь, это было интересно и полезно.

Теги: #rails #rvm #Upstart #mina #puma #ubuntu #ruby onrails

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.