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 この作業を上のビルドスクリプトに含めていいかもしれない。


2016年07月07日

_ Recruit Technologies Open Lab #03 テーマ:Infrastructure as Code に行ってきた。 #rtechlab

1ヶ月ぶりくらいに外の勉強会に参加した。 最近、またAnsibleでゴニョゴニョとレガシーなアプリケーションを牧畜するために、再現性のある環境構築をしている。 参加するまでは、「Infrastructure as Codeって、インフラをコードで書くってことっしょ?」というくらいの浅い知識でした。 ですが、単なるコード化だけではなく、その周辺への影響を知ることができた。

"Infrastructure as Code" から数年、結果どうなったか", @naoya_ito

伊藤さんと言えば、入門Chef Solo - Infrastructure as Code でChefとInfrastructure as Codeの普及を推した人として有名だ。自分もこれを読んで、Chefの勉強をして、色々環境構築をした。

伊藤さんの話で非常に面白かったのが、コード化の意義についてだった。 アプリケーションエンジニアがなぜコード化するのかと言えば、それは対象としているサービスのプロセスをモデリング化するためだ。それと同じことが、IaCでも必要なんじゃないかっていう話だった。

自分もAnsibleで書いていて、「結局これによって構築される環境の全体像みたいなものは何なのだろう」と疑問に思うことが多々ある。ドメイン駆動とかは参考になるのだろうけど、インフラって極力アプリケーションが意識しない方が嬉しくて、ブラックボックスになりそうなので、モデリングする対象がずれて来るんじゃないかなぁ、とか悶々と考えていた。これは悩ましい問題なんだろう。

"Infrastructure as Code と企業文化", @ryuzee

コンウェイの法則を元に、様々な組織の構造の中で誰がインフラのコードを書くか、そしてそれによってどのようなことが起きるのかという考察でした。 ポイントは、コミュニケーションのオーバーヘッドと責任範囲または分界点がどこなのかというところだと思いました。

やはり、1つのプロダクトに対して従事する多能工なチームが良さそう。しかしながら、チーム内で属人的な形に陥るおそれがあるので、

  • スキルマップでスキルの冗長構成を保ちつつ、
  • それぞれのチーム間での知識共有を行う といった対策が必要とのこと。

しかし、技術については現場での努力でなんとかなるところもありますが、IaCのように新しいものの導入は、変化に対する抵抗が生じるので、人間系の問題への泥臭い対応が生じる、とのことでした。

"Infrastructure as Code のこれまでとこれから ", @gosukenator

正直言って、あまり自分は理解に追いつけなかった。最新の動向とかこれから先のことを知るには良いのかも。

"プロビジョニングツールはMakeで決まりだろ", @katzchang

タイトルから、どんなネタをぶっこんでくるのだろうと思ってたのですが、まじめにmakeはデフォルトで安全に落ちるようにできてるし、DSLはなくshellで書けるので良さそう。

Tags: IaC

最近の投稿

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

follow us in feedly