2015-09-18

lojinha を Cloud Foundry で動かす

「Cloud Foundry 百日行」第64日目は、Play Framework ベースのネットショッピング用アプリ lojinha です。アプリ名が見慣れない単語だったため調べてみたところ、どうもポルトガル語のようです。実際にショッピングサイトとして利用する場合は、英語等に翻訳する必要があるかもしれませんが、Play Framework のアプリをCloud Foundry で動かしてみたかったのでやってみました。

基本情報

デプロイ準備から動作確認までの手順は以下の通りです。

  • 1) Play 用ツールのインストール
  • 2) デプロイ準備
  • 3) デプロイ
  • 4) 動作確認

1. Play 用ツールのインストール

まず、Cloud Foundry へデプロイするバイナリを作成するため、デプロイ実行環境に Play用ツールの Activator をインストールします。
lojinhaのソースをみると、Play Frameworkのバージョンは 2.3.8 あたりが良さそうなので、それに対応する Activator_1.3.5 をDLページから取得してきます。
JDK 6 以降が必要なので予め準備しておいてください。

$ wget https://downloads.typesafe.com/typesafe-activator/1.3.5/typesafe-activator-1.3.5-minimal.zip
$ unzip typesafe-activator-1.3.5-minimal.zip
$ ls activator-1.3.5-minimal
activator  activator.bat  activator-launch-1.3.5.jar

解凍先を PATH へ登録し、 activator コマンドが実行できるようにします。

$ export PATH="$HOME/activator-1.3.5-minimal:$PATH"
$ activator --version
sbt launcher version 0.13.8

2. デプロイ準備

まずは、lojinha が PostgreSQL を使用するため、 PostgreSQL のサービスを作成しておきます。
もしデプロイする bosh-lite 環境に PostgreSQL サービスブローカがない場合、 百日行の「postgresql-cf-service-broker を Cloud Foundry で動かす」を参考に、事前に準備をしてください。

lojinha$ cf create-service PostgreSQL "Basic PostgreSQL Plan" lj-pg
lojinha$ cf services
:
OK

name         service      plan                    bound apps   last operation
lj-pg        PostgreSQL   Basic PostgreSQL Plan                create succeeded

次に、デプロイ用のバイナリを作成するため、 lojinha のソースを取得してきます。

$ git clone https://github.com/jcranky/lojinha.git
$ cd lojinha
lojinha$ ls
app.json  Capfile  config.ru  Gemfile  LICENSE.txt   Procfile  Rakefile  script

activator コマンドでデプロイ用のバイナリを作成します。
Warning が出るかもしれませんが、最後に success がでれば完了です。

lojinha$ activator dist

:
[info]
[success] Total time: 30 s, completed Sep 18, 2015 10:37:47 AM

zip ファイルが target/universal の下に出来ているか確認します。

lojinha$ ls target/universal/
lojinha-1.0-SNAPSHOT.zip  tmp

3. デプロイ

まずは、 no-start 指定でアプリを Push します。

lojinha$ cf push lj-100 --no-start
Creating app lj-100 in org horiu-jn / space 100nichi as horiu-jn...
OK

Creating route lj-100.10.244.0.34.xip.io...
OK

Binding lj-100.10.244.0.34.xip.io to lj-100...
OK

Uploading lj-100...
Uploading app files from: /home/horiu-jn/workspace/apps/lojinha
Uploading 6.4M, 1488 files
Done uploading
OK

次に、サービスをバインドします。

lojinha$ cf bind-service lj-100 lj-pg
Binding service lj-pg to app lj-100 in org horiu-jn / space 100nichi as horiu-jn...
OK
TIP: Use 'cf restage lj-100' to ensure your env variable changes take effect
Creating app lj-100 in org horiu-jn / space 100nichi as horiu-jn...
OK

バインドまで完了したら、 cf env コマンドで VCAP_SERVICES の情報を確認し、バインドした PostgreSQL の ユーザ名、パスワード、データベース名を確認しておきます。
Java アプリ の場合、 DATABASE_URL に格納される URL の形式と異なるため、後ほど作成するアプリデプロイ用の manifest.yml の中でJDBC URL 形式で定義します。

lojinha$ cf env lj-100
:
OK

System-Provided:
{
 "VCAP_SERVICES": {
  "PostgreSQL": [
   {
    "credentials": {
     "uri": "postgres://f7cb3f5f-01a5-4fb9-a13f-1e4c97049cdc:vbburntrrhil3l9i6vrkp6kcta@192.168.15.91:5432/f7cb3f5f-01a5-4fb9-a13f-1e4c97049cdc"
    },
    "label": "PostgreSQL",
    "name": "lj-pg",
    "plan": "Basic PostgreSQL Plan",
    "tags": [
     "PostgreSQL",
     "Database storage"
    ]
   }
  ]
 }
}
:

取得した PostgreSQL の情報を元に、デプロイ用のマニフェストを作成します。

lojinha$ vi manifest.yml
---
applications:
- name: lj-100
  memory: 1G
  path: target/universal/lojinha-1.0-SNAPSHOT.zip
  command: "PATH=$PATH:/home/vcap/app/.java-buildpack/open_jdk_jre/bin ~/lojinha-1.0-SNAPSHOT/bin/lojinha -Dhttp.port=$PORT -DapplyEvolutions.default=true -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url='jdbc:postgresql://192.168.15.91:5432/f7cb3f5f-01a5-4fb9-a13f-1e4c97049cdc?user=f7cb3f5f-01a5-4fb9-a13f-1e4c97049cdc&password=vbburntrrhil3l9i6vrkp6kcta'"

起動時点でメモリを結構使っていたので、 memory: は大きめに指定しています。
command: 部分が長いので、ポイントとなる内容を記述します。

  • コマンド全体は、ダブルクォートで囲みます。
  • java コマンドへのパスが通っていないため、 PATH でコンテナ内でコマンドのある場所へパスを通しています。
PATH=$PATH:/home/vcap/app/.java-buildpack/open_jdk_jre/bin
  • -Dhttp.port には、 $PATH を指定します。
  • -Ddb.default.url には、以下のようなフォーマットでJDBC URL を作成します。URL は必ずシングルクォートで囲んでください。
Ddb.default.url='jdbc:postgresql://<HOST>:<PORT>/<DATABAE>?user=<USER>&password=<PASSWORD>'

デプロイ用のマニフェストが作成できたら、アプリをプッシュします。

lojinha$ cf push

:
OK

requested state: started
instances: 1/1
usage: 1G x 1 instances
urls: lj-100.10.244.0.34.xip.io
last uploaded: Fri Jul 10 10:00:56 UTC 2015
stack: cflinuxfs2
buildpack: java-buildpack=v3.0-https://github.com/cloudfoundry/java-buildpack.git#3bd15e1 open-jdk-jre=1.8.0_45 play-framework-auto-reconfiguration=1.7.0_RELEASE play-framework=2.3.8

     state     since                    cpu    memory       disk      details
#0   running   2015-07-10 07:01:36 PM   0.0%   213M of 1G   0 of 1G

4. 動作確認

ブラウザから、払いだされたアプリのURLへアクセスします。

ログインして、商品情報を追加をしてみます。
URL に /login を指定してログイン画面へアクセスします。
admin の情報は何処にも書いていませんので、lojinha/conf/evolutions/default/1.sql で定義されている情報をもとにログインします。

INSERT INTO _user(email, name, passwd) VALUES('admin@lojinha.com', 'jcranky', '1234');

ログインに成功すると、 admin ページが出てきます。

まず、カテゴリーを追加してみます。
雰囲気で読めますが、 Adicionar categoria がカテゴリー追加画面へのリンクなので、クリックして表示します。

表示されたら、追加するカテゴリー名 (Nome para exibir) と、カテゴリーのURL (Nome para url) を入力し、send (Enviar) をクリックします。 ホーム画面が表示され、追加したカテゴリーが表示されます。

次に、追加したカテゴリーに商品情報を登録します。
admin ページへ戻るリンクは用意されていないため、URLへ直接 /admin を指定して戻ります。
Adicionar item が商品の追加画面へのリンクなので、クリックして表示します。

表示されたら、商品の名前、説明、個数(Lance minimo)、カテゴリを選んで、send (Enviar) をクリックします。
ホーム画面が表示され、追加された商品が表示されます。

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