Деплой Rails приложения на Linux

Устанавливаем linux, настраиваем ssh доступ к серверу, работаем с файлами проекта под Linux на Windows машине, рассмотрим настройку пар серверов Nginx + Passenger, Apache + Passenger, Nginx + Unicorn, Puma + Nginx, установим Ruby on rails  с помощью rbenv, используем базу данных PostgreSQL и заставим все это хозяйство работать вместе.

Основная цель.

Основная задача – развернуть Rails-приложение на сервере Linux. Также настроить автоматическое обновление файлов проекта из удаленного git-репозитория  и автоматическое отображение обновленного приложения по адресу в интернете.

Все действия можно разделить на несколько шагов.

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

  1. Сервер Linux.

  2. Пользователи на сервере.

  3. SSH.

  4. Ruby (rbenv,rvm)

  5.  Http-сервер и сервер приложения (NGNIX, Apache + Passenger,Unicorn)

  6. База данных (Postgresql, MySQL)

  7. Репозиторий

  8. Rails-приложение

Сервер Linux.

Результат этого шага – IP-адрес сервера, который откликается на ping.
Сервером, который будет хранить и запускать файлы нашего приложения обычно является некая машина (реальная или виртуальная) с установленной ОС Linux.

Виртуальная машина на локальной машине.

Устанавливаем на локальный компьютер программу для управления виртуальными машинами VirtualBox. Она бесплатна и хороша.

Скачиваем дистрибутив Linux Ubuntu и устанавливаем его на виртуальную машину.

Также устанавливаем дополнения гостевой ОС:
меню Устройства -> подключить образ диска Дополнений гостевой ОС.
Перезапуск.
Теперь гостевая ОС Linux

По умолчанию сетевой адаптер VirtualBox настроен с типом подключения NAT. Таким образом виртуальная машина может выходить в интернет через локальную машину, но не будет видна в локальной сети.
Чтобы это исправить, нужно (ИЛИ):

  • Включить еще один Адаптер2 с типом подключения «виртуальный адаптер хоста»
  • Изменить тип подключения первого (и единственного) адаптера с "NAT" на "Сетевой мост" (bridged).

Узнать IP-адрес сервера можно, используя команду в терминале:

ifconfig

Смотрим свойство inet addr. Скорее всего это будет что-то типа 192.168.56.101

VPS (Virtual Private Server)

виртуальный сервер, предоставляемый хостинг-провайдерами в интернете. Например, DigitalOcean, самый дешевый тариф на нем 5$ в месяц. Но можно найти где-нибудь и зарегистрироваться по реферальной ссылке и получить 10$ на счет аккаунта, которых хватит на 2 месяца аренды сервера.

Следуем инструкциям при настройке удаленного сервера и получаем IP и данные SSH подключения.

Пингуем полученный IP-адрес сервера и убеждаемся, что он виден по сети.

Как сделать общую папку из Linux на Windows.

Скажем, зачем-то вам понадобилось из среды Windows получить доступ к каталогу с проектом, который лежит на Linux виртуальной машине в вашей ЛВС.  Мне, например,  нужно было запускать и тестировать проект под Linux, но редактор и все другие инструменты были установлены в Windows, и все что было нужно, это получить доступ к ним на редактирование из под Винды.

Выход - это сделать общую папку между двумя машинами.

Установим утилиту samba на Linux машине:

sudo apt-get install samba

Создадим на Linux машине в домашнем каталоге пользователя папку, которую будем делать общей. Установим ей свойства как на картинке

 

настройки общей папки Linux

Затем добавим пользователя к samba:

sudo useradd –M –N –g sambashare MyUserName

Обычно это тот же пользователь ОС.

И поменяем пароль на папку

sudo smbpasswd –a MyUserName

Теперь эта папка видна на windows по локальной сети. Эту папку можно использовать для редактирования файлов проекта в редакторе в среде windows. А сами файлы проекта будут находиться и запускаться на Linux машине.

Пользователи на сервере

На VPS создан пользователь root по умолчанию. Пользователь root  может делать на сервере все, что угодно. Поэтому лучше создать еще одного пользователя и включить его в группу sudo. Тогда этот пользователь сможет выполнять действия «как root» только если введет свой пароль. Таким образом мы немного увеличим безопасность нашего сервера.

