Ещё одно мануальство
по Ruby on Rails на OpenShift
OpenShift — новое опенсоурсное PaaS-облако от Red Hat и представитель следующего поколения Web-хостинга. Облачность здесь означает, что при необходимости наше приложение будет прозрачно масштабироваться, кроме того, облако берёт на себя обслуживание и обновление базовых компонентов системы. OpenShift предлагает полноценный бесплатный тариф для всех пользователей своей платформы.
Кроме моря всякой всячины (включая WebSocket-приложения) на OpenShift можно развёртывать и Ruby on Rails. OpenShift пока что поддерживает только Ruby 1.9, но этой версии, как известно, вполне достаточно как для Rails 3, так и для Rails 4. В этой статье мы создадим новое RoR-приложение и развернём его на OpenShift, при разворачивании уже существующего приложения первые шаги будут слегка отличаться.
Приложение
Сначала нам нужно зарегистрироваться на сайте OpenShift и скачать набор утилит rhc. Команда rhc
позволяет полностью управлять нашими приложениями (чтобы посмотреть доступные функции, запустите rhc
без параметров).
В папке наших проектов (папку для самого проекта создавать не нужно, она будет создана автоматически) выполняем:
$ rhc setup
$ rhc app create app_name ruby-1.9 postgresql-9.2 --scaling
$ rails new app_name
На вопрос о перезаписи рубивского config.rb
рейловским стоит ответить утвердительно.
Приложение можно создавать и с помощью Web-панели OpenShift, но через rhc
удобнее. Также можно воспользоваться примером rails-приложения от OpenShift. Но вне зависимости от того, как будет создано приложение, важно внести туда данное изменение:
+ config.logger = Logger.new(STDOUT)
иначе через какое-то время ваш /app-root/repo/log/production.log
заполнит всё доступное пространство.
Если у вас есть что-то, что сказать .gitignore
, стоит сделать это сейчас, чтобы не засорять репозиторий.
База
С Rails в продакшене обыкновенно используют PostgreSQL, так что добавим гем pg
, заменяя в файле GemFile
gem 'sqlite3'
на
group :development, :test do
gem 'sqlite3'
end
group :production do
gem 'pg'
end
OpenShift не настраивает автоматически нашу базу при деплое, поэтому нужно также внести
production:
adapter: postgresql
database: <%=ENV['OPENSHIFT_APP_NAME']%>
username: <%=ENV['OPENSHIFT_POSTGRESQL_DB_USERNAME']%>
password: <%=ENV['OPENSHIFT_POSTGRESQL_DB_PASSWORD']%>
host: <%=ENV['OPENSHIFT_POSTGRESQL_DB_HOST']%>
port: <%=ENV['OPENSHIFT_POSTGRESQL_DB_PORT']%>
min_messages: ERROR
reconnect: false
encoding: utf8
pool: 5
timeout: 5000
в config/database.yml
.
Чтобы новый GemFile был учтён:
$ bundle install --without production
Теперь всё готово к git push
:
$ git add .
$ git commit -m "pervonah"
$ git push
Миграции
OpenShift сам не применяет миграции, но это легко исправить, создав sh-скрипт deploy
в директории .openshift/action_hooks
:
#!/bin/bash
# This deploy hook gets executed after dependencies are resolved and the
# build hook has been run but before the application has been started back
# up again. This script gets executed directly, so it could be python, php,
# ruby, etc.
pushd ${OPENSHIFT_REPO_DIR} > /dev/null
echo "exec rake db:migrate RAILS_ENV=${RAILS_ENV:-production}"
bundle exec rake db:migrate RAILS_ENV=${RAILS_ENV:-production}
popd > /dev/null
Не забудьте сделать скрипт исполняемым!
Если возникнут проблемы с базой, её можно пересоздать с помощью db:setup
или db:schema:load
, воспользовавшись ssh-доступом:
$ rhc ssh
$ cd app-root/repo
$ RAILS_ENV=production bundle exec rake db:setup
503
Если главная страница сайта будет содержать ошибки, то балансировщик HAProxy, который используется для масштабирования в OpenShift, будет считать сайт неработоспособным и на все запросы к нему будет отвечать кодом 503 (не позволяя увидеть, в чём проблема). Чтобы изменить ситуацию, можно отредактировать конфигуарцию балансировщика:
$ rhc ssh
$ cd haproxy/conf
$ nano haproxy.cfg
изменив проверяемую страницу с корня
option httpchk GET /
на, например, robots.txt:
option httpchk GET /robots.txt
Перезапускаем балансировщик:
$ rhc cartridge-restart --cartridge haproxy
Похоже на хак, но на блоге OpenShift есть запись об этом (параграф "Fixing the Service Unavailable Error"). При желании можно добавить в скрипт deploy
команды для этой модификации и перезапуска балансировщика, но проще отладить главную страницу]
Файловое хранилище
OpenShift сейчас предоставляет 1 Гб для хранения загружаемых пользователем файлов, поэтому нам нет необходимости использовать внешнее хранилище, как в случае с Heroku. Однако, так как развёртывание полностью пересоздаёт файловую структуру, то, если просто сохранять файлы в одну из папок проекта, они проживут не долго. Поэтому нужно либо сохранять файлы в $OPENSHIFTDATADIR
, либо симлинкнуть эту директорию в дерево проекта, добавив в deploy
-скрипт нечто вроде
STORED_ASSETS="${OPENSHIFT_DATA_DIR}/files"
LIVE_ASSETS="${OPENSHIFT_REPO_DIR}/public"
# Ensure our stored assets directory exists
if [ ! -d "${STORED_ASSETS}" ]; then
echo "Creating permanent assets directory"
mkdir "${STORED_ASSETS}"
fi
echo "Remove stored assets directory"
rm -rf "${LIVE_ASSETS}/files"
echo "Restoring stored assets"
ln -sf "${STORED_ASSETS}" "${LIVE_ASSETS}"
Похожий скрипт есть в официальном примере от OpenShift'а, поэтому этот хак также можно смело применять.
Доменное имя
Остаётся привязать к облачному ресурсу короткий CNAME-псевдоним а-ля www.example.com. Это можно сделать, например, с помощью CloudFlare или другого DNS-хостинга, поддерживающего CNAME. Не все хостинги его поддерживают, например, Яндекс — нет, но, вопреки распространённому мнению, DNS-запись с CNAME и без A (а их именно нужно делать без A, так как к IP облака привязываться совершенно не стоит!) не нарушают RFC, хотя, действительно, не поддерживают MX-записи. Что с этим делать я хз, пишите, если что, на shitpoet@gmail.com.
Всем прозрачно масштабируемых хай-лоад проектов.
Ссылки:
- OpenShift PaaS
- Пример Rails3-приложения от OpenShift'а
- Добротное по полноте руководство
- Хорошее руководство в виде ответа на StackOverflow
- О сохранении загруженных пользователем файлов после переразвёртывания
- Настрока RoR на OpenShift с MongoDB
- Настройка CNAME на различных хостингах
- О том, как устроено масштабирование в OpenShift
shitpoet@gmail.com