Деплой Ruby on Rails приложения при помощи Docker и Mina

от автора

Введение

Данное руководство в первую очередь предназначено для новичков, которые хотят научиться азам деплоя и ознакомиться в общих чертах с алгоритмом работы над удаленной unix системой локально. Итак, что же такое Mina? Это инструмент для деплоя и автоматизации выполнения операций на удаленном сервере.

Преимущество этого решения, в первую очередь, заключается в быстроте выполнения. Mina работает очень быстро, поскольку деплоит bash скрипт, который генерируется на удаленном сервере из вашего deploy.rb файла и в последствии выполняется.

Capistrano, к примеру, выполняет каждую команду отдельно, в своей ssh сессии, и поэтому уступает по скорости в разы, mina выполняет все в одном bash скрипте, который требует только одну сессию.

Требования

В этом руководстве, предполагается, что вы используете Ubuntu и у вас уже установлено следующее программное обеспечение:

Подготовка Rails приложения

Я не буду рассматривать подробно шаги создания Rails приложения, поскольку самым лучшим вариантом будет наличие у вас своего приложения, которое вы хотели бы задеплоить. Либо вы можете воспользоваться тестовым примером github.com/rails-guides/mina-deploy-example

Установка SSH / Rbenv / Ruby & Rails

Итак, у вас установлен Docker и имеется образ Ubuntu. Если все сделано верно, то при вызове команды docker images вы должны увидеть следующую информацию:

root@root:~$ docker images | grep ubuntu  ubuntu      latest      0ef2e08ed3fa      6 weeks ago      130MB 

Запускаем данную последовательность операций в консоли:

docker run -d -it -p 2222:22 ubuntu:16.04 docker ps      //Скопируйте container_id docker attach container_id 

Первая команда запустит образ Ubuntu в фоновом режиме и открытым портом для ssh подключения. Далее мы подключаемся к системе через attach с использованием уникального идентификатора контейнера.

После того, как вы вошли в систему под пользователем root, вам необходимо получить последние обновления, установить ssh-сервер и запустить его.

apt-get update apt-get install openssh-server service ssh start 

Добавляем в систему пользователя deployer, мы будем использовать его при настройке mina.

adduser deployer 

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

ssh -p 2222 deployer@0.0.0.0 

! Если у вас появится предупреждение `WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED`
Выполните удаление ключей из файла known_host с указанным сокетом (0.0.0.0:2222).

ssh-keygen -f "/home/USER/.ssh/known_hosts" -R [0.0.0.0]:2222 

После этого переподключитесь еще раз и вы увидите следующее:

deployer@e2cad98fb69d:~$ 

SSH работает, отлично! Вернемся к нашему пользователю root, нам все еще необходимо установить rbenv / ruby / rails.
В первую очередь нам потребуется git для установки rbenv.

apt-get install git 

Проследуйте шагам описанным в официальной документации для установки.

github.com/rbenv/rbenv#installation

Для работы с ruby нам нужно предустановить следующие библиотеки:

apt-get install bzip2 apt-get install -y libssl-dev libreadline-dev zlib1g-dev apt-get install build-essential 

Мне понадобится ruby версии 2.3.1 и RoR 4.2.7.1. Не забудьте определить вашу Ruby версию глобально.

rbenv install -v 2.3.1 rbenv global 2.3.1 gem install rails -v 4.2.7.1 

Установка Postgres / Nginx

apt-get install postgresql postgresql-contrib service postgresql start 

Определим пароль для пользователя postgres (все тот же 123)

su - postgres psql \password create database mina_deploy_example; //заранее создадим базу данных 

Nginx — веб-сервер и почтовый прокси-сервер, работающий на Unix-подобных операционных системах.

apt-get install nginx 

После установки измените конфигурационный файл на нижеследующий.