[Опционально] установим на сервер локаль русского языка:

dpkg-reconfigure locales // следуем по диалогу и выбираем локаль ru –utf8

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

adduser maksim

Придумываем надежный пароль и запоминаем его.

Добавляем пользователя в группу sudo

adduser maksim sudo

Настройка SSH соединения

Результат этого шага – возможность подключиться из терминала (или командной строки на Windows) на сервер Linux, используя SSH протокол.

Для начала на Linux сервере нужно установить набор утилит OpenSSH. Для этого в терминале сервера набираем команду:

sudo apt-get install openssh-server

Далее на локальной машине ОС Windows.
Для работы с SSH нам понадобится утилита Putty. Качаем ее тут и устанавливаем.

Запускаем Putty.
В поле Host name (or IP address) вводим IP-адрес нашего Linux сервера.
В открывшемся окне вводим логин и пароль пользователя Linux сервера и оказываемся технически в терминале сервера и можем выполнять в нем все команды так, как если бы мы открыли терминал внутри самого Linux-сервер.

Если на локальной машине установлена ОС Linux или iOS, тогда вместо Putty используем просто терминал этой ОС

Теперь на локальной машине нужно сгенерировать пару ключей (private-public).
На Windows-машине нет полноценной поддержки OpenSSH, поэтому будем генерировать ключи с помощью утилиты PUTTYgen. Она устанавливается в одном пакете с Putty.
Подробнее о порядке генерирования ключей смотри тут.

Private-key сохраняем на локальной машине как mykey.ppk.
Public-key сохраняем на локальной машине как id_rsa.pub  и переносим на Linux-сервер.
Также сохраните текст публичного ключа из поля Public key for pasting into OpenSSH authorized_keys file в какой-нибудь текстовый файл в той же папке с ключами. Он имеет формат пригодный для OpenSSH.

Далее нам нужно скопировать публичный ключ на сервер Linux.
Сначала в домашней папке пользователя Linux создадим папку .ssh (если ее там нет) и внутри файл authorized_keys. Для этого набираем в терминале Putty команды:

mkdir ~/.ssh                          // создали каталог
chmod 0700 ~/.ssh                     // назначили права редактирования
touch ~/.ssh/authorized_keys          // создали контейнер для публичных ключей
chmod 0644 ~/.ssh/authorized_keys     // назначили права на файл

Чтобы скопировать публичный ключ на сервер в созданное нами хранилище ключей, можно воспользоваться текстовым редактором nano (встроенный в Ubuntu) или редактором Vim (его нужно установить предварительно). Открываем файл authorized_keys в редакторе вставляем туда текст публичного ключа для OpenSSH и сохраняем файл.

На локальной машине Linux, iOS.

Скопируем публичный ключ с локальной машины на сервер для пользователя deploy:

ssh-copy-id deploy@192.168.0.12  // указать реальный IP адрес сервера
ssh deploy@192.168.0.12          // проверяем можно ли залогиниться по SSH под новым пользователем

Повышаем безопасность сервера

Нужно сконфигурировать наш SSH для повышения его безопасности. Для этого нужно

  • поменять порт,
  • отключить авторизацию по паролю,
  • и включить белый список пользователей, которые могут логиниться по SSH,
  • включить в этот список нашего пользователя.

В терминале putty набираем команды:

sudo apt-get install vim         // установим текстовый редактор vim, если его еще нет
sudo vim /etc/ssh/sshd_config    // откроем в Vim файл настроек конфигурации SSH

находим и меняем следующие настройки:

Port 2503		// меняем порт по умолчанию с 22 на любой в диапазоне 1025…65536
Protocol 2		// установим версию протокола SSH2
PermitRootLogin no	// запрещаем логиниться пользователю root
UseDNS no		//
AllowUsers maksim	//  разрешаем логиниться только пользователям в этом списке

После сохранения этих настроек и перезапуска терминала вход на сервер будет возможен только по SSH, только на порт 2503 и только пользователю maksim. Поэтому нужно сохранить эту информацию где-то иначе зайти на сервер будет уже невозможно.

Перезапускаем настройки SSH

reload ssh

