В 2012 году, чтобы упростить развертывание приложений, написанных на Ruby on Rails, компания Heroku сделала свой знаменитый продукт. В статье мы рассмотрим несколько вариантов для хостинга и разберем, как задеплоить Ruby on Rails на конкретном примере приложения.
Хостинг Ruby on Rails. Провайдеры
Amvera Cloud - российский сервис. По функционалу похож на Heroku, только можно оплачивать российской картой. Поддерживает развертывание и обновление через push в привязанный Git-репозиторий либо через интерфейс, если вам не знаком Git. Есть нативная поддержка как C#, так и других окружений - достаточно в интерфейсе выбрать нужную конфигурацию. Стоимость начинается от 170 руб. в месяц, и есть стартовый баланс для бесплатного начала использования.
Heroku - компания, которая изобрела GitOps-подход и начинала свой путь именно как хостинг для Ruby. Достаточно запушить ваше ruby-приложение в репозиторий через git push, и Heroku развернет его автоматически. Потребуется иностранная карта. Тарифы стартуют от 5-7$ в месяц.
Движки приложений от Azure, GCE, AWS. Позволяют легко развернуть ваше ruby-приложение в инфраструктуре данных облачных провайдеров.
Развернем Fullstack-приложение на Ruby c подключением к SQLite
Приведем видеопример и подробную инструкцию.
Для этого воспользуемся сервисом Amvera. Чтобы развернуть основное приложение в Amvera, нужно выполнить следующие простые шаги:
1. Открываем страницу https://cloud.amvera.ru/projects (необходимо предварительно зарегистрироваться в Amvera)
2. Нажимаем кнопку “Создать” и выбираем тип сервиса “Приложение”
3. Выгружаем все файлы (можно через git, а можно через интерфейс). Убедитесь, что вы выгрузили все нужные файлы. Для проекта из примера ниже это:
- static/styles.css
- app.rb
- Gemfile
- amvera.yml и/или Dockerfile
4. После этого начнется сборка и развертывание приложения. Дождитесь появления статуса «Успешно развернуто».
Рассмотрим процесс подробнее
Давайте создадим простое веб-приложение на языке программирования Ruby, которое будет отслеживать посещения сайта. Для хранения этой информации мы будем использовать СУБД SQLite.
Директория приложения имеет следующую структуру:
└─ code/
├── static
│ └── styles.css
├── amvera.yml
├── app.rb
├── Gemfile
└── Dockerfile
Конфигурация
amvera.yml
Можно как написать yaml файл самостоятельно, так и воспользоваться нашим генератором yaml по ссылке либо в разделе «Конфигурация» личного кабинета.
Пример файла amvera.yml при использовании только amvera.yml:
meta:
environment: ruby
toolchain:
name: bundle
version: 3.0
build:
image: ruby:3.0
run:
image: ruby:3.0
mainScript: app.rb
persistenceMount: /data
containerPort: 80
Пример файла amvera.yml при использовании вместе с Dockerfile:
meta:
environment: docker
toolchain:
name: docker
version: latest
build:
dockerfile: Dockerfile
skip: false
run:
persistenceMount: /data
containerPort: 80
Важно: сохранять изменяемые файлы (база данных и т.д.) именно в постоянное хранилище /data. Это позволит избежать их потери при пересборке. Папка Data в коде и постоянное хранилище /data - разные директории.
Рассмотрим альтернативный способ задания конфигурации - через Dockerfile.
Dockerfile
Замечание: если вы используете Dockerfile, то конфигурационный файл amvera.yml в большинстве случаев можно не добавлять.
Шаги:
1. Создаем Dockerfile в директории с проектом.
2. В Dockerfile указываем базовый образ:
FROM ruby:3.0
вместо 3.0 можете указать любую другую версию, которая вам нужна.
3. Устанавливаем рабочую директорию:
WORKDIR /app
4. Копируем файл Gemfile в текущую директорию рабочего каталога:
COPY Gemfile ./
5. Устанавливаем зависимости, указанные в Gemfile:
RUN bundle install
6. Обновляем информацию об установленных зависимостях:
RUN bundle update
7. Копируем оставшиеся файлы внутрь контейнера:
COPY . ./
8. Открываем порт 80 для внешних подключений:
EXPOSE 80
9. Добавляем команду для запуска приложения
CMD ["ruby", "app.rb"]
Получившийся Dockerfile:
FROM ruby:3.0
WORKDIR /app
COPY Gemfile ./
RUN bundle install
RUN bundle update
COPY . ./
EXPOSE 80
CMD ["ruby", "app.rb"]
Зависимости (Gemfile)
Чтобы создать Gemfile, нужно выполнить команду:
$ bundle init
Не забудьте изменить этот файл, добавив в него информацию о всех используемых библиотеках. Например, Gemfile для примера ниже будет следующим:
source 'https://rubygems.org'
gem 'sqlite3'
gem 'webrick'
Создание проекта в Amvera
Последний шаг - развернуть само приложение. В файле app.rb содержится основной код и выполняется подключение к базе данных.
Подключение к репозиторию через Git
1. Вызовем терминал в IDE, где открыто приложение, или откроем папку проекта в терминале
2. Инициализируем локальный гит репозиторий командой
git init
3. Добавим удаленный репозиторий нашего проекта (url вашего репозитория будет отличаться. Во избежание синтаксических ошибок скопируйте ссылку на втором шаге создания проекта)
git remote add amvera https://git.amvera.ru/имя_пользователя/имя_проекта
4. Добавим файлы и сделаем первый коммит
git add .
git commit -m "init"
5. Запушим наш код в репозиторий проекта
git push amvera master
После данной команды ваше приложение развернется.
Использование SQLite с Ruby приложением
Для использования SQLite в Amvera отдельное приложение/контейнер не требуется. Достаточно в коде указать путь для хранения файлов этой БД в постоянное хранилище. Подробнее можно почитать здесь.
Итог
Мы развернули Ruby on Rails на сервере Amvera и подключили базу данных SQLite. Теперь накатывать обновления можно простой командой - git push
P.S.
Код приложения из примера
require "webrick"
require "sqlite3"
DB_PATH = "../data/visits.db"
DB = SQLite3::Database.new DB_PATH
DB.execute <<-SQL
CREATE TABLE IF NOT EXISTS visits (
id INTEGER PRIMARY KEY,
time_visited TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
SQL
class IndexHandler < WEBrick::HTTPServlet::AbstractServlet
def do_GET(request, response)
if request.path == "/"
DB.execute("INSERT INTO visits DEFAULT VALUES")
end
response.status = 200
response.content_type = "text/html"
response.body = generate_html
end
private
def generate_html
visits = fetch_visits
html = <<~HTML
<!DOCTYPE html>
<html>
<head>
<title>Visits</title>
<link rel="stylesheet" type="text/css" href="/static/styles.css">
</head>
<body>
<h1>Visits</h1>
<table border="1">
<thead>
<tr>
<th>Index</th>
<th>Time of Visiting</th>
</tr>
</thead>
<tbody>
HTML
visits.each do |visit|
html += "<tr><td>#{visit[0]}</td><td>#{visit[1]}</td></tr>"
end
html += <<~HTML
</tbody>
</table>
</body>
</html>
HTML
html
end
def fetch_visits
DB.execute("SELECT * FROM visits")
end
end
server = WEBrick::HTTPServer.new(Port: 80)
server.mount("/static", WEBrick::HTTPServlet::FileHandler, "static")
server.mount("/", IndexHandler)
server.start
```
> Не забудьте выбрать именно тот порт, который вы указали в amvera.yml и/или Dockerfile
## Проверка работоспособности
1. Переходим в настройки проекта и активируем доменное имя.
2. Теперь можно перейти по нему и откроется наше приложение.
Если что-то не работает, рекомендуем ознакомиться с логами Сборки и Приложения.
Поздравляем, вы успешно создали свое первое приложение в Amvera!
## Код styles.css из примера:
```css
body {
font-family: Arial, sans-serif;
}
table {
width: 80%;
margin: 20px auto;
border-collapse: collapse;
}
th, td {
padding: 10px;
text-align: left;
}
thead {
background-color: #f2f2f2;
}
tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
tbody tr:hover {
background-color: #ddd;
}