nano /etc/nginx/sites-available/default 
upstream mysite {   server unix:///home/deployer/mina-deploy-example/shared/tmp/sockets/puma.sock fail_timeout=0; }  server {   listen 80;   listen [::]:80;    root /home/deployer/mina-deploy-example/current/public;    location ~ ^/assets/ {       expires max;       gzip_static on;       gzip_vary on;       add_header Cache-Control public;       break;   }    location ~ ^/system/ {       expires max;       gzip_static on;       gzip_vary on;       add_header Cache-Control public;       break;   }    location / {       proxy_pass http://mysite; # match the name of upstream directive which is defined above       proxy_set_header Host $host;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   }    location ~ ^/(500|404|422).html {       root /home/deployer/mina-deploy-example/current/public;   }    error_page 500 502 503 504 /500.html;   error_page 404 /404.html;   error_page 422 /422.html;    client_max_body_size 4G;   keepalive_timeout 10; } 

Настройка git репозитория

Для деплоя через mina вам необходимо создать репозиторий на github, настроить git пользователя, сгенерировать ssh ключ и добавить его в ваш репозиторий. Для примера я буду использовать github

ssh -p 2222 deployer@0.0.0.0 git config --global user.name "Some User" git config --global user.email "someuser@example.com" ssh-keygen -t rsa -b 4096 -C "someuser@example.com" ssh -T git@github.com 

Скопируйте публичный ключ

cat ~/.ssh/id_rsa.pub 

Переходим на github → ваш репозиторий → settings → слева выбираем Deploy keys → жмем Add deploy key и вставляем скопированное значение.

Deploy при помощи mina

Переходим в директорию проекта, добавляем в Gemfile

gem 'mina' gem 'mina-puma',  require: false gem 'mina-nginx', require: false 

В папке config создайте файл deploy.rb, он будет использоваться mina при деплое приложения. Файл конфигурации состоит из нескольких основных частей.

require 'mina/bundler' require 'mina/rails' require 'mina/git' require 'mina/rbenv' require 'mina/nginx' require 'mina/puma'  set :application_name, 'mina-deploy-example' set :domain, '127.0.0.1' set :port, '2222' set :user, 'deployer' set :shared_dirs,  fetch(:shared_dirs, []).push('tmp', 'log', 'public/uploads', 'public/system') set :shared_files, fetch(:shared_files, []).push('config/puma.rb', 'config/database.yml', 'config/secrets.yml') set :deploy_to, '/home/deployer/mina-deploy-example' set :repository, 'git@github.com:rails-guides/mina-deploy-example.git' set :branch, 'master'  set :rails_env, 'production' 

В верхней части мы подключаем зависимости, устанавливаем домен приложения, порт и пользователя через которого будет создаваться bash скрипт и идти выполнение команд. На файлы и директории объвленные в shared_dirs и shared_files будет создана символическая ссылка.

Данная часть определяет команды, которые будут выполненны при вызове mina setup.

task :environment do   invoke :'rbenv:load' end  task setup: :environment do   command %{mkdir -p "#{fetch(:shared_path)}/log"}   command %{chmod g+rx,u+rwx "#{fetch(:shared_path)}/log"}      command %{mkdir -p "#{fetch(:shared_path)}/config"}   command %{chmod g+rx,u+rwx "#{fetch(:shared_path)}/config"}    command %{touch "#{fetch(:shared_path)}/config/puma.rb"}   command %{touch "#{fetch(:shared_path)}/config/database.yml"}   command %{touch "#{fetch(:shared_path)}/config/secrets.yml"}      command %{mkdir -p "#{fetch(:shared_path)}/tmp/sockets"}   command %{chmod g+rx,u+rwx "#{fetch(:shared_path)}/tmp/sockets"}   command %{mkdir -p "#{fetch(:shared_path)}/tmp/pids"}   command %{chmod g+rx,u+rwx "#{fetch(:shared_path)}/tmp/pids"} end 

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

task deploy: :environment do   deploy do     invoke :'git:clone'     invoke :'deploy:link_shared_paths'          on :build do         invoke :'bundle:install'         invoke :'rails:db_migrate'         invoke :'rails:assets_precompile'         invoke :'deploy:cleanup'     end      on :launch do         invoke :'puma:restart'     end   end end 

В директории проекта, в папке config, вам необходимо создать файл puma.rb.

directory '/home/deployer/mina-deploy-example/current' rackup '/home/deployer/mina-deploy-example/current/config.ru' environment 'production' daemonize true  pidfile '/home/deployer/mina-deploy-example/shared/tmp/pids/puma.pid' state_path '/home/deployer/mina-deploy-example/shared/tmp/sockets/puma.state'  bind 'unix:///home/deployer/mina-deploy-example/shared/tmp/sockets/puma.sock'  activate_control_app 'unix:///home/deployer/mina-deployexample/shared/tmp/sockets/pumactl.sock' 

Данный конфиг позволяет запустить сервер в фоновом режим и production окружении привязывая сервер к unix сокету. Хорошее объяснение команд для настройки puma вы можете найти в этом репозитории и официальной документации github.com/puma/puma/blob/master/examples/config.rb.

Создайте database.yml и secrets.yml в папке /home/deployer/mina-deploy-example/shared/config

production:   host: localhost   database: mina_deploy_example   adapter: postgresql   encoding: unicode   username: postgres   password: 123 
production:   secret_key_base: SECRET_KEY_BASE 

Для того, что-бы не смотреть на то, как ваш bundler постоянно ругается на то, что у вас отсутствуют определенные зависимости, установите следующие гемы и библиотеки:

gem install bundler apt-get install ruby-dev gem install json -v '1.8.6' gem install pg -v '0.20.0'  apt-get install postgresql postgresql-contrib libpq-dev gem install uglifier apt-get install nodejs apt-get install imagemagick 

Далее деплоим приложение и запускаем puma

mina deploy mina puma:start 

Прокидываем ssh тонель на порт nginx’a

sudo ssh -f -N -L 80:localhost:80 deployer@0.0.0.0 -p 2222 

При переходе по адресу http://localhost:80 вы увидите надпись New article. Если все шаги выполнены верно, то при создании новых статей и добавлении изображений все будет корректно отображаться.
ссылка на оригинал статьи https://habrahabr.ru/post/328582/


Комментарии

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

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