2015-09-03

Publify を Cloud Foundry で動かす

「Cloud Foundry 百日行」第53日目は、Ruby on Rails製のブログアプリ Publify です。

基本情報

今回の手順の概要は以下の通りです。

  • 1) ソースコード入手
  • 2) 事前準備
  • 3) Cloud Foundry上へのデプロイ
  • 4) 動作検証

1. ソースコード入手

$ git clone https://github.com/publify/publify.git
・・・
$ cd publify/
publify$ ls -A
app           config.ru        Gemfile     .hound.yml  MIT-LICENSE  .rspec             spec         vendor
bin           CONTRIBUTING.md  .git        lib         public       rspec.sample       themes
CHANGELOG.md  db               .gitignore  log         Rakefile     .rubocop_todo.yml  TODO.txt
config        doc              Guardfile   .metrics    README.md    .rubocop.yml       .travis.yml

Ruby on Rails製のアプリです。
ローカルのインストール手順Herokuへのインストール手順が紹介されているのでこれらを参考に進めていきます。

2. 事前準備

Database周りの準備

database.yml ファイルを準備し、

publify$ cp config/database.yml.mysql config/database.yml

データベースとしてMySQLのServiceを準備します。

publify$ cf create-service p-mysql 100mb publify-mysql
Creating service instance publify-mysql in org ukaji / space default as ukaji...
OK

Gemfile修正

Cloud Foundry上で動作させるために、Gemfileを少し修正します。
ここでは既存のコードには手を加えずに、環境変数 CFtrue の時のみ特定のパッケージをインストールするように設定を追加しました。

publify$ vi Gemfile 
・・・
if ENV['CF']
  gem 'rb-readline'
  gem 'rails_12factor'
end
publify$ git diff origin/master
・・・
diff --git a/Gemfile b/Gemfile
index f56fd13..e6374a5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -102,3 +102,8 @@ end
 Dir.glob(File.join(File.dirname(__FILE__), 'themes', '**', 'Gemfile')) do |gemfile|
   eval(IO.read(gemfile), binding)
 end
+
+if ENV['CF']
+  gem 'rb-readline'
+  gem 'rails_12factor'
+end
・・・

Gemfile.lock にも変更を反映しておきます。

publify$ CF=true bundle install --path vendor/bundle
・・・
Bundle complete! 46 Gemfile dependencies, 155 gems now installed.
Bundled gems are installed into ./vendor/bundle.

Cloud Foundry上にPushしないファイルの設定

さて、上記の手順によってGemfileとGemfile.lockが修正され、それに伴いvendor/bundleディレクトリの中にパッケージがインストールされました。
ところで、RubyのアプリをCloud Foundry上で動かす際、アプリの起動前にCloud Foundry内部でGemfileとGemfile.lockの情報を元にパッケージのインストールを行う処理が走ります。つまり vendor/bundle/ 配下のパッケージはその時点で生成されるため、実はデプロイ時に手元にある vendor/bundle/ の中身をPushする必要は特にありません。
もちろん一緒にPushしてしまっても基本的には動作に影響はありませんが、わざわざネットワーク越しに送付するファイルを重くすることもないので今回は除外するような設定を行ってみましょう。
いっそディレクトリごと削除してしまってもいいのですが、ここでは .cfignore という設定ファイルを用いて、Cloud Foundryにデプロイする際にPushしないファイルを選択的に指定するという方法をとってみます。

publify$ vi .cfignore
/vendor/
/.bundle

manifestファイルの作成

manifest.yml ファイルを作っておきましょう。

publify$ vi manifest.yml
---
applications:
  - name: publify
    memory: 1G
    command: 'rake db:migrate && rake db:seed && rails server -p $PORT'
    services:
      - publify-mysql
    env:
      CF: true

これで cf push だけでデプロイができるようになるはずです。

3. Cloud Foundry上へのデプロイ

デプロイを行います。

publify$ cf push
(一部略)
-----> Uploading droplet (41M)

0 of 1 instances running, 1 starting
0 of 1 instances running, 1 starting
1 of 1 instances running

App started


OK

App publify was started using this command `rake db:migrate && rake db:seed && rails server -p $PORT`

Showing health and status for app publify in org ukaji / space default as ukaji...
OK

requested state: started
instances: 1/1
usage: 1G x 1 instances
urls: publify.10.244.0.34.xip.io
last uploaded: Fri Aug 21 04:55:06 UTC 2015
stack: cflinuxfs2
buildpack: Ruby

     state     since                    cpu    memory         disk      details   
#0   running   2015-08-21 01:57:10 PM   0.0%   184.7M of 1G   0 of 1G 

デプロイ完了です。

4. 動作検証

発行されたURLにブラウザでアクセスします。

ブログサイト名、メールアドレスを記入して Save を押すだけで登録は終了です。

管理者画面はこのように、

ブログ本体のページはこのようになっています。

新規記事作成は上のメニューの一覧から、 ArticlesNew Article を選択して作成します。

Media Library メニューでは画像などのファイルの追加などもできます。

今回使用したソフトウェア