В случае использования PuTTY можно (и нужно) сохранить профиль подключения к серверу.
Запускаем PuTTY.
Заполняем IP и порт сервера, к которому хотим подключаться.
Connection type – SSH.
В дереве слева Connection-> Data -> в поле Auto-login user заполняем имя пользователя Linux, под которым будем заходить на сервер.
В дереве слева Connection->SSH->Auth -> в поле Private key file for authentication выбираем ранее сохраненный файл приватного ключа mykey.ppk.
В дереве слева Session -> в поле Saved Sessions пишем название настроек и нажимаем Save.
В списке ниже появится запись с только что сохраненными настройками.
В последующем из этих настроек можно будет загружать значения (Load) и соединяться с сервером с этими настройками.

Устанавливаем Ruby с помощью rbenv.

Результатом этого шага будет наличие установленных на сервере rbenv и ruby, что возможно будет проверить флагом «–v», который покажет версию этих программ.

Наберем в поисковой системе браузера «Ubuntu 16 install rbenv» и найдем страницу с инструкцией, например, эту.

Далее все инструкции взяты с этой страницы.

sudo apt-get update    // обновим все пакеты из репозиториев Ubuntu

Установка rbenv

sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
// эти пакеты нужны для rbenv
sudo apt-get install git   // установим git

Далее установим rbenv клонированием репозитория в папку ~/.rbenv

git clone https://github.com/rbenv/rbenv.git ~/.rbenv

Для автоматической загрузки rbenv добавим две настройки в конфигурационный файл bashrc:

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc

Выполним теперь этот файл:

source ~/.bashrc

Проверим, правильно ли мы настроили rbenv:

type rbenv

Должно получиться это:

rbenv is a function
rbenv ()
{
    local command;
    command="$1";
    if [ "$#" -gt 0 ]; then
        shift;
    fi;
    case "$command" in
        rehash | shell)
            eval "$(rbenv "sh-$command" "$@")"
        ;;
        *)
            command rbenv "$command" "$@"
        ;;
    esac }

Установим плагин ruby-build:

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Использование переменных окружения.

Перед тем как развернуть наше приложение мы должны установить секретный ключ (production secret key) и пароль к базе данных. Легкий способ загружать секретный ключ и пароль к базе данных в приложение во время исполнения – это использовать плагин rbenv-vars. Для использования этого плагина, его нужно просто склонировать из github репозитория:

cd ~/.rbenv/plugins
git clone https://github.com/sstephenson/rbenv-vars.git

Затем редактируем файл .rbenv-vars, просто добавляя в него пары <имя переменной>=<значение переменной>:

SECRET_KEY_BASE=<результат команды rake secret>
APPNAME_DATABASE_PASSWORD=<придуманный пароль, установленный в СУБД ранее>
APPNAME – это любое имя приложения

Чтобы посмотреть, какие переменные содержит плагин:

rbenv vars

Установка ruby.

Проверим список доступных версий ruby:

rbenv install -i

Установим последнюю версию (ну или нужную):

rbenv install 2.4.1

Сделаем эту версию языка ruby используемой по умолчанию:

rbenv global 2.4.1

Проверим версию установленного ruby:

ruby –v

Чтобы узнать где лежит исполняемый файл ruby:

which ruby

Работа с гемами.

Отключим установку документации гемов вместе с гемами. Для этого добавим строку «gem: --no-document» в файл настроек ~/.gemrc.

echo "gem: --no-document" > ~/.gemrc

Далее установим bundler, утилита которая скачивает и устанавливает гемы для ruby:

gem install bundler  // с помощью этой утилиты потом будем устанавливать RubyOnRails

Чтобы узнать куда будут установлены все гемы, наберем команду:

gem env home

 

Http-сервер и сервер приложений.

Результат этого шага – возможность увидеть сначала стартовую страницу http-сервера, а затем и созданную нами статичную html страницу по ip адресу сервера в браузере. Http-серверы чаще всего используются Apache и NGINX. Серверы приложений: Passenger и Unicorn. Они могут образовывать пары в любой комбинации.

NGINX+Passsenger

В поисковой системе браузера наберем ubuntu 16 install nginx passenger и найдем страницу с описанием установки, например, эту. Далее все инструкции будут взяты с этой страницы. Passenger NGINX

Установка.

Устанавливаем ключ passenger  и поддержку HTTP:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

