Ещё одно мануальство
по 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.


Всем прозрачно масштабируемых хай-лоад проектов.


Ссылки:

 

shitpoet@gmail.com

 



 

free hit counters