Rack – стандартный интерфейс между веб-сервером и Ruby-приложением, обеспечивающий обработку HTTP-запросов и формирование ответов. Rack-приложение реализует метод call
, который получает запрос и возвращает массив [статус, заголовки, тело]
. Интерфейс Rack обеспечивает переносимость приложений между серверами, поддержку промежуточного ПО и стандартизированный поток обработки запросов. Rack-приложения используют для того, чтобы код приложения был независим от конкретного сервера и мог работать с различными серверами, такими как Unicorn, Puma или Falcon. Это позволяет сосредоточиться на логике обработки запросов, упрощает внедрение промежуточного ПО, повышает переносимость, гибкость и управляемость веб-приложений, а также облегчает масштабирование и интеграцию с другими компонентами инфраструктуры.
Unicorn – многопроцессный веб-сервер для Ruby-приложений, совместимый с интерфейсом Rack, предназначенный для обработки HTTP-запросов с высокой производительностью и масштабируемостью. Rack-приложение может обрабатываться веб-сервером Unicorn для приёма HTTP-запросов и формирования ответов.
В статье разберём, как развернуть Rack-приложение на сервере Unicorn, работающем на VPS под управлением Ubuntu или Debian.
Установка необходимого ПО
Перед установкой нового ПО обновите списки пакетов в системе:
$ sudo apt update
Затем установите минимальный набор пакетов, необходимый для работы Ruby-приложений на Ubuntu и Debian:
$ sudo apt install \
ruby-full \
build-essential \
zlib1g-dev \
libssl-dev \
libreadline-dev \
libyaml-dev \
libxml2-dev \
libxslt1-dev \
libcurl4-openssl-dev \
software-properties-common \
libffi-dev \
git \
curl
В данном случае в систему инсталлируются:
ruby-full
– полный пакет Ruby со стандартной библиотекой;build-essential
– набор инструментов для сборки нативных расширений;zlib1g-dev
– библиотека для работы с архивами и гемами, часто используемая внутри Rails;libssl-dev
– поддержка TLS/SSL для работы с HTTPS;libreadline-dev
– пакет заголовочных файлов и статических библиотек для разработки;libyaml-dev
– пакет для разработки на C/C++ с заголовочными файлами и статическими библиотеками для работы с YAML;libxml2-dev
,libxslt1-dev
– зависимости для Nokogiri;libcurl4-openssl-dev
– библиотеки для работы с HTTP-запросами в гемах;software-properties-common
– утилиты для управления PPA и сторонними репозиториями, например, для установки Ruby через RVM илиrbenv
;libffi-dev
– библиотека для работы с FFI-биндингами;git
– утилита для клонирования репозиториев и получения исходного кода гемов с GitHub и других хостингов;curl
– инструмент для загрузки файлов и скриптов из сети.
По окончании установки проверьте версию Ruby:
$ ruby -v

А также версию Gem:
$ gem -v

Затем установите Ruby-гемы Rack для стандартизированного взаимодействия веб-сервера и приложения, а также Unicorn как веб-сервер для запуска Rack-приложений:
$ sudo gem install rack unicorn
Для проверки корректности установки Unicorn выведите на экран его версию:
$ unicorn --version

