Rubyが好きなプログラマーの日記。日々の生活、開発に関するメモとか考えとか。
Redhatが手がけるPaaSプラットフォームOpenShiftにtDiaryをデプロイしたので、今日はその方法について書きます。 「OpenShiftって何?」とか「PaaSって何?」、「tDiaryって何?」という方は自分で調べて下さい。
OpenShiftは、Rubyのアプリを実行するカートリッジ*1として、
を提供していて、Ruby 1.9を以前に試したのですが、Passengerの不具合があり、POSTやPUTのリクエストがちゃんと受けれないという問題がありました。 これで日記を書くのが困難であると思い、まったく何も無い状態から自分でサーバーやランタイムを設定するDIY(Do It Yourself)カートリッジを選びました。
DIYだからといって、DBのセットアップなど他のカートリッジと組み合わせることは可能です。 なのでDIYでやることは
の2つです。後者はアプリケーション、つまりtDiaryのプロジェクトで作成するので後ほど。
アカウントの作成は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の実行環境をセットアップします。
参考の記事では、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は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している。
OpenShiftはHerokuのようにOpenShift上にあるGitリポジトリへpushすると、所定のスクリプトが実行され、アプリケーションのデプロイから起動まで行われる。 今回はDIYカートリッジなので、所定のスクリプトというものは無く、自身で定義する必要がある。 OpenShiftはデプロイするプロジェクトに.openshift/action_hooks下に所定の名前のスクリプトを置くと、それを起動やビルドの際に実行してくれる。
今回作成するのは、
の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ヶ月ぶりくらいに外の勉強会に参加した。 最近、またAnsibleでゴニョゴニョとレガシーなアプリケーションを牧畜するために、再現性のある環境構築をしている。 参加するまでは、「Infrastructure as Codeって、インフラをコードで書くってことっしょ?」というくらいの浅い知識でした。 ですが、単なるコード化だけではなく、その周辺への影響を知ることができた。
伊藤さんと言えば、入門Chef Solo - Infrastructure as Code でChefとInfrastructure as Codeの普及を推した人として有名だ。自分もこれを読んで、Chefの勉強をして、色々環境構築をした。
伊藤さんの話で非常に面白かったのが、コード化の意義についてだった。 アプリケーションエンジニアがなぜコード化するのかと言えば、それは対象としているサービスのプロセスをモデリング化するためだ。それと同じことが、IaCでも必要なんじゃないかっていう話だった。
自分もAnsibleで書いていて、「結局これによって構築される環境の全体像みたいなものは何なのだろう」と疑問に思うことが多々ある。ドメイン駆動とかは参考になるのだろうけど、インフラって極力アプリケーションが意識しない方が嬉しくて、ブラックボックスになりそうなので、モデリングする対象がずれて来るんじゃないかなぁ、とか悶々と考えていた。これは悩ましい問題なんだろう。
コンウェイの法則を元に、様々な組織の構造の中で誰がインフラのコードを書くか、そしてそれによってどのようなことが起きるのかという考察でした。 ポイントは、コミュニケーションのオーバーヘッドと責任範囲または分界点がどこなのかというところだと思いました。
やはり、1つのプロダクトに対して従事する多能工なチームが良さそう。しかしながら、チーム内で属人的な形に陥るおそれがあるので、
しかし、技術については現場での努力でなんとかなるところもありますが、IaCのように新しいものの導入は、変化に対する抵抗が生じるので、人間系の問題への泥臭い対応が生じる、とのことでした。
正直言って、あまり自分は理解に追いつけなかった。最新の動向とかこれから先のことを知るには良いのかも。
タイトルから、どんなネタをぶっこんでくるのだろうと思ってたのですが、まじめにmakeはデフォルトで安全に落ちるようにできてるし、DSLはなくshellで書けるので良さそう。