среда, 8 октября 2014 г.

How To Add Swap on Ubuntu Linux

Если вашей системе не хватает оперативной памяти для выполнения каких-либо задач, можно либо увеличить физический размер ОЗУ, либо настроить swapping (механизм виртуальной памяти, когда данные из ОЗУ перемещаются на жесткий диск).

Данная статья описывает процесс добавления swap файла в linux. Если swap файл уже существует, и необходимо лишь увеличить его размер, можно просто добавить еще один extra swap.

Проверьте существование swap файла


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

sudo swapon -s
Пустой список сигнализирует вам о том, что swap файла не существует:

Filename        Type       Size  Used Priority

Если swap файл уже существует, придумайте имя для нового swap файла, отличающееся от имени существующего.

Проверьте систему


Далее нужно проверить, сколько места доступно на жестком диске. В этом примере Swap файл будет занимать 256 Мб на сервере. Введите команду:

df

После этого вам будет показана информация о занятом пространстве на жестком диске:

Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/vda        20509308 3033068  16411384  16% /
none                   4       0         4   0% /sys/fs/cgroup
udev              240132       4    240128   1% /dev
tmpfs              50188     328     49860   1% /run
none                5120       0      5120   0% /run/lock
none              250932       0    250932   0% /run/shm
none              102400       0    102400   0% /run/user

В данном случае, в разделе /dev/vda использовано всего 16% от 20 Гб дискового пространства. Можем создать swap файл размером 256 Мб.

Создайте и задействуйте swap файл


Пришло время создать swap файл командой dd (утилита для копирования данных из одного файла в другой):

sudo dd if=/dev/zero of=/swapfile bs=1024 count=256k

"if='/dev/zero" - файл, из которого копировать информацию. /dev/zero представляет собой источник нулевых байтов в unix системах.
"of=/swapfile" означает имя создаваемого swap файла.

Далее подготавливаем swap файл, создавая для него место в системе:

sudo mkswap /swapfile

На экране появится следующее:

Setting up swapspace version 1, size = 262144 KiB
no label, UUID=90faca87-ad4d-4a70-bc80-c1cab1c88fbd

Завершаем все активацией swap файла:

sudo swapon /swapfile

Теперь, выполнив команду swapon -s можно посмотреть только что добавленный swap файл:

swapon -s
Filename Type Size Used Priority
/swapfile       file 262144 0 -1

Этот файл будет существовать на сервере, пока он не будет перезапущен. Чтобы этого избежать добавьте следующее в fstab файл.

Откройте файл:

sudo vim /etc/fstab

Допишите следующую строку:

/swapfile none swap sw 0 0


И конечно же защитите файл от чтения и записи пользователями:

sudo chown root:root /swapfile
sudo chmod 0600 /swapfile

Интенсивность использования swap файла


За интенсивность использования swap файла системой отвечает параметр swappiness, принимающий значение от 0 до 100. Если он равен 0, то swap используется только в случае крайней необходимости, например, когда загруженность ОЗУ равна 100%. Если он равен 100, то swap используется с наибольшим приоритетом.

По умолчанию swappiness равен 60. Можно отдать меньший приоритет, чтобы предотвратить утечку памяти во время использования swap файла.

Выполните команды:

echo 10 | sudo tee /proc/sys/vm/swappiness
echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf



среда, 3 сентября 2014 г.

Rails. Полезные статьи

В этом разделе я приведу статьи и книги о Ruby On Rails, которые, по моему мнению, не нуждаются в дополнениях а так же переведены на русский язык или не требуют перевода.

Замечательная книга Ruby On Rails Tutorial:
Оригинал книги на английском языке
Перевод книги Ruby on Rails Tutorial

Сравнение популярных серверов приложений для Ruby:
A Comparison of Popular Ruby Application Servers

Транзакции в Ruby On Rails:

AngularJS и Rails 4:

среда, 13 августа 2014 г.

Ruby. Specific features. Специфические особенности

Ruby - интерпретируемый динамичный язык программирования высокого уровня, пришедший к нам из далекой утонченной страны Японии (Аниме!!!!!). Его так же сложно понять, как и умы японцев. Взгляните только на это:
http://www.youtube.com/watch?v=V3j4Y3InMHc

Рассказывать я буду не про достоинства и недостатки Ruby, а про характерные особенности, незнания которых могут привести к серьезным ошибкам. (Если рассуждать про достоинства и недостатки, начнется безудержный холивар)

1. ООП от головы до пят


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

"Ruby".class
=> String 
1.class
=> Fixnum
123.to_s
=> "123"

Как видите, даже численные примитивы являются объектами со своим набором методов. Даже true и false являются объектами классов TrueClass и FalseClass

2. Правда и ложь. Объект nil


В Руби всего два объекта обладают булевым значением false. Это объект false и объект nil (не NULL, как во многих других языках!). Все остальные объекты являются эквивалентами булевого значения true. Это означает, что число 0 так же является эквивалентом значения true!

if 0
   print "0 is true"
end
0 is true => nil

if !nil
   print "nil object is false"
end
nil object is false => nil

if !false
   print "false object is false"
end
false object is false => nil

3. Объекты передаются по ссылке


В Ruby методы получают ссылку на объект, а не копию его значения. Это означает, что изменение объекта внутри метода повлечет за собой его изменение в вызывающем контексте. В Ruby это называется вызов по соиспользованию (объект является рязделяемым, или используемым совместно).

ЗАМЕЧАНИЕ: Присвоение значения аргументу в методе не повлечет за собой никаких изменений в вызывающем контексте. Присвоение значений компонентам аргумента - повлечет.

Заключение


Если хотите узнать больше, переходите сюда, изучайте и достигайте просвещения.

вторник, 12 августа 2014 г.

VSFTPD. File Permissions

Основные сведения


1. Когда пользователь системы Linux создает файл, он автоматически наделяется стандартным набором разрешений (permissions).

2. Стандартный набор разрешений определяется разностью двух параметров: режима доступа (access mode) и пользовательской маски (umask - user mask).

