Деплой: Nginx, Puma и Mina

от автора

В этой небольшой статье я бы хотел показать настройку Rails — приложения работающего на Nginx’е с Puma и как это все деплоить с помощью Mina.

Будем считать, что у Вас на сервере уже установлено все окружение, кроме вышеперечисленных вещей (Я предпочитаю ставить ruby через rbenv, поэтому приведенные конфиги для Mina будут расчитаны именно на него.)

Mina
Поставить Mina очень просто — ставим гем и все (нет нужды помещать установку в Gemfile):
gem install mina

Затем ввести команду:
mina init

Данная команда сгенерирует файл config/deploy.rb, который будет содержать минимально необходимую конфигурацию.
Помните, что git у Вас должен быть сконфигурирован или (на крайний случай) логин и пароль от репозитория можно прописать прямо в файле конфига Mina, как приведено в примере. У Вас должны существовать все настройки, которые касаются баз данных. Также хочу отметить, что если у Вас не создано каких — либо папок/файлов, приведенных в конфиге, необходимо их создать.
Пример полной конфигурации:

deploy.rb

require 'mina/bundler' require 'mina/rails' require 'mina/git' require 'mina/rbenv'  lock '3.2.1'  set :user, 'admin' set :domain, '100.100.100.100' set :identity_file, "#{ENV['HOME']}/.ssh/google" set :deploy_to, '/var/www/admin_app' set :app_path, lambda { "#{deploy_to}/#{current_path}" } set :repository, 'https://admin:admin@github.com/Admin_app.git' set :branch, 'master' set :forward_agent, true   set :rbenv_path, '/home/admin/.rbenv/' set :shared_paths, ['config/database.yml', 'log']  task :environment do    invoke :'rbenv:load' end  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! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]   queue  %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'."] end  desc "Deploys the current version to the server." task :deploy => :environment do   to :before_hook do     # Put things to run locally before ssh   end   deploy do     invoke :'git:clone'     invoke :'server:stop_server'     invoke :'deploy:link_shared_paths'     invoke :'bundle:install'     invoke :'rails:db_migrate'     invoke :'rails:assets_precompile'     invoke :'deploy:cleanup'      to :launch do       queue "mkdir -p #{deploy_to}/#{current_path}/tmp/"       queue "touch #{deploy_to}/#{current_path}/tmp/restart.txt"       invoke :'server:start_server'     end   end end  namespace :server do   desc 'Stop server'   task :stop_server do     queue 'echo "-----> Stop Server"'     queue 'kill -9 $(lsof -i :3000 -t) || true'     queue '[ -f /var/www/admin/admin_app.pid ] && rm /var/www/admin/admin_app.pid || echo "File admin_app.pid not exist"'   end    desc 'Start server'   task :start_server do     queue 'echo "-----> Start Server"'     queue! 'rails s -b 0.0.0.0 -e production -P /var/www/admin/admin_app.pid -d &'   end end 

После того, как Вы убедились, что Ваш файл deploy.rb похож на правду и вроде должен работать, нужно ввести команду:
mina setup

Данная команда создаст необходимую инфраструктуру папок внутри корневой папки для вашего приложения(в конфиге это /var/www/admin_app).
Убедитесь, что файл database.yml содержит информацию и она верна. Файл находится в /var/www/myapp/shared/config.
Далее вводим:
mina deploy

Если данная операция прошла успешно, Ваше приложение будет ждать Вас по пути: /var/www/admin_app.

Вы можете легко расширять свой деплой, прописывая task’и в deploy.rb и вызывая их внутри :deploy => :environment.
Например, напишем два task’а, для запуска и остановки resque — воркеров.

Task'и для resque

desc 'Start resque-workers'    task :start_workers do     queue 'echo "-----> Start resque-workers"'     queue "cd #{app_path} && RAILS_ENV=#{stage} && touch resque.pid"     queue "cd #{app_path} &&  bundle exec rake resque:work QUEUE=contacts_adder BACKGROUND=yes TERM_CHILD=1"     queue "cd #{app_path} &&  bundle exec rake resque:work QUEUE=photo_downloader BACKGROUND=yes TERM_CHILD=1"     # Запуск по задачи по расписанию     queue 'echo "-----> Start resque-scheduler"'     queue "cd #{app_path} && rake resque:scheduler BACKGROUND=yes VERBOSE=yes RAILS_ENV=production "   end    desc 'Stop resque-workers'   task :stop_workers do     queue 'echo "-----> Stop resque-workers"'     queue 'kill -9 `ps aux | grep [r]esque | grep -v grep | cut -c 10-16` || true'   end 

Вы можете просматривать список доступных task’ов с помощью команды:
mina tasks

Puma
Для настройки Puma понадобится два файла: файл конфигурации puma.rb и shell — скрипт, предназначенный для запуска/остановки/рестарта Puma.