Подключаем APT repository для последующей установки пакетов из него:

sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update  // обновим список пакетов из только что подключенного репозитория APT

Устанавливаем Passenger + Nginx:

sudo apt-get install nginx-extras passenger

Запустим службу http-сервера:

sudo service nginx start

Проверка В браузере введем IP-адрес сервера. Мы должны увидеть страницу приветствия “Welcome to NGINX!”.

Настройка NGINX.

Редактируем основной конфигурационный файл nginx.conf (кнопка “i” в редакторе vim):

sudo vim /etc/nginx/nginx.conf            // откроем файл в редакторе vim

найдем и раскомментируем эту строку # include /etc/nginx/passenger.conf; кнопкой esc завершаем редактирование. :wq - выход с сохранением. Редактируем конфигурационный файл passenger.conf (кнопка “i” в редакторе vim):

sudo vim /etc/nginx/passenger.conf    // открываем его в редакторе vim

нам нужно поменять путь к исполняемому файлу языка ruby passenger_ruby на результат вывода команды which ruby:

passenger_ruby /hone/maksim/.rbenv/shims/ruby;

кнопкой esc завершаем редактирование. :wq - выход с сохранением. Перезапускаем nginx:

sudo service nginx restart

Проверим, что все работает как и раньше – зайдем на стартовую страницу «Welcome to Nginx”, набрав IP адрес в браузере.

Настройки для приложения.

Создадим файл настроек для нашего приложения, чтобы сервер nginx мог его обслуживать. Для этого в папке /etc/nginx/sites-available создадим новый файл myapp (по названию приложения или как угодно):

sudo vim /etc/nginx/sites-available/myapp

Откроется текстовый редактор. В нем напишем следующий код:

server {
	listen 80 default_server;                    // порт по умолчанию для ipv4
	listen [::]:80 default_server ipv6only=on;   // порт по умолчанию для ipv6
	server_name mydomain.com;                    // когда появится домен, тут изменить
	access_log /var/log/nginx/myapp.access.log;  // файл логов для приложения
	error_log   /var/log/nginx/myapp.error.log;  // файл логов для ошибок
	passenger_enabled on;                        // говорим, чтоб будет работать passenger
	rails_env production;                        // настройка среды приложения
	root /home/maksim/www/public;                // каталог, где будет лежать приложение
}

В каталоге www будут все файлы приложения, а папка public это стандартная папка rails приложения. На данный момент ее не существует, поэтому создадим ее, находясь в домашней папке пользователя:

 mkdir –p www/public

Создадим в этой папке файл index.html с текстом «My first app!»:

echo “My first app!” > www/public/index.html

Мы создали сервер для нашего приложения в папке sites-available. Теперь, чтобы он запустился, нужно сделать символьную ссылку на него в папке sites-enabled:

sudo ln –s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp

Затем удалим сервер по умолчанию default из папки sites-enabled:

sudo rm /etc/nginx/sites-enabled/default

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

sudo service nginx restart

И проверим стартовую страницу в браузере по ip адресу нашего сервера. Должна быть страница с надписью «My first app!». Для дальнейших шагов по настройке Linux сервера остановим сервер nginx:

sudo service nginx stop

NGINX + Unicorn

В поисковике можно найти, например, такую ссылку. Этот шаг лучше делать после копирования на сервер файлов приложения (шаги 6-8). Установим Unicorn просто добавив его в gemfile и запустив bundle install в каталоге нашего приложения.

cd ~
gem install bundler

*почему-то это нужно сделать, даже если bundler уже стоит в системе. GemFile:

gem ‘unicorn’

В терминале:

bundle install --without test development // или просто bundle

Конфигурируем Unicorn.

Для этого отредактируем файл /config/unicorn.rb. Скопируем туда этот код:

# set path to application
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
working_directory app_dir

# Set unicorn options
worker_processes 2
preload_app true
timeout 30

# Set up socket location
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64

# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"
# Set master PID location
pid "#{shared_dir}/pids/unicorn.pid"

Не забудем создать каталоги, которые используются в этом файле:

mkdir -p shared/pids shared/sockets shared/log

Дадим права на запуск файла unicorn.rb:

sudo chmod 755 ~/www/config/unicorn.rb