3. По умолчанию режим доступа для создаваемых файлов имеет значение 666 (разрешены чтение и запись для всех), а для директорий - 777 (разрешены чтение, запись и исполнение для всех).

4. Для обычных пользователей umask равен 002, для root - 022.

Исходя из вышеперечисленного все создаваемые обычными пользователями файлы имеют разрешения 664, а папки 775 (Для root - 644 и 755 соответственно).

umask в vsftpd


В VSFTPD umask имеет значение по умолчанию 077. Это означает, что переданный по ftp файл будет иметь разрешения 600 (чтение и запись для пользователя, и не для кого другого).

Управлять разрешениями переданных файлов можно с помощью изменения umask для ftp сервера. Для этого откройте файл /etc/vsftpd.conf
sudo vim /etc/vsftpd.conf

И измените/добавьте параметр local_umask:
local_umask=007

После этого перезагрузите ftp сервер:
sudo restart vsftpd

В данном случае я изменил маску на 007. Таким образом на переданные файлы даются разрешения чтения и записи для пользователя и пользователей его группы (666 - 007 = 660).

воскресенье, 10 августа 2014 г.

Changing the Primary Key in Ruby on Rails Models

Здесь рассмотрено, как изменить тип и имя первичного ключа в модели Ruby On Rails.

Введение


По умолчанию, в любой создаваемой таблице в Ruby On Rails, первичным ключом является автогенерируемое поле :id типа integer. Это поле можно изменить как на этапе создания таблицы, так и в любое время после этого.

1. Файл миграции


Создадим модель пальцев (Finger). После выполнения команды rails generate model создастся файл миграции. Подправим его перед выполнением rake db:migrate:

class CreateFingers < ActiveRecord::Migration
  def change
    create_table :fingers, id: false do |t|
      t.string :name, null: false
      t.float :length

      t.timestamps
    end

    reversible do |dir|
      dir.up do
        execute "ALTER TABLE fingers ADD PRIMARY KEY (name);"
      end
      dir.down do
        execute "ALTER TABLE fingers DROP CONSTRAINT fingers_pkey;"
      end
    end
  end
end

То же самое можно проделать с уже существующей таблицей, удалив поле :id и добавив свое поле, которое будет первичным ключом:

class ChangePrimaryKeyInFingers < ActiveRecord::Migration
  def change
    remove_column :fingers, :id
    add_column :fingers, :name, :string
    reversible do |dir|
      dir.up do
        execute "ALTER TABLE fingers ADD PRIMARY KEY (name);"
      end
      dir.down do
        execute "ALTER TABLE fingers DROP CONSTRAINT fingers_pkey;"
      end
    end
  end
end

2. Модель


Подправим модель, указав в ней первичный ключ:
class Finger < ActiveRecord::Base
  self.primary_key = :name
end

3. Заключение


Все готово. Мы настроили свой первичный ключ в модели. Теперь можно использовать его в качестве внешнего ключа в других таблицах так же, как в случае стандартного первичного ключа (Создав поле с именем finger_id).



четверг, 7 августа 2014 г.

Виртуальные пользователи в VSFTPD

За основу взяты статьи:

Перед нами стоит задача предоставить множеству пользователей доступ по FTP, при этом не создавая для этого реальных пользователей. Эти пользователи не находятся в файлах /etc/passwd и /etc/shadow. Ко всему этому, все пользователи будут работать на сервере от одного реального пользователя, к примеру www-data или ftp. Управление доступом к папкам будут регулироваться на уровне установленных прав для директорий. Ни один из пользователей не уйдет дальше своей папки.
Не пугайтесь большого количества действий - все довольно просто. Приступим.

Примечание: в этой статье используется FTP сервер vsftpd.

Если у вас не установлен FTP сервер, установите его по этой инструкции:

1. База данных пользователей


Для создания базы виртуальных пользователей, нужна будет Berkeley DB. Для начала нужно узнать доступную версию. Для этого вводим в командной строке:
sudo apt-cache search db | grep Berkeley

И ищем строчку, похожую на:
db5.3-util - Berkeley v5.3 Database Utilities

Выбираем самую последнюю версию и устанавливаем:
sudo apt-get install db5.3-util

2. Список пользователей


Пользователи являются виртуальными, но их использование будет производиться от лица реального пользователя. Создадим его и папку для виртуальных пользователей:
sudo mkdir /home/ftp
sudo useradd -d /home/ftp ftpadmin
sudo passwd ftpadmin
sudo chown ftpadmin /home/ftp

Для того, чтобы создать Berkeley DB базу данных виртуальных пользователей, сперва необходимо подготовить список пользователей и паролей в текстовом файле. Формат файла очень прост. Каждая запись базы данных состоит из пары «ключ, значение», где ключом является имя учётной записи виртуального пользователя, а значением — его пароль. Каждая пара разбита на две строки: первая строка — ключ (имя пользователя), вторая — значение (пароль пользователя). Для примера создадим следующий файл vsftpdusers в директории /etc/vsftpd/:
sudo mkdir /etc/vsftpd
sudo touch /etc/vsftpd/vsftpdusers
#Читать и изменять файл сможет только root
sudo chmod 0600 /etc/vsftpd/vsftpdusers

Запишем в него информацию о пользователях. sudo vim vsftpdusers:
user1
password1
user2
password2

Для каждого пользователя создаем папки в нужной директории. К примеру, у меня это /home/ftp:
sudo mkdir /home/ftp/user1
sudo mkdir /home/ftp/user2

Указываем владельца папок, от которого будет осуществляться работа пользователей на сервере:
sudo chown ftpadmin:ftpadmin /home/ftp/user1
sudo chown ftpadmin:ftpadmin /home/ftp/user2

Остается создать базу пользователей из созданного выше текстового файла:
#Создаем DB
sudo db5.3_load -T -t hash -f /etc/vsftpd/vsftpdusers /etc/vsftpd/users.db
#Устанавливаем права ради безопасности. Читать и изменять файл сможет только root
sudo chmod 0600 /etc/vsftpd/users.db


