Satoryu's Diary

Rubyが好きなプログラマーの日記。日々の生活、開発に関するメモとか考えとか。


2013年07月07日 [長年日記]

_ tDiaryをOpenShiftのDIYカートリッジにデプロイする方法【解説編】

Redhatが手がけるPaaSプラットフォームOpenShiftにtDiaryをデプロイしたので、今日はその方法について書きます。 「OpenShiftって何?」とか「PaaSって何?」、「tDiaryって何?」という方は自分で調べて下さい。

OpenShift DIYカートリッジのセットアップ

OpenShiftは、Rubyのアプリを実行するカートリッジ*1として、

  • Ruby 1.8
  • Ruby 1.9

を提供していて、Ruby 1.9を以前に試したのですが、Passengerの不具合があり、POSTやPUTのリクエストがちゃんと受けれないという問題がありました。 これで日記を書くのが困難であると思い、まったく何も無い状態から自分でサーバーやランタイムを設定するDIY(Do It Yourself)カートリッジを選びました。

DIYだからといって、DBのセットアップなど他のカートリッジと組み合わせることは可能です。 なのでDIYでやることは

  • Rubyの実行環境を設定
  • 起動、停止スクリプトの作成

の2つです。後者はアプリケーション、つまりtDiaryのプロジェクトで作成するので後ほど。

OpenShift上にアプリケーションを作成

アカウントの作成はOpenShiftでできるので、事前に作成。 つぎにOpenShift上のアプリケーションやカートリッジの管理を行うためのrhcコマンドをインストールする。gemとして配布されているため、

gem install rhc

で完了。 次にアプリケーションの作成。

rhc app create tdiary diy-0.1

これは、diyカートリッジ(バージョン0.1)でtdiaryという名前のアプリケーションを作成している。 次に、DBとしてPostgreSQLのカートリッジを上で作成したアプリで使えるようにセットアップする。

rhc cartridge postgresql-8.4 --app tdiary

次に直にサーバーに入って、Rubyの実行環境をセットアップします。

Ruby実行環境の設定

参考の記事では、rvmを使っているのですが、同じだと面白くないのでrbenvを使ってみます。 OpenShiftは設定したアプリケーションをホストするサーバーにSSHでログインすることができ、ログを収集したり、プロセスを確認したり色々できます。 SSHのログインは、

rhc app ssh tdiary

でできます。 では早速rbenvをインストール。ここで注意しないといけないのは、ログインしたユーザのHOMEディレクトリ直下は書き込みが禁止されていること。

cd $OPENSHIFT_DATA_DIR
git clone https://github.com/sstephenson/rbenv.git
# Install ruby-build
git clone https://github.com/sstephenson/ruby-build.git $OPENSHIFT_DATA_DIR/rbenv/plugins/ruby-build

これでrbenvでRubyをインストールできるようにできました。が、ここで注意しなければならないのは、rbenvをHOMEディレクトリ以外にインストールしたので、その場所を環境変数RBENV_ROOTで設定する必要があること。デフォルトだと$HOME/.rbenvを見るようになってしまい、上で言ったようにHOME下に書き込めないことから、rubyのインストールに失敗します。これは後で作成するtDiaryの起動、終了スクリプトを作成する際にも気にしなければいけません。 なので、それを踏まえて、

export RBENV_ROOT=$OPENSHIFT_DATA_DIR/rbenv
export PATH=$RBENV_ROOT/bin:$PATH
eval "$(rbenv init -)"
rbenv install 2.0.0-p247
gem install bundler

で、Ruby 2.0をインストールできます。 できたら次にtDiaryのセットアップをしましょう。

tDiaryのセットアップ

今回、tDiaryはgemとして配布されているversion 3.2.2.20130604を利用しています。

gem install tdiary
tdiary new mydiary
cd mydirary

で、一とおりセットアップしてくれます。 今回、PostgreSQLを使うので、Gemfileに