Затем создадим скрипт запуска/остановки Unicorn. Создадим и откроем на редактирование файл скрипта

sudo vi /etc/init.d/unicorn_www

Скопируем в него следующий код:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the unicorn app server
# Description:       starts unicorn using start-stop-daemon
### END INIT INFO

set -e

USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"

# app settings
USER="maksim"
APP_NAME="www"
APP_ROOT="/home/$USER/$APP_NAME"
ENV="production"

# environment settings
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
GEM_PATH="/home/$USER/.rbenv/shims"
CMD="cd $APP_ROOT && $GEM_PATH/bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"

# make sure the app exists
cd $APP_ROOT || exit 1

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PID && kill -$1 `cat $OLD_PID`
}
case $1 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload|upgrade)
    sig USR2 && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac

Не забудем поменять значение настроек USER и APPNAME на наши значения. USER – это пользователь Linux, под которым будет запускаться Unicorn. Установим разрешения на редактирования файла и включим автозапуск при старте системы:

sudo chmod 755 /etc/init.d/unicorn_www
sudo update-rc.d unicorn_www defaults
sudo systemctl daemon-reload

Запустим службу Unicorn

sudo service unicorn_www start

Теперь наше приложение запущено в production под управлением Unicorn.

Установка и настройка NGINX.

sudo apt-get install nginx

Теперь откроем на редактирование настройку сервера для нашего приложения:

sudo vi /etc/nginx/sites-available/myapp

Заменим весь текст в нем на следующий:

upstream app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/home/maksim/www/shared/sockets/unicorn.sock fail_timeout=0;
}
server {
    listen 80;
    server_name localhost;

    root /home/maksim/www/public;

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

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

Замените deploy на имя пользователя Linux, а appname на имя вашего приложения.
Этот код конфигурирует nginx как обратный прокси таким образом, что http запросы перенаправляются на сервер приложения Unicorn через сокет Unix. Эти настройки можно изменить по необходимости.

Мы создали сервер для нашего приложения в папке sites-available. Теперь, чтобы он запустился, нужно сделать символьную ссылку на него в папке sites-enabled:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp

Удалим из sites-enabled настройку по-умолчанию:

sudo rm /etc/nginx/sites-enabled/default

Перезапустим nginx:

sudo service nginx restart

Проверяем доступность приложения по IP сервера в браузере.

Puma+NGINX

В поисковике можно найти такую ссылку. Далее инструкции из нее.

Установим Puma, просто добавив его в Gemfile:

gem ‘puma’

Затем

bundle

Конфигурируем Puma.

Нам потребуется узнать количество ядер процессора, которые имеет сервер. Это можно сделать, выполнив команду:

Grep –c processor /proc/cpuinfo</pre
Теперь создадим конфигурационный файл puma.rb в корневом каталоге приложения:
vim config/puma.rb

Скопируем туда текст файла:

# Change to match your CPU core count
workers 2
# Min and Max threads per worker
threads 1, 6
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env
# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.sock"
# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app
on_worker_boot do
  require "active_record"
  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
End

Поменяем количество workers на количество ядер процессора.
Этот файл сконфигурирует Puma под конкретно наше приложение, под его сокеты, логи и PIDы. Этот файл можно редактировать под нужды приложения, если нужно.
Создадим в приложении каталоги pids, sockets, log, на которые ссылается этот файл:

mkdir -p shared/pids shared/sockets shared/log

Создаем Puma Upstart script.

Этот скрипт нужен для возможности быстрой остановки и старта сервера Puma, а также для автоматического старта при запуске сервера.

Скачаем Jungle Upstart tool из репозитория Puma в домашний каталог пользователя.

cd ~
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma-manager.conf
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma.conf

Откроем загруженный файл puma.conf, для настройки пользователя.

vim puma.conf

Найдем такие строки setuid и setgid, и заменим ‘apps’ на имя нашего пользователя в Linux.

setuid maksim
setgid maksim

Затем скопируем оба файла в сервисный каталог Upstart:

sudo cp puma.conf puma-manager.conf /etc/init

Скрипт puma-manager.conf ссылается на файл /etc/puma.conf для получения приложений, которыми он должен управлять.
Создадим такой файл и запишем туда путь к нашему приложению:

sudo vim /etc/puma.conf

Добавим в него путь к нашему приложению

/home/maksim/www

**На Ubuntu 16.04 скрипт Upstart не запустится. Нужно еще кое-что сделать. Подробнее тут и тут

Создадим файл puma.service в каталоге /etc/system/system/ и скопируем туда текст следующего содержания:

[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
Type=simple
# Preferably configure a non-privileged user
User=appuser
# Specify the path to your puma application root
WorkingDirectory=/home/deploy/appname
# Helpful for debugging socket activation, etc.
Environment=PUMA_DEBUG=1
# Setting secret_key_base for rails production environment. We can set other Environment variables the same way, for example PRODUCTION_DATABASE_PASSWORD
Environment=SECRET_KEY_BASE=b7fbccc14d4018631dd739e8777a3bef95ee8b3c9d8d51f14f1e63e613b17b92d2f4e726ccbd0d388555991c9e90d3924b8aa0f89e43eff800774ba29
# The command to start Puma, use 'which puma' to get puma's bin path, specify your config/puma.rb file
ExecStart=/usr/local/bin/puma -C /home/deploy/appname/config/puma.rb
Restart=always
[Install]
WantedBy=multi-user.target

Не забудем поменять значения переменных User, WorkingDirectory, ExecStart на правильные.
Затем выполняем по-очередно эти команды:

sudo systemctl daemon-reload
sudo systemctl enable puma.service
sudo systemctl start puma.service

Проверить статус службы можно с помощью этих команд:

systemctl status puma.service

Если все сделано правильно, тогда в терминале увидим что-то типа этого:

puma status

Установка и настройка NGINX.

 

sudo apt-get install nginx

отредактируем дефолтный файл настроек:

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

и заменим весь код в нем на следующий:

upstream app {
    # Path to Puma SOCK file, as defined previously
    server unix:/home/maksim/www/shared/sockets/puma.sock fail_timeout=0;
}
server {
    listen 80;
    server_name localhost;
    root /home/maksim/www/public;
    try_files $uri/index.html $uri @app;
    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

Это сконфигурирует nginx как обратный прокси.
Перезапустим nginx:

Sudo service nginx restart

Проверяем доступность приложения по ip в браузере локальной машины на windows.

База данных.

Результат этого шага – возможность из консоль зайти в базу данных приложения используя флаги –user – password.

Базой данных для production может быть любая из тех, что поддерживается ActiveRecord:

  • PostgreSQL,
  • MySQL,
  • MongoDB
    и другие.

PostgreSQL

Набираем в поиске в браузере «Ubuntu 16 install postgres» и находим страницу с инструкциями по установке, например, эту.

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

Установим нужные пакеты Linux:

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Посмотреть файл конфигурации postgres можно тут:

sudo vim /etc/postgresql/9.5/main/pg_hba.conf

в нем есть настройка:

postgresql settings

которая позволяет авторизоваться в postgresql под пользователем с тем же именем, как и у пользователя Linux.
То есть, это значит, что нам достаточно создать в postgres  пользователя с именем maksim, чтобы получить возможность заходить на сервер postgres и выполнять манипуляции с базой данных.

Создаем пользователя.

Во время установки пакетов в системе Linux  был создан дополнительный пользователь Postgres для работы с этой СУБД.
Поэтому залогинимся в консоли под этим пользователем:

sudo su - postgres

Заходим в консоль postgres:

psql

Создадим пользователя с именем таким же как у пользователя Linux:

CREATE USER maksim WITH PASSWORD 'developer';    // получим ответ CREATE ROLE

Создадим базу данных под этим пользователем:

CREATE DATABASE “myapp” WITH OWNER = maksim;  // получим ответ CREATE DATABASE

выходим из консоли postgres:

\q

Выходим из пользователя postgres

exit

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

psql myapp    // получилось
\q   // Затем выходим

Пробуем подсоединиться по пользователем maksim:

psql –user maksim –password myapp // пароль потом система спросит, вводим пароль пользователя maksim в postgres.

Получилось. Теперь выходим \q
Второй способ аутентификации в postgres будет использоваться Rails-приложением при взаимодействии с базой данных. Поэтому важно убедиться, что этот способ работает:

Репозиторий.

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

rails new bookmarks
cd bookmarks
rails g scaffold title url
rake db:migrate
rails s

В браузере локальной машины по адресу localhost:3000 вы должны увидеть свое приложение.
Гасим сервер приложения Ctrl+C

Git – репозиторий.

Находясь в каталоге приложения:

git init   // инициализируем репозиторий

Переименуем файлы:

config/database.yml -> config/database.yml.example
config/secrets.yml -> config/secrets.yml.example

Эти файлы нужно исключить из репозитория. На сервере Linux мы их будем создавать вручную.
В файл .gitignore добавим строки:

config/database.yml
config/secrets.yml

В gemfile добавим гем для работы с postgres:

group :production do
   gem ‘pg’
end

Далее помещаем все файлы в репозиторий:

git add .
git commit –am “initial commit’

Создаем репозиторий на GitHub.
Подключаем удаленный репозиторий на своей локальной машине. По сути связываем репозиторий на локальной машине с репозиторием на GitHub.
Отправляем файлы локального репозитория в удаленный репозиторий:

git push –u origin master

На сервере Linux
Сгенерируем пару SSH ключей для того, чтобы этот сервер (пользователь maksim) мог общаться с репозиторием на GiHub.

ssh-keygen –t rsa

Выведем в консоль текст публичного ключа:

cat ~/.ssh/id_rsa.pub

И добавляем этот ключ в список ключей на GitHub нашего репозитория.
Удалим папку www:

rm –rf www/

склонируем удаленный репозитрий в папку www (она будет создана):

git clone  www
cd www  // зайдем в эту папку

Приложение.

Результат этого шага – работающее приложение в браузере по ip-адресу сервера Linux.
Мы получили из репозитория файлы нашего приложения, но оно еще не может быть запущено, поскольку не хватает нескольких пакетов. Установим их.

sudo apt-get install nodejs sqlite3 libsqlite3-dev libpq-dev

Установим Rails:

gem install rails –v 4.2.6

Установим все гемы, необходимые для работы приложения (они перечислены в gemfile) кроме сред test и development:

bundle install --without test development

Создаем файл config/database.yml

vim /config/database.yml

И напишем там следующее:

Production:
  adapter: postgresql
  user: maksim
  password: developer
  database: myapp

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

rbenv local 2.2.4  // указываем версию руби
gem install bundle // установим bundler для этой версии руби

подробности тут.

Прогоним миграции только для среды production:

rake db:migrate RAILS_ENV=production

Теперь нам нужно создать и заполнить файл config/srcrets.yml. Для начала сгенерируем секретный хеш:

rake secret

Результат вывода скопируем в буфер и затем вставим в файл secrets.yml

sudo vim config/secrets.yml  // создадим и/или откроем файл для редактирования

Заполняем файл таким образом:

production:
  secret_key_base: < секретный хеш, скопированный ранее>

**если используется rbenv-vars, тогда вместо секретного хеша тут должна быть ссылка на переменную окружения

secret_key_base: < %=ENV[“SECRET_KEY_BASE”] %>

В этом случае в каталоге проекта нужно создать файл .rbenv-vars и записать туда значение переменной

SECRET_KEY_BASE=< значение секретного хеша результат rake secret>

Этот файл нужно внести в .gitignore
Последнее, что нужно сделать перед запуском сервера, это скомпилировать ресурсы (assets). На серверах это делают один раз и обычно это делает Capistrano.

bundle exec rake assets:precompile RAILS_ENV=production
или
rake assets:precompile RAILS_ENV=production

Запускаем сервер NGINX:

sudo service nginx start

Если не было никакой информации в терминале, значит запустилось без проблем.

Проверяем в браузере по ip адресу сервера Linux. Мы должны увидеть наше приложение.

Доработки.

Предположим, что нам необходимо изменить что-то в приложении.
На локальной машине делаем доработки.

git add .
git commit –am “Some changes”
git push

В терминале сервера Linux:

git pull
touch tmp/restart.txt // создаем/изменяем этот файл, чтобы сервер автоматом перезагрузил

приложение, это триггер для passenger.

Обновляем страницу в браузере и видим наши изменения.

P.S. Как установить google chrome на Ubuntu 16.04

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb

 

Posted in Новости, Ruby on Rails, Deploy and tagged , , .

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

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