3. Конфигурация VSFTPD


Редактируем файл настроек vsftpd:
sudo vim /etc/vsftpd.conf
Это минимальный набор параметров, необходимый для работы с нашими требованиями:
# Активирум сервис. Если используется xinetd, то выставить NO
listen=YES
# Отключаем вход от анонимного пользователя
anonymous_enable=NO
# Разрешение подключаться локальным и виртуальным пользователям
local_enable=YES
# Работа с виртуальными пользователями
user_sub_token=$USER
# Путь к домашним каталогам виртуальных пользователей
local_root=/home/ftp/$USER
# Не даём вылазить за пределы своего домашнего каталога пользователям
chroot_local_user=YES
# Скрываем реальные ID пользователей работающих на сервере
hide_ids=YES
# Все виртуальные пользователи работают как гостевые
guest_enable=YES
# Настоящее имя пользователя, от которого работают гостевые
guest_username=ftpadmin
# Виртуальные пользователи пользуются такими же привилегиями, что и локальные
virtual_use_local_privs=YES
# Глобальное разрешение операций записи
write_enable=YES
allow_writeable_chroot=YES
# Разрешаем работать в пассивном режиме
pasv_enable=YES
pasv_max_port=65535
pasv_min_port=32768
# Имя службы PAM
pam_service_name=vsftpd.virtual

Создадим новую службу авторизации для vsftpd. В каталоге /etc/pam.d создаем файл с именем указанным в vsftpd.conf в пункте pam_service_name
sudo vim /etc/pam.d/vsftpd.virtual

Заполняем файл следующим содержимым, где указываем на созданную нами базу без её расширения:
auth        required    pam_userdb.so db=/etc/vsftpd/users
account     required    pam_userdb.so db=/etc/vsftpd/users
session     required    pam_loginuid.so
Все настройки завершены. Осталось перезапустить сервис:
sudo vsftpd restart
Для заметки:
Более подробно ознакомиться с параметрами файла vsftpd.conf можно на www.lissyara.su

Настройка и использование FTP-сервера в Ubuntu Linux

За основу взяты статьи:

Почти каждый пользователь, работающий в сети интернет, сталкивался хотя бы раз с FTP. Здесь описано, как установить FTP сервер на машину и обеспечить его безопасность.

Мы будем использовать легкий и эффективный FTP-сервер vsFTPd, предназначенный для работы на высоконагруженных серверах. Далее в этой статье мы будем говорить просто об FTP-сервере, подразумевая vsFTPd.

1. Что такое FTP


FTP расшифровывается как File Transfer Protocol - протокол передачи данных. Название подразумевает, что этот протокол используется для передачи файлов или директорий с одного хоста на другой по сети - как локальной, так и через интернет.

2. Установка FTP-сервера в Ubuntu


Чтобы установить vsftpd откройте консоль и выполните команду:
sudo apt-get install vsftpd

После выполнения этой команды сервер будет установлен и запущен.
Setting up vsftpd (2.3.5-1ubuntu2) ...
vsftpd start/running, process 1891

3. Варианты запуска службы FTP


vsftpd может быть запущен тремя различными способами. Первый способ - запуск через inetd. Второй - через xinetd, третий - запускать сервер вручную (автономный режим).

По умолчанию vsftpd запускается в автономном режиме, в котором запускаемая на сервере служба использует собственный стартовый скрипт, называемый демоном. В случае vsftpd это /etc/init.d/vsftpd. Данный автономный демон в момент старта службы FTP берет управление нею на себя. Демон vsftpd предоставляет администратору несколько команд для управления FTP-сервером vsftpd:

start или stop - используется для запуска или остановки ftp-сервера.
status - выводит подробную информацию о текущем состоянии вашего FTP-сервера.
restart - это альтернатива последовательности из остановки и запуска сервера. Если сервер уже остановлен, команда restart запустит его.
reload - эта команда позволяет перезагрузить и применить все новые настройки. Ее отличие от restart заключается в том, что применение новых настроек производится без остановки сервера.
Чтобы выполнить данные команды, напечатайте:
sudo start/stop/status/restart/reload vsftpd

Однако автономный режим менее гибкий, inetd старый, так что рекомендуется запускать vsftp через xinetd. В нем есть такие вещи как регистрация запросов, контроль доступа, привязка сервиса к определенному сетевому интерфейсу и т.д.

4. Запуск службы FTP через xinetd


Устанавливаем суперсервер xinetd:
sudo apt-get install xinetd

Приведенная выше команда устанавливает и запускает суперсервер xinetd. В случае, если он у вас уже установлен, эта команда не нужна. Далее, создайте файл vsftpd в директории /etc/xinetd.d/ со следующим содержимым:
service ftp
{
        disable                 = no
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/vsftpd
        per_source              = 5
        instances               = 200
        no_access               = 10.1.1.10
        banner_fail             = /etc/vsftpd.busy
        log_on_success          += PID HOST DURATION
        log_on_failure          += HOST
}


В то же время вы можете изменять любые опции, чтобы настроить суперсервер в соответствии со своими требованиями.
Опции, на которые стоит обратить внимание:
server - введите в командной строке "$ which vsftpd", чтобы узнать правильный путь.
no_access - все хосты с IP-адресами, указанными в этой директиве, будут блокированы.
banner_fail - здесь можно указать путь к текстовому файлу, содержимое которого будет показано для любых блокированных IP-адресов.

Далее нам необходимо отредактировать конфигурационный файл FTP-сервера /etc/vsftpd.conf, заменив строку
listen=YES
на
listen=NO

Эта директива даст команду FTP-серверу не открывать никаких портов, полностью перепоручив их суперсерверу xinetd. Перед тем, как запустить сервер в нормальном режиме, убедитесь, что демон vsftpd отключен:
sudo service vsftpd stop

Теперь можно запустить FTP-сервер с помощью команды:
sudo service xinetd restart

Чтобы убедиться в нормальной работе FTP-сервера, протестируйте и откройте порт 21 с помощью команды netstat:
$ netstat -ant | grep 21tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN

5. Настройка FTP сервера


Настройка vsftpd производится внесением изменений в конфигурационный файл /etc/vsftpd.conf.

Примечание: при внесении любых изменений в настройки FTP-сервера не забудьте воспользоваться командой restart/reload, чтобы активировать их.

5.1 Настройка пользовательского доступа

vsftpd позволяет предоставить либо анонимный доступ, либо пользователям из файла /etc/passwd, либо из своего собственного списка.

Анонимный доступ

Примечание: Открывать анонимный доступ опасно, а анонимный доступ без пароля еще опаснее. Это плохая идея. Лучше не делайте так, а просто почитайте для справки.

Чтобы предоставить анонимный доступ, в конфигурационном файле задайте директиве anonymous_enable значение YES:
anonymous_enable=YES

Для доступа без пароля дополнительно пропишите:
no_anon_password=YES

Теперь доступ к FTP серверу можно получить через пользователя anonymous. Для этого просто введите команду ftp с аргументом localhost или ip адресом вашего сервера:

$ ftp localhost
Connected to localhost.
220 (vsFTPd 2.3.5)
Name (localhost:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
ftp> quit
221 Goodbye.

Доступ локальных пользователей

Чтобы позволить авторизоваться всем пользователям, указанным в файле /etc/passwd, необходимо изменить значение директивы local_enable в файле /etc/vsftpd.conf.
local_enable=YES
Теперь любой пользователь, указанный в файле /etc/passwd, сможет авторизоваться, используя свой пароль.

Список доступа пользователей

Сначала создадим список доступа, используемый сервером vsFTPd. Обычно вы можете задать его в директории /etc/. Создайте файл с произвольным именем и перечислите в нем всех пользователей, которым вы хотите разрешить или запретить доступ. Например, давайте создадим новый список с единственным пользователем "root":
echo root > /etc/vsftpd.userlist

Далее, определим новый список пользователей в конфиграционном файле /etc/vsftpd.conf и активируем директиву userlist_enable:
userlist_file=/etc/vsftpd.userlist
userlist_enable=YES

Таким образом всем пользователям, перечисленным в файле /etc/vsftpd.userlist, будет отказано в доступе к FTP-серверу.
$ ftp localhost
Connected to localhost.
220 (vsFTPd 2.3.5)
Name (localhost:root): lubos
530 Permission denied.
Login failed.
ftp>

Чтобы разрешить доступ всем пользователям, перечисленным в файле /etc/vsftpd.userlist, установите значение "NO" для директивы userlist_deny. При этом вы открываете доступ только пользователям, перечисленным в /etc/vsftpd.userlist. Каждое имя пользователя в этом файле должно располагаться на отдельной строке.

5.2 Другие настройки


На сегодняшний день vsFTPd имеет 125 опций конфигурации. Это делает его очень гибким в настройке и в то же время простым в использовании и администрировании. Хотите ли вы использовать его дома, в пределах корпоративной сети, или на удаленном сервере, вы можете быть уверены, что vsFTPd полностью удовлетворит ваши нужды.
Список настроек можно посмотреть тут:
http://www.lissyara.su/doc/man/vsftpd/
Список команд можно посмотреть тут:
http://www.nsftools.com/tips/RawFTP.htm



вторник, 29 июля 2014 г.

Auto Deploy Ruby On Rails Ubuntu (Capistrano + nginx + unicorn + PostgreSQL)

Предположим, что у вас есть физический или виртуальный сервер, на котором вы собираетесь разворачивать свое Ruby On Rails приложение. Данный процесс сопровождается несколькими небольшими, но скучными задачами, которые приходится выполнять каждый раз, а именно:
1) Получить доступ к серверу (Например, логин через SSH в командной строке);
2) Перейти в папку приложения;
3) Обновить приложение до последней версии;
4) Выполнить прекомпиляцию ресурсов, если необходимо;
5) Перезапустить приложение, если необходимо.

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

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

В данной статье приведена пошаговая инструкция настройки сервера для разворачивания (deploy) Ruby On Rails приложения и автоматизация данного процесса. В ней рассмотрено:
- Первичная настройка сервера и закрытого доступа к нему;
- Установка веб-сервера nginx и базы данных PostgreSQL;
- Установка rvm и Ruby On Rails;
- Настройка гема foreman для управления процессами приложения;
- Настройка http-сервера Unicorn;
- Настройка гема Capistrano (v3.1) для автоматизации деплоя.

Инструкция протестирована на операционных системах Ubuntu 14.04 LTS и 12.10 LTS.
Для работы с файлами на удаленном сервере я использовал текстовый редактор vim (sudo apt-get install vim).

Первичная настройка сервера


Допустим, что у Вас есть машинка с голой Ubuntu, к которой вы подключились по SSH. Для начала сменим пароль у пользователя root командой:

passwd

Создадим нового пользователя, от лица которого будет производится деплой (Выбирайте любое имя, которое вам удобно. Я выбрал deployer, пользуясь случаем):

adduser ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ

Разрешим ему пользоваться командой sudo и укажем, какие команды можно выполнять без пароля. Для этого выполняем команду:

visudo

В открывшемся файле дописываем:

ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ ALL=(ALL:ALL) ALL
ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ ALL=NOPASSWD: /usr/sbin/service, /bin/ln, /bin/rm, /bin/mv, /sbin/start, /sbin/stop, /sbin/restart, /sbin/status

Изменим настройки ssh сервера (запретим логин под root, доступ по доменному имени и разрешим логин только под нашим новым пользователем).
Для этого добавляем в файл '/etc/ssh/sshd_config':

PermitRootLogin no
UseDNS no
AllowUsers ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ

Перезапустим ssh сервер командой:

reload ssh

Или для Ubuntu 16:

sudo service ssh restart 

Установка и настройка nginx

Оригинал статьи по установке nginx с плагином pagespeed тут.