Создайте файл puma.rb в config/. И заполните его следующей информацией:

puma.rb

#!/usr/bin/env puma environment ENV['RAILS_ENV'] || 'production' pidfile "/var/www/admin/current/shared/tmp/pids/puma.pid" stdout_redirect "/var/www/admin/current/shared/tmp/log/stdout", "/var/www/admin/current/shared/tmp/log/stderr" threads 2, 16 workers 2 bind "unix:///var/www/admin/current/shared/tmp/sockets/puma.sock" daemonize true 

Внимательно проверяйте пути при заполнении конфигов!

Создайте файл bin/puma.sh. Заполните его:

puma.sh

#! /bin/sh PUMA_CONFIG_FILE=/var/www/admin/current/config/puma.rb PUMA_PID_FILE=/var/www/admin/current/shared/tmp/pids/puma.pid PUMA_SOCKET=/var/www/admin/current/shared/tmp/sockets/puma.sock  # check if puma process is running puma_is_running() {   if [ -e $PUMA_SOCKET ] ; then     if [ -r $PUMA_PID_FILE ] ; then        if ps -p `cat $PUMA_PID_FILE` > /dev/null; then         return 0       else         echo "No puma process found"       fi     else       echo "No puma pid file found"     fi   else     echo "No puma socket found"   fi    return 1 }  case "$1" in   start)     echo "Starting puma..."       if [ -e $PUMA_SOCKET  ] ; then # if socket exists         rm -f $PUMA_SOCKET         echo "removed $PUMA_SOCKET"       fi       if [ -e $PUMA_CONFIG_FILE ] ; then         echo "config"         bundle exec puma -C $PUMA_CONFIG_FILE       else         echo "socket"         bundle exec puma --daemon --bind unix://$PUMA_SOCKET --pidfile $PUMA_PID_FILE       fi      echo "done"     ;;    stop)     echo "Stopping puma..."       kill -s SIGTERM `cat $PUMA_PID_FILE`       rm -f $PUMA_PID_FILE       rm -f $PUMA_SOCKET      echo "done"     ;;    restart)     if puma_is_running ; then       echo "Hot-restarting puma..."       kill -s SIGUSR2 `cat $PUMA_PID_FILE`        echo "Doublechecking the process restart..."       sleep 5       if puma_is_running ; then         echo "done"         exit 0       else         echo "Puma restart failed :/"         exit 1       fi     fi      echo "Trying cold reboot"     bin/puma.sh start     ;;    *)     echo "Usage: script/puma.sh {start|stop|restart}" >&2     ;; esac 

Теперь дополним файл deploy.rb настройками Puma:

Task'и для Puma

 namespace :puma do   desc 'Start the application'   task :start do     queue 'echo "-----> Start Puma"'     queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh start" , :pty => false   end    desc 'Stop the application'   task :stop do     queue 'echo "-----> Stop Puma"'     queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh stop"   end    desc 'Restart the application'   task :restart do     queue 'echo "-----> Restart Puma"'     queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh restart"   end end 

Внутри блока «to :launch do»(перед стартом сервера) пропишем:

invoke :'puma:restart' 

Не забудьте сделать файл puma.sh исполняемым:
chmod +x bin/puma.sh

И заново производим деплой:
mina deploy

Nginx
Nginx можно ставить прямо из пакетного менеджера:
sudo apt-get install nginx

После того, как nginx установлен нужно удалить default site.
sudo rm /etc/nginx/conf.d/sites-enabled/default

Создайте файл /etc/nginx/sites-available/my_app.conf:

Конфиг nginx'a

upstream my_app {           server unix:///var/www/admin/current/shared/tmp/sockets/puma.sock;         } server {     listen 80;     server_name 100.100.100.100; # change to match your URL     root /var/www/admin/current/public;      location / {         root /var/www/admin/current/public;         try_files $uri @app;         gzip_static on;         expires max;         add_header Cache-Control public;     }      location @app {      proxy_pass        http://my_app;      proxy_set_header  X-Real-IP  $remote_addr;      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;      proxy_set_header  X-Forwarded-Proto http;      proxy_set_header  Host $http_host;      proxy_redirect    off;      proxy_next_upstream error timeout invalid_header http_502;     } 

Если вдруг возникли какие — то проблемы, можно попробовать прописать данные строчки прямо в файле /etc/nginx/nginx.conf. Информация о сервере (server {}), должна находиться внутри блока http(http{}).

Затем создадим ссылку:
sudo ln -sf /etc/nginx/sites-available/my_app.conf /etc/nginx/sites-enabled/my_app.conf

И сделаем перезапуск nginx’a:
sudo service nginx restart

Вот собственно и все. Приятного деплоя 🙂

ссылка на оригинал статьи http://habrahabr.ru/post/265459/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *