オープンソースのPaaSソフトウェア CloudFoundry の技術情報やイベント告知などを掲載します

2015-10-05

Concerto を Cloud Foundry で動かす

「Cloud Foundry 百日行」第72日目,今回は少し変わり種で,ディジタル・サイネージ配信アプリの Concerto です。ディジタル・サイネージはあまりよく知らない分野であるため,今回「動いた」と言えるかどうかは微妙なのですが,少なくとも配信サーバー側は動いたので,それを記事にしました。

なお,Concerto は Ruby on Rails ベースのアプリなのですが,今回は (なぜか) production モードでは動作しなかったので,無理やり development モードで動作させています。悪しからずご了承ください。

基本情報

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

  • 1) ソースコードの取得
  • 2) 起動スクリプトの準備 (及びその他の修正)
  • 3) サービスの作成及びアプリとのバインド
  • 4) アプリの起動
  • 5) 動作確認

1. ソースコードの取得

GitHub からソースコードを clone します。

$ git clone https://github.com/concerto/concerto.git

ディレクトリーを移動して,2.3.0 を checkout します。

$ cd concerto/
$ git checkout 2.3.0

2. 起動スクリプトの準備 (及びその他の修正)

本アプリを Cloud Foundry 上で動作させるにあたっては,(ほぼ) 起動スクリプトを追加するだけでOKでした。やはり Ruby on Rails のアプリは PaaS 上で動かすのが比較的容易なようです。

2.1. 起動スクリプトの作成

などを参考に起動スクリプトを作成しました。最終的には以下のようになりました。

$ cat start.sh
#!/bin/bash

set -x

## run in development mode
RACK_ENV=development
RAILS_ENV=$RACK_ENV

## setup database
bundle exec rake db:migrate
bundle exec rake db:seed

## prepare logdir for clock & worker
logdir=${HOME}/../logs/
mkdir -p $logdir

## start clock
bundle exec clockwork lib/cron.rb >> ${logdir}/clock-1.log 2>&1 &
sleep 5

## start worker
bundle exec rake jobs:work >> ${logdir}/worker-1.log 2>&1 &
sleep 5

## start server
bundle exec rackup -p $PORT

以下,簡単に説明します。

  • 5 - 7 行目:
    アプリを development モードで起動するための環境変数設定です
    Cloud Foundry の ruby-buildpack では通常,これらの環境変数は production に設定されます
    今回のアプリは,調査の結果,Cloud Foundry 上だけでなくローカルでも production モードでは正常に動作しなかったので,このような設定を行ってアプリが development モードで起動するようにしています

  • 9 - 11 行目:
    データベースのスキーマ設定及び初期データ投入です

  • 13 - 15 行目:
    後述する clock 及び worker プロセスがログを書き込むディレクトリーを作成しています
    このディレクトリーがないとこれらプロセスの起動に失敗しエラーが起きることへの対策です

  • 17 - 19 行目:
    clock プロセスを起動します

  • 21 - 23 行目:
    worker プロセスを起動します

  • 25 - 26 行目:
    配信サーバー本体の起動です
    config.ru が既にあるので, rackup で起動しています

2.2. その他の修正

Gemfile の修正

Cloud Foundry の ruby-buildpack では,起動だけでなく (当然) ステージングも production モードで行います。

しかし本アプリではなぜかステージング時に sqlite3 gem を必要とするようで,production モードで bundle install が行われると,その後の処理で sqlite3 gem が見つからないというエラーが発生しました。

/home/vcap/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.1.12/lib/active_record/connection_adapters/connection_specification.rb:190:in `rescue in spec': Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)
..

そこでこの問題を回避するために,sqlite3 gem の group 設定を外しました。

$ git diff 2.3.0 -- Gemfile
diff --git a/Gemfile b/Gemfile
index 0e4c6d4..2d2911f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -61,7 +61,7 @@ gem 'bundler-audit', :require => false, :group => :test

 gem 'kaminari'

-gem 'sqlite3', :group => [:development, :test]
+gem 'sqlite3'

 gem 'mysql2', :group => :mysql
 gem 'pg', :group => :postgres

.cfignore の追加 (optional)

これは必須ではありませんが,ローカルで試しに起動したりした場合,Cloud Foundry 上では不要なファイルがディレクトリー内に生成されて, cf push 時にアップロードされてしまうので,.cfignore ファイルを作っておいたほうが便利です。

今回は .gitignore ファイルと全く同じ内容でOKだった(多くの場合 .gitignore と .cfignore の内容は似たものになります)ので,.gitignore ファイルをコピーして .cfignore ファイルを作りました。

$ cp .gitignore .cfignore
$ cat .cfignore
.bundle
db/*.sqlite3
log/*.log
tmp/
.sass-cache/
tmp/restart.txt
config/database.yml
public/.htaccess
.DS_Store
doc/app/*
public/assets/*
public/frontend_js/compiler.jar
vendor/bundle/
doc/coverage/*
.ruby-version
.ruby-gemset
.powrc
Gemfile-plugins.bak
Gemfile.local

3. サービスの作成及びアプリとのバインド

アプリのアップロード

サービスとバインドするために,アプリを停止状態でプッシュします。

$ cf push concerto --no-start
Creating app concerto in org nota-ja / space 100 as nota-ja...
..
OK

サービスの作成

$ cf create-service p-mysql 100mb mysql-concerto
Creating service instance mysql-concerto in org nota-ja / space 100 as nota-ja...
OK

アプリとサービスのバインド

$ cf bind-service concerto mysql-concerto
Binding service mysql-concerto to app concerto in org nota-ja / space 100 as nota-ja...
OK
TIP: Use 'cf restage concerto' to ensure your env variable changes take effect

4. アプリの起動

起動コマンドとメモリを指定してアプリを再度プッシュし,起動します。
試行錯誤の結果,本アプリは512MBほどのメモリを割り当てるのが良さそうでした。

$ cf push concerto -c './start.sh' -m 512m
Updating app concerto in org nota-ja / space 100 as nota-ja...
OK
..
requested state: started
instances: 1/1
usage: 512M x 1 instances
urls: concerto.10.244.0.34.xip.io
last uploaded: Tue Sep 29 11:10:56 UTC 2015
stack: cflinuxfs2
buildpack: Ruby

     state     since                    cpu    memory           disk      details
#0   running   2015-09-29 08:13:48 PM   0.0%   344.6M of 512M   0 of 1G

起動しました。

5. 動作確認

アプリの URL (http://concerto.10.244.0.34.xip.io) にアクセスすると,初期ユーザー登録画面にリダイレクトされます:

必要事項を入力して【Let’s Get Started!】をクリックします:

ユーザー登録に成功すると,ログイン済みの状態で設定画面に遷移します:

とりあえず設定は無視して,【Browse】をクリックしてコンテンツをブラウズしてみると,【Concerto】という登録済みのフィードが見えます:

【Concerto】をクリックして中を見てみますが,何も登録されていません:

【Add】をクリックして,グラフィックを追加してみます:

今度は【Text】タブからティッカーを追加してみます:

コンテンツの追加後,広告の表示がどうなったかをプレビューで見ることができます。

【Screens】をクリックすると,”Concerto” フィードに割り当てられた【Sample Screen】があるのが見えます:

【Sample Screen】をクリックすると,スクリーンのレイアウトが表示されます:

【Preview Screen】をクリックすると,今追加したコンテンツがレイアウトに合わせて表示されました:

以上で動作確認は終わりです。

感覚的には,プレゼンテーション・ソフトでアニメーションを作るのと似た印象を受けました。これくらいなら (センスの問題は措くとして; 上の例のセンスがひどいのは自分でもわかっています) 私にも作れるかも,と思いました。

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