Nginx является веб-сервером для обслуживания статических запросов и хранения статичных файлов. Он будет использоваться в связке с unicorn (сервером для динамических страниц приложения).

Необходимо установить его на сервере. Для этого логинимся под новым пользователем:

ssh ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ@123.123.123.123

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

sudo apt-get update
sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip libssl-dev

Загружаем плагин pagespeed:

NPS_VERSION=[check the release notes for the latest version]
cd
wget https://github.com/pagespeed/ngx_pagespeed/archive/v${NPS_VERSION}-stable.zip
unzip v${NPS_VERSION}-stable.zip
cd ngx_pagespeed-${NPS_VERSION}-stable/
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_VERSION}.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})  # extracts to psol/

Загружаем и устанавливаем nginx с поддержкой pagespeed:

NGINX_VERSION=[check nginx's site for the latest version]
cd
wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
tar -xvzf nginx-${NGINX_VERSION}.tar.gz
cd nginx-${NGINX_VERSION}/
./configure --add-module=$HOME/ngx_pagespeed-${NPS_VERSION}-stable --with-http_ssl_module
make sudo make install

Если подключение к серверу через HTTPS не требуется, флаг --with-http_ssl_module можно упустить.

Далее создадим upstart скрипт для управления nginx. Он позволит управлять сервером командами:

sudo start/stop/restart/status nginx

Для этого создаём файл '/etc/init/nginx.conf' со следующим содержимым:

description "nginx http daemon"
author "George Shammas <georgyo@gmail.com>"

start on (filesystem and net-device-up IFACE=lo)
stop on runlevel [!2345]

env DAEMON=/usr/local/nginx/sbin/nginx
env PID=/var/run/nginx.pid

expect fork
respawn
respawn limit 10 5
#oom never

pre-start script
        $DAEMON -t
        if [ $? -ne 0 ]
                then exit $?
        fi
end script

exec $DAEMON

Файл настроек nginx лежит по адресу '/usr/local/nginx/conf/nginx.conf', но пока мы его трогать не будем. Мы его зальем автоматически при первой выкладке приложения.

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

sudo useradd -s /sbin/nologin -r nginx
sudo groupadd web
sudo usermod -a -G web nginx
sudo usermod -a -G web ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ
sudo mkdir /var/www
sudo chgrp -R web /var/www
sudo chmod -R 775 /var/www

После этого разлогинтесь и войдите под вашим пользователем снова, чтобы изменения вступили в силу, а так же запустите nginx:

sudo start nginx

Если upstart скрипты на ubuntu 16 не будут работать, переключитесь с режима systemd в upstart командой sudo apt-get install upstart-sysv и перезагрузите сервер.

Установка и настройка PostgreSQL


PostgreSQL - свободная объектно-реляционная СУБД. Про ее достоинства и недостатки вы можете почитать отдельно.

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

В репозиториях ubuntu лежит устаревшая версия, так что мы добавим сторонний репозиторий. В файл '/etc/apt/sources.list.d/pgdg.list' добавим:

deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main

Затем добавляем ключ репозитория и устанавливаем PostgreSQL:

wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get install postgresql-9.3 postgresql-server-dev-9.3

И создаем нового пользователя. Для этого входим в оболочку PostgreSQL:

sudo -u postgres psql

Создаем пользователя, даем ему привилегии и выходим из оболочки (На сервере я назвал пользователя db_deployer. На клиенте создал пользователя со своим привычным именем и без пароля):

create user ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД with password 'ВАШ_ПАРОЛЬ';
alter role ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД superuser createrole createdb replication login;
\q

Далее разрешим удаленную работу с базой данных и предоставим доступ к базе данных от лица нового пользователя. Для этого только на сервере выполняем следующее:
1) в файле '/etc/postgresql/9.3/main/postgresql.conf' изменим параметр listen_addresses = 'localhost' на listen_addresses = '*';
2) добавим в файл '/etc/postgresql/9.3/main/pg_hba.conf' строчки:

local   all             ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД                md5
host    all             ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД    0.0.0.0/0   md5

После этого Перезагружаем postgresql командой:

sudo service postgresql restart

ЗАМЕЧАНИЕ: Если при работе с PostgreSQL на клиенте будут возникать ошибки, пропишите соответствующие разрешения и на локальной машине.

ПОЛЕЗНОЕ: Так же можно поставить веб-интерфейс teampostgresql. Управляется командами:

sudo teampostgresql-service start
sudo teampostgresql-service stop
sudo teampostgresql-service status

Установка RVM, Ruby, Rails, Bundler


Устанавливаем на сервере Ruby On Rails и все необходимые для его работы примочки. Если Rails не установлены на вашем рабочем компьютере, устанавливаем и на нем. Про это здесь:
Если Вы еще не создали Rails приложение, то про это можно почитать тут:
Для продолжения работы по данной статье у Вас должно быть в наличии приложение в минимальной конфигурации, ибо что-то нужно разворачивать на сервере.

Создаем репозиторий на github


Мы будем использовать удаленный репозиторий git для разворачивания приложения. На сервере будет происходить загрузка последней версии приложения именно с него. Если у вас нет клиента git, его можно установить командой:

apt-get install git

Для удаленного хранения я использую сервис github. Регистрируемся, создаем репозиторий в сервисе, запоминаем его адрес. 
Далее, создаем репозиторий в папке проекта:

git init

Добавляем адрес репозитория (Будет указан во время его создания):

git remote add origin АДРЕС_РЕПОЗИТОРИЯ

Но не спешим заливать на него наше приложение!

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

/config/database.yml # доступ к базе данным
/Procfile # про него я еще расскажу
/config/deploy/ # файлы Capistrano
/shared/ # файлы, которых нет в репозитории, но они будут скопированы на сервер при первом деплое приложения

Теперь фиксируем изменения и производим их публикацию на github:

git add -A
git commit -m 'first commit'
git push -u origin master

Так же нужно добавить публичный ключ сервера в настройки github репозитория. Для этого, подключившись к серверу по ssh производим следующее:

chmod 700 ~/.ssh
cd ~/.ssh
ssh-keygen

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

Установка и первоначальная настройка гема foreman


Данный гем позволяет управлять запуском потоков приложения. Если ваше приложение является многопоточным (например, главный поток, и поток отложенных задач), то они оба должны быть запущены со стартом приложения. Foreman можно настроить так, чтобы оба этих потока запускались всего лишь одной командой - foreman start. Стоит всего лишь прописать их в Procfile, находящийся в корне приложения. Более того, имеется возможность создать upstart скрипт (командой foreman export upstart), чтобы приложением можно было управлять командами start/stop/status/restart ИМЯ_ПРИЛОЖЕНИЯ, а так же запуск потоков происходил автоматически со стартом компьютера.

Добавляем строчку в Gemfile:

gem 'foreman', '0.63.0'

И выполняем:

bundle install
bundle update

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

В корне приложения создаем файл Procfile в котором прописываем, какие процессы необходимо запустить со стартом приложения:

web: rails s
worker: bundle exec rake jobs:work

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

Позже мы напишем Production конфигурацию Procfile, для запуска приложения на сервере.

Установка Unicorn


Unicorn - это продвинутый http сервер для обработки множества http запросов и работы с динамическими страницами. Если nginx занимается обработкой и хранением статических файлов, то Unicorn необходим для взаимодействия с базой данных через Rack интерфейс и работы с динамическими страницами.

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

group :production do
    gem 'unicorn'
end

После чего не забудьте про bundle install

В папке '/config/' создаем файл unicon.rb c примерно таким содержимым (ИМЯ_ПРИЛОЖЕНИЯ заменяем на имя вашего приложения. Так будет называться папка на сервере):

# Устанавливаем количество процессов на сервере (Чем больше поток пользователей, тем больше нужно процессов)
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)

working_directory "/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/current" # available in 0.94.0+

# Слушаем Unix domain socket и TCP порт
listen "/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/socket/.unicorn.sock", :backlog => 64
listen 8080, :tcp_nopush => true

# уничтожаем workers после 30 секунд вместо 60 дефолтных
timeout 30

# Устанавливаем путь к PID файлу главного процесса unicorn
pid "/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/run/unicorn.pid"

# Направляем потоки вывода
stderr_path "/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/log/unicorn.stderr.log"
stdout_path "/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/log/unicorn.stdout.log"

# Подгружаем приложение в память до того, как произойдет форк процессов. (Типа для memory savings)
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

#При включенной опции юникорн проверяет соединения клиентов, записывая начало
#хедера HTTP запроса до того, как он вызовется приложением. Это
#предотвращает вызов приложения для соединений, которые были отключены от очереди.
#Это лишь гарантирует определение клиентов на том же хосте, что и юникорн.
check_client_connection false

before_fork do |server, worker|

  # Следующее особенно рекомендовано для Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!

  # The following is only recommended for memory/DB-constrained
  # installations.  It is not needed if your system can house
  # twice as many worker_processes as you have configured.
  #
  # # This allows a new master process to incrementally
  # # phase out the old master process with SIGTTOU to avoid a
  # # thundering herd (especially in the "preload_app false" case)
  # # when doing a transparent upgrade.  The last worker spawned
  # # will then kill off the old master process with a SIGQUIT.
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
  #
  # Throttle the master from forking too quickly by sleeping.  Due
  # to the implementation of standard Unix signal handlers, this
  # helps (but does not completely) prevent identical, repeated signals
  # from being lost when the receiving process is busy.
  # sleep 1
end

after_fork do |server, worker|
  # per-process listener ports for debugging/admin/migrations
  # addr = "127.0.0.1:#{9293 + worker.nr}"
  # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)

  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection


  # if preload_app is true, then you may also want to check and
  # restart any other shared sockets/descriptors such as Memcached,
  # and Redis.  TokyoCabinet file handles are safe to reuse
  # between any number of forked children (assuming your kernel
  # correctly implements pread()/pwrite() system calls)
end

Установка Capistrano


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

Capistrano скрипт будет выполнять некоторые команды от имени суперпользователя на сервере. Чтобы разрешить ему делать это, выполняем команду на сервере:

sudo visudo

и добавляем строчку:

ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ ALL=NOPASSWD: /usr/sbin/service, /bin/ln, /bin/rm, /bin/mv, /sbin/start, /sbin/stop, /sbin/restart, /sbin/status

Установим Capistrano, добавив в Gemfile несколько строчек, и выполнив bundle update, bundle install:

group :development do
    gem 'capistrano', '3.1.0'
    gem 'capistrano-rails'
    gem 'capistrano-bundler'
    gem 'capistrano-rvm'
end

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

Выполняем команду:

bundle exec cap install

В созданном файле Capfile добавляем:

require 'capistrano/deploy'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails'

Теперь, если указать в настройках Capistrano адрес сервера, репозитория и рабочую папку, то он одной командой:
- Загрузит ваше приложение из репозитория на сервер в папку рабочая_папка/имя_приложения/releases/дата_релиза/, не удаляя старую версию (по умолчанию он хранит 5 последних версий приложений);
- Выполнит bundle install;
- Выполнит db:migrate;
- Выполнит assets:precompile;
- Создаст symlink из папки приложения в папку рабочая_папка/имя_приложения/current

Почти все, что нам надо. Однако, еще необходимо произвести настройку nginx, unicorn и foreman при первом деплое, а так же запускать unicorn при каждом последующем.

Файлы настроек для сервера


Файлы настроек, которые необходимо загрузить на сервер, будем хранить в папке shared (в папке проекта на локальной машине). Для этого мы добавили ее в .gitignore.
Сначала создадим там nginx.conf примерно с таким содержимым:

user nginx web; 

# В этот файл пишем pid процесса
pid /var/run/nginx.pid;

# Ошибки выводим сюда
error_log /var/www/log/nginx.error.log;

events {
  worker_connections 1024; # increase if you have lots of clients
  accept_mutex off; # "on" if nginx worker_processes > 1
  use epoll; # enable for Linux 2.6+
  # use kqueue; # enable for FreeBSD, OSX
}