gem 'sequel'

を追加します*2

次に設定ファイルtdiary.conf を修正。設定ファイルの先頭に下記を追加する。

@database_url = "postgres://#{ENV['OPENSHIFT_POSTGRESQL_DB_USERNAME']}:#{ENV['OPENSHIFT_POSTGRESQL_DB_PASSWORD']}@#{ENV['OPENSHIFT_POSTGRESQL_DB_HOST']}:#{ENV['OPENSHIFT_POSTGRESQL_DB_PORT']}/#{ENV['OPENSHIFT_APP_NAME']}"

require 'tdiary/io/cache/file'
require 'tdiary/io/rdb'
@io_class = TDiary::RdbIO

@database_urlは接続するDBのURLを定義している。PostgreSQLカートリッジを設定すると、その接続情報が環境変数として定義されるので、それを使う。 あとは、cacheはファイルに、日記の情報はDBに保存するので、それぞれ必要なものをrequireしている。

Action hooksを作成

OpenShiftはHerokuのようにOpenShift上にあるGitリポジトリへpushすると、所定のスクリプトが実行され、アプリケーションのデプロイから起動まで行われる。 今回はDIYカートリッジなので、所定のスクリプトというものは無く、自身で定義する必要がある。 OpenShiftはデプロイするプロジェクトに.openshift/action_hooks下に所定の名前のスクリプトを置くと、それを起動やビルドの際に実行してくれる。

今回作成するのは、

ビルド
bundle install を実行してgemを準備
起動
RackアプリケーションとしてtDiaryを起動。今回はThinを仕様。
停止
Thinサーバーを停止。

の3つ。 これらは単純なshellスクリプトとして実装できる。今回はbashを使ったが、もし既にPythonなどインストール済みであれば、それらを利用することもできるそうだ*3

ビルド
#!/bin/bash

export RBENV_ROOT="$OPENSHIFT_DATA_DIR/rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"

eval "$(rbenv init -)"

pushd ${OPENSHIFT_REPO_DIR} > /dev/null
bundle install --deployment
popd > /dev/null

まずはrbenvの場所を指定し、PATHを通してrubyが実行できるようにする。 そのあとに、OpenShigit push したソースが展開されるディレクトリに移動し、bundlerでgemをインストールする。

起動
#!/bin/bash

export RBENV_ROOT="$OPENSHIFT_DATA_DIR/rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"

eval "$(rbenv init -)"

pushd ${OPENSHIFT_REPO_DIR} > /dev/null
bundle exec thin start -d -a $OPENSHIFT_DIY_IP -p $OPENSHIFT_DIY_PORT -l $OPENSHIFT_DIY_LOG_DIR/thin.log -e production
popd > /dev/null

ここではThinに、サーバーのIPとポート、ログの出力先を指定して起動。

停止
#!/bin/bash

export RBENV_ROOT="$OPENSHIFT_DATA_DIR/rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"

eval "$(rbenv init -)"

pushd ${OPENSHIFT_REPO_DIR} > /dev/null
bundle exec thin stop
popd > /dev/null

thin stopコマンドで停止。

その他もろもろ

thinサーバーのプロセスIDはデフォルトで、tmp/pids/thin.pidに作られるため、プロジェクトの中に予め用意しておく必要がある*4

mkdir -p tmp/pids
touch tmp/pids/.gitkeeps

デプロイ

ここまでの変更をコミットして、git push すれば、デプロイ完了。

git init
git add -A
git commit -m "First Deploy"
git push origin master

参考

*1 DBやWebサーバーなど起動、停止の仕組み。

*2 development groupに記述されているのですが、productionで実行するためこれはrequireされない。

*3 試してない。おそらくPATHが通っていればできるはず。

*4 この作業を上のビルドスクリプトに含めていいかもしれない。


最近の投稿

翻訳しました(ちょっとだけ)

follow us in feedly