Как развернуть Rack-приложение на сервере Unicorn
Чтобы развернуть Rack-приложение на сервере Unicorn, рассмотрим пример запуска простейшего структурированного проекта.
Создайте каталог для Rack-приложения:
$ sudo mkdir -p /var/www/your_rack_app/
После чего перейдите в него:
$ cd /var/www/your_rack_app/
В данном каталоге создайте основной файл запуска Rack-приложения:
$ sudo nano config.ru
В нашем примере такой файл указывает Rack, что перед запуском нужно загрузить файл app.rb
и запустить приложение, созданное из класса YourApp
:
# config.ru
require_relative "app"
run YourApp.new
Далее создайте файл с исходным кодом самого приложения:
$ sudo nano app.rb
Данный файл в нашем примере определяет простейшее Rack-приложение – класс YourApp
с методом call
, который возвращает HTTP-ответ с кодом 200, заголовком content-type: text/html
и телом страницы, отображающей сообщение и IP-адрес клиента, взятый из переменной окружения env['REMOTE_ADDR']
. Проще говоря, при обращении к нашему Rack-приложению в браузере оно возвращает HTML-страницу, где отображаются надпись Your Rack Application!
и IP-адрес пользователя, открывшего страницу:
# app.rb
class YourApp
def call(env)
[
200,
{ "content-type" => "text/html" },
["<h1>Your Rack Application!</h1><p>Your IP: #{env['REMOTE_ADDR']}</p>"]
]
end
end
Затем создайте конфигурационный файл веб-сервера Unicorn:
$ sudo nano unicorn.rb
В нём задаются параметры работы сервера: 2 рабочих процесса, директория приложения, порт для прослушивания, путь к PID-файлу и пути для логов стандартного вывода и ошибок:
worker_processes 2
working_directory "/var/www/your_rack_app"
listen "0.0.0.0:8080"
pid "/var/www/your_rack_app/unicorn.pid"
stderr_path "/var/www/your_rack_app/unicorn.stderr.log"
stdout_path "/var/www/your_rack_app/unicorn.stdout.log"
Поскольку в конфигурационном файле Unicorn указан порт 8080, веб-интерфейс приложения будет слушать именно этот порт. Следовательно для подключения к нему необходимо открыть доступ к серверу через порт 8080. Чтобы это сделать, добавьте соответствующее разрешающее правило в брандмауэр UFW:
$ sudo ufw allow 8080/tcp
Чтобы процесс Unicorn, запущенный от пользователя www-data
, смог читать файлы приложения, измените владельца и группу всех файлов и директорий внутри каталога Rack-приложения, назначив их пользователю и группе www-data
:
$ sudo chown -R www-data:www-data /var/www/your_rack_app/
Следующей командой запустите Rack-приложение под управлением Unicorn, чтобы проверить его работоспособность:
$ unicorn -c /var/www/your_rack_app/unicorn.rb
Чтобы убедиться в том, что приложение работает, откройте браузер и перейдите на http://X.X.X.X:8080
, где X.X.X.X
замените на IP-адрес вашего сервера.

Для завершения работы Rack-приложения используйте сочетание клавиш Ctrl C
.
Как запустить Rack-приложение в качестве системного сервера
Чтобы Rack-приложение работало постоянно и его не нужно было всякий раз запускать вручную, необходимо настроить его работу в качестве системного сервиса. Для этого, во-первых, создайте для него юнит-файл:
$ sudo nano /etc/systemd/system/unicorn.service
В юнит-файл добавьте следующее содержимое:
[Unit]
Description=Unicorn Rack Application Server
After=network.target
[Service]
User=www-data
WorkingDirectory=/var/www/your_rack_app
ExecStart=/usr/local/bin/unicorn -c /var/www/your_rack_app/unicorn.rb -E production
Restart=always
PIDFile=/var/www/your_rack_app/unicorn.pid
[Install]
WantedBy=multi-user.target
В строках WorkingDirectory
, ExecStart
и PIDFile
вместо /var/www/your_rack_app/
укажите каталог, в котором находится ваше Rack-приложение. Также в вашем случае расположение файла unicorn
может отличаться от указанного в нашем примере. Чтобы узнать, где именно расположен файл unicorn
, запустите команду:
$ which unicorn
Вывод команды скопируйте в строку ExecStart
.

Сохраните изменения в файле, закройте его, после чего обновите конфигурацию systemd, перечитав все юнит-файлы, в том числе и только что созданный:
$ sudo systemctl daemon-reload
Затем запустите новую службу:
$ sudo systemctl start unicorn
Установите её в автозагрузку:
$ sudo systemctl enable unicorn
И чтобы убедиться в том, что новый системный сервис стартовал и работает, выведите на экран его текущее состояние:
$ systemctl status unicorn
Вывод команды не должен содержать сообщений о каких-либо ошибках.

Если ошибок нет, запустите браузер и проверьте работоспособность приложения при помощи ссылки http://X.X.X.X:8080
, заменив X.X.X.X
на IP-адрес виртуального сервера.