http {
  # nginx will find this file in the config directory set at nginx build time
  include mime.types;
  types_hash_max_size 2048;
  server_names_hash_bucket_size 64;
  # fallback in case we can't determine a type
  default_type application/octet-stream;

  # click tracking!
  access_log /var/www/log/nginx.access.log combined;

  # you generally want to serve static files with nginx since neither
  # Unicorn nor Rainbows! is optimized for it at the moment
  sendfile on;

  tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
  tcp_nodelay off; # on may be better for some Comet/long-poll stuff

  # we haven't checked to see if Rack::Deflate on the app server is
  # faster or not than doing compression via nginx.  It's easier
  # to configure it all in one place here for static files and also
  # to disable gzip for clients who don't get gzip/deflate right.
  # There are other gzip settings that may be needed used to deal with
  # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 0;
  gzip_vary on;
  gzip_disable "MSIE [1-6]\.";
  gzip_proxied expired no-cache no-store private auth;
  gzip_comp_level 9;
  gzip_types text/plain text/xml text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;

  # this can be any application server, not just Unicorn/Rainbows!
  upstream app_server {
    server unix:/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/socket/.unicorn.sock fail_timeout=0;
  }

  server {
    # PageSpeed
    pagespeed on;
    pagespeed FileCachePath /var/ngx_pagespeed_cache;
    location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { 
      add_header "" ""; 
    }
    location ~ "^/ngx_pagespeed_static/" { }
    location ~ "^/ngx_pagespeed_beacon$" { }
    location /ngx_pagespeed_statistics { 
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    }
    location /ngx_pagespeed_global_statistics { 
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    }
    pagespeed MessageBufferSize 100000;
    location /ngx_pagespeed_message { 
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    }
    location /pagespeed_console { 
      allow 127.0.0.1; allow 5.228.169.73; deny all; 
    }

    charset utf-8;
    # enable one of the following if you're on Linux or FreeBSD
    listen 80 default deferred; # for Linux
    # listen 80 default accept_filter=httpready; # for FreeBSD

    # If you have IPv6, you'll likely want to have two separate listeners.
    # One on IPv4 only (the default), and another on IPv6 only instead
    # of a single dual-stack listener.  A dual-stack listener will make
    # for ugly IPv4 addresses in $remote_addr (e.g ":ffff:10.0.0.1"
    # instead of just "10.0.0.1") and potentially trigger bugs in
    # some software.
    # listen [::]:80 ipv6only=on; # deferred or accept_filter recommended

    client_max_body_size 4G;
    server_name _;

    # ~2 seconds is often enough for most folks to parse HTML/CSS and
    # retrieve needed images/icons/frames, connections are cheap in
    # nginx so increasing this is generally safe...
    keepalive_timeout 5;

    # path for static files
    root /var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/current/public;

    # Prefer to serve static files directly from nginx to avoid unnecessary
    # data copies from the application server.
    #
    # try_files directive appeared in in nginx 0.7.27 and has stabilized
    # over time.  Older versions of nginx (e.g. 0.6.x) requires
    # "if (!-f $request_filename)" which was less efficient:
    # http://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
    try_files $uri/index.html $uri.html $uri @app;

    location ~ ^/(assets)/  {
      root /var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/current/public;
      
      expires max;
      add_header Cache-Control public;
    }
    location @app {
      # an HTTP header important enough to have its own Wikipedia entry:
      #   http://en.wikipedia.org/wiki/X-Forwarded-For
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      # enable this if you forward HTTPS traffic to unicorn,
      # this helps Rack set the proper URL scheme for doing redirects:
      # proxy_set_header X-Forwarded-Proto $scheme;

      # pass the Host: header from the client right along so redirects
      # can be set properly within the Rack application
      proxy_set_header Host $http_host;

      # we don't want nginx trying to do something clever with
      # redirects, we set the Host: header above already.
      proxy_redirect off;

      # set "proxy_buffering off" *only* for Rainbows! when doing
      # Comet/long-poll/streaming.  It's also safe to set if you're using
      # only serving fast clients with Unicorn + nginx, but not slow
      # clients.  You normally want nginx to buffer responses to slow
      # clients, even with Rails 3.1 streaming because otherwise a slow
      # client can become a bottleneck of Unicorn.
      #
      # The Rack application may also set "X-Accel-Buffering (yes|no)"
      # in the response headers do disable/enable buffering on a
      # per-response basis.
      # proxy_buffering off;

      proxy_pass http://app_server;
    }

    # Rails error pages
    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/current/public;
    }
  }
}

Только что Вы создали файл настроек веб-сервера nginx. ИМЯ_ПРИЛОЖЕНИЯ смените на имя, которое вы указали в unicorn.rb

Если нужно подключение через HTTPS, воспользуйтесь Let's Encrypt и данной статьей:
https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-14-04

ВНИМАНИЕ! Если вы хотите, чтобы сервер работал как по HTTP, так и по HTTPS, все серверные настройки в файле nginx.conf должны находиться внутри одного блока server {}, а не в разных, как указано в статье по ссылке.

Теперь создаем Production конфигурацию Procfile в папке shared:

web: bundle exec unicorn_rails -c /var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ/current/config/unicorn.rb -E production
worker: RAILS_ENV=production bundle exec rake jobs:work

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

Там же создаём database.yml с настройками базы данных для сервера:

production:
   adapter: postgresql
   encoding: unicode
   database: ИМЯ_ПРИЛОЖЕНИЯ_production
   pool: 5
   username: ИМЯ_ПОЛЬЗОВАТЕЛЯ_БД
   password: ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_БД

Осталось настроить Capistrano и написать скрипт для разворачивания приложения.

Настройка Capistrano


В файле 'config/deploy/production.rb' делаем изменения:
role :app, %w{ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ@IP_АДРЕС_СЕРВЕРА}
role :web, %w{ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ@IP_АДРЕС_СЕРВЕРА}
role :db,  %w{ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ@IP_АДРЕС_СЕРВЕРА}
server 'ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ@IP_АДРЕС_СЕРВЕРА', user: 'ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ', password: 'ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ', roles: %w{web app db}, my_property: :my_value

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

Теперь редактируем файл 'config/deploy.rb'. Это собственно и есть скрипт, который будет выполняться при разворачивании приложения. Он должен выглядеть примерно так:

# config valid only for Capistrano 3.1
lock '3.1.0'

set :application, 'ИМЯ_ПРИЛОЖЕНИЯ'
set :deploy_to, '/var/www/apps/ИМЯ_ПРИЛОЖЕНИЯ'
set :deploy_via, :copy
set :scm, :git
set :repo_url, 'git@github.com:ПОЛЬЗОВАТЕЛЬ_ГИТХАБА/ИМЯ_ПРИЛОЖЕНИЯ.git'
set :branch, 'master'
application = 'ИМЯ_ПРИЛОЖЕНИЯ'
set :rvm_type, :user
set :rvm_ruby_version, '2.0.0-p481'
#set :port, 2222

namespace :foreman do
  desc 'Start server'
  task :start do
    on roles(:all) do
      sudo "start #{application}"
    end
  end

  desc 'Stop server'
  task :stop do
    on roles(:all) do
      sudo "stop #{application}"
    end
  end

  desc 'Restart server'
  task :restart do
    on roles(:all) do
      sudo "restart #{application}"
    end
  end

  desc 'Server status'
  task :status do
    on roles(:all) do
      execute "initctl list | grep #{application}"
    end
  end
end

namespace :git do
  desc 'Deploy'
  task :deploy do
    ask(:message, "Commit message?")
    run_locally do
      execute "git add -A"
      execute "git commit -m '#{fetch(:message)}'"
      execute "git push origin master"
    end
  end
end

# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

# Default deploy_to directory is /var/www/my_app
# set :deploy_to, '/var/www/my_app'

# Default value for :scm is :git
# set :scm, :git

# Default value for :format is :pretty
# set :format, :pretty

# Default value for :log_level is :debug
# set :log_level, :debug

# Default value for :pty is false
# set :pty, true

# Default value for :linked_files is []
# set :linked_files, %w{config/database.yml}

# Default value for linked_dirs is []
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

# Default value for keep_releases is 5
# set :keep_releases, 5

namespace :deploy do
  desc 'Setup'
  task :setup do
    on roles(:all) do
      execute "mkdir  #{shared_path}/config/"
      execute "mkdir  /var/www/apps/#{application}/run/"
      execute "mkdir  /var/www/apps/#{application}/log/"
      execute "mkdir  /var/www/apps/#{application}/socket/"
      execute "mkdir  /var/www/log/"
      execute "mkdir  /var/www/log/upstart/"
      execute "mkdir #{shared_path}/system"
      sudo "ln -s /var/log/upstart /var/www/log/upstart"

      upload!('shared/database.yml', "#{shared_path}/config/database.yml")
      
      upload!('shared/Procfile', "#{shared_path}/Procfile")


      upload!('shared/nginx.conf', "#{shared_path}/nginx.conf")
      sudo 'stop nginx'
      sudo "rm -f /usr/local/nginx/conf/nginx.conf"
      sudo "ln -s #{shared_path}/nginx.conf /usr/local/nginx/conf/nginx.conf"
      sudo 'start nginx'

      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, "db:create:all"
        end
      end
    end
  end

  desc 'Create symlink'
  task :symlink do
    on roles(:all) do
      execute "ln -s #{shared_path}/config/database.yml #{release_path}/config/database.yml"
      execute "ln -s #{shared_path}/Procfile #{release_path}/Procfile"
      execute "ln -s #{shared_path}/system #{release_path}/public/system"
    end
  end

  desc 'Foreman init'
  task :foreman_init do
    on roles(:all) do
      foreman_temp = "/var/www/tmp/foreman"
      execute  "mkdir -p #{foreman_temp}"
      # Создаем папку current для того, чтобы foreman создавал upstart файлы с правильными путями
      execute "ln -s #{release_path} #{current_path}"

      within current_path do
        execute "cd #{current_path}"
        execute :bundle, "exec foreman export upstart #{foreman_temp} -a #{application} -u ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ -l /var/www/apps/#{application}/log -d #{current_path}"
      end
      sudo "mv #{foreman_temp}/* /etc/init/"
      sudo "rm -r #{foreman_temp}"
    end
  end


  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      sudo "restart #{application}"
    end
  end

  after :finishing, 'deploy:cleanup'
  after :finishing, 'deploy:restart'

  after :updating, 'deploy:symlink'

  after :setup, 'deploy:foreman_init'

  after :foreman_init, 'foreman:start'

  before :foreman_init, 'rvm:hook'

  before :setup, 'deploy:starting'
  before :setup, 'deploy:updating'
  before :setup, 'bundler:install'

  after :publishing, :restart

  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      # Here we can do anything such as:
      # within release_path do
      #   execute :rake, 'cache:clear'
      # end
    end
  end

end

#before :deploy, 'git:deploy'

Данный скрипт, помимо стандартных умений Capistrano, загрузит на сервер файлы из папки shared, настроит nginx, unicorn, создаст upstart скрипт foreman для легкого запуска приложения.
Можете самостоятельно разобраться в этом файле, синтаксис довольно простой. Главное замените ИМЯ_ПРИЛОЖЕНИЯ на имя вашего приложения, введите адрес репозитория, а так же ИМЯ_ПОЛЬЗОВАТЕЛЯ_СИСТЕМЫ на имя пользователя на сервере, под которым производится деплой.

И так, все готово! Не прошло и пол года)

Как производить деплой


Публикуем изменения на github.
Выполняем cap production deploy:setup при самом первом деплое Вашего приложения.
Выполняем cap production deploy при каждом деплое Вашего приложения.

Спасибо за внимание)


За основу была взята статья:
http://habrahabr.ru/post/213269/

Код подсвечен сервисом http://hilite.me/