---
title: オレオレブログAPIサーバーCategoLJ3をデプロイしよう(Cloud Foundry編)
tags: ["CategoLJ3", "Cloud Foundry", "Spring Boot"]
categories: ["Dev", "Blog", "CategoLJ3"]
date: 2015-12-29T13:05:04Z
updated: 2015-12-29T13:16:24Z
---

[前回](https://blog.ik.am/entries/365)はCategoLJ3をHerokuにデプロイする方法を見てきました。次はCloud Foundryにデプロイする方法を紹介します。

まずはElasticsearchのサービスを用意している[Pivotal Web Services (PWS)](https://run.pivotal.io/)を使用します。
Cloud Foundry及び、PWSの設定方法は[こちらの記事](https://blog.ik.am/entries/359)を参照してください。

まずは、ElasticsearchのサービスであるSearchlyのサービスを`blog-es`という名前で作成します。

	$ cf create-service searchly starter blog-es
	Creating service instance blog-es in org maki-org / space development as ***...
	OK

PWSの[Searchlyサービスマニュアル](http://docs.run.pivotal.io/marketplace/services/searchly.html)を見ると、サービスをアプリにバインドすると環境変数`VCAP_SERVICES`に次のようなJSONが設定されることがわかります。

	{
	  searchly: [
	    {
	      name: "searchly-1",
	      label: "searchly",
	      tags: [ ],
	      plan: "starter",
	      credentials: {
	        uri: "http://cloudfoundry:f0d15584ef7b5dcd1c5c1794ef3506ec@api.searchbox.io",
	        sslUri: "https://cloudfoundry:f0d15584ef7b5dcd1c5c1794ef3506ec@api.searchbox.io"
	      }
	    }
	  ]
	}

この中で重要なのは`credentials`に設定されている値です。ここにサービスへの接続情報が設定されています。

Spring Bootでは`VCAP_SERVICES`に設定された`credentials`値は`vcap.services.(service名).credentials`プロパティでアクセスできます。
上の例では、

* `vcap.services.searchly-1.credentials.uri=http://cloudfoundry:f0d15584ef7b5dcd1c5c1794ef3506ec@api.searchbox.io`
* `vcap.services.searchly-1.credentials.sslUri=https://cloudfoundry:f0d15584ef7b5dcd1c5c1794ef3506ec@api.searchbox.io`

です。

今回は、`cf create-service`でサービス名`blog-es`を指定したので、作成したサービスへの接続情報は`vcap.services.blog-es.credentials.sslUri`プロパティでアクセスできます。

Spring BootアプリではCloud Foundryにデプロイすると自動で`cloud`プロファイルが適用されます。したがって、Cloud Foundryでのみ有効になるプロパティは`application-cloud.properties`に書けば良いです。(Cloud Foundry上の設定を行う方法は他にも[いろいろ](https://spring.io/blog/2015/04/27/binding-to-data-services-with-spring-boot-in-cloud-foundry)ありますが、個人的には`application-cloud.properties`を使う方法がお気に入りです)

CategoLJ3をCloud Foundryにデプロイする場合は、`application-cloud.properties`に以下の設定をしてください。

	jest.connection-url=${vcap.services.blog-es.credentials.sslUri}

あとはビルドしてデプロイしましょう。アプリの作り方は[こちら](https://blog.ik.am/entries/364)を参照してください。
サービスのバインドが必要なので、`--no-start`をつけて、一旦起動しないようにしておきます。

	$ mvn clean package -Dmaven.test.skip=true
	$ cf push demo -p target/demo-0.0.1-SNAPSHOT.jar -m 512m --no-start --random-route
	Creating app demo in org maki-org / space development as ***...
	OK
	
	Creating route demo-untinkered-turnbuckle.cfapps.io...
	OK
	
	Binding demo-untinkered-turnbuckle.cfapps.io to demo...
	OK
	
	Uploading demo...
	Uploading app files from: target/demo-0.0.1-SNAPSHOT.jar
	Uploading 667.2K, 95 files
	Done uploading               
	OK

(補足ですが、`--random-route`をつけることで、ホスト名が`アプリケーション名-ランダムな文字列`になり、重複を避けられます。)

サービスをバインドしましょう。
	
	$ cf bind-service demo blog-es
	Binding service blog-es to app demo in org maki-org / space development as ***...
	OK
	TIP: Use 'cf restage' to ensure your env variable changes take effect
	
あとは起動すればデプロイ完了です。

	$ cf start demo
	Starting app demo in org maki-org / space development as ***...
	Creating container
	(略)
	Uploading complete
	
	0 of 1 instances running, 1 starting
	0 of 1 instances running, 1 starting
	1 of 1 instances running
	
	App started
	
	
	OK
	
	App demo was started using this command `CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-2.0.1_RELEASE -memorySizes=metaspace:64m.. -memoryWeights=heap:75,metaspace:10,native:10,stack:5 -memoryInitials=heap:100%,metaspace:100% -totMemory=$MEMORY_LIMIT) && SERVER_PORT=$PORT $PWD/.java-buildpack/open_jdk_jre/bin/java -cp $PWD/.:$PWD/.java-buildpack/spring_auto_reconfiguration/spring_auto_reconfiguration-1.10.0_RELEASE.jar -Djava.io.tmpdir=$TMPDIR -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh $CALCULATED_MEMORY org.springframework.boot.loader.JarLauncher`
	
	Showing health and status for app demo in org maki-org / space development as ***...
	OK
	
	requested state: started
	instances: 1/1
	usage: 512M x 1 instances
	urls: demo-untinkered-turnbuckle.cfapps.io
	package uploaded: Tue Dec 29 12:18:34 UTC 2015
	stack: cflinuxfs2
	buildpack: java-buildpack=v3.3.1-https://github.com/cloudfoundry/java-buildpack.git#063836b java-main open-jdk-like-jre=1.8.0_65 open-jdk-like-memory-calculator=2.0.1_RELEASE spring-auto-reconfiguration=1.10.0_RELEASE
	
	     state     since                    cpu    memory           disk         details   
	#0   running   2015-12-29 09:25:32 PM   0.0%   379.4M of 512M   188M of 1G 

あとはHeroku編と同じです。

	$ curl https://demo-untinkered-turnbuckle.cfapps.io/api/entries | jq .
	{
	  "content": [],
	  "last": true,
	  "totalPages": 0,
	  "totalElements": 0,
	  "first": true,
	  "numberOfElements": 0,
	  "sort": null,
	  "size": 10,
	  "number": 0
	}

Elasticesearchへの初回のみre-indexも行いましょう。

	$ curl https://demo-untinkered-turnbuckle.cfapps.io/api/jest/reindex

これでGitの記事が反映されました。

	$ curl https://demo-untinkered-turnbuckle.cfapps.io/api/entries | jq .
	{
	  "content": [
	    {
	      "entryId": 1,
	      "content": "This is my first article using CategoLJ3!",
	      "created": {
	        "name": "Toshiaki Maki",
	        "date": "2015-12-28T17:16:23Z"
	      },
	      "updated": {
	        "name": "Toshiaki Maki",
	        "date": "2015-12-28T17:16:23Z"
	      },
	      "frontMatter": {
	        "title": "First article",
	        "tags": [
	          "Demo"
	        ],
	        "categories": [
	          "Demo",
	          "Hello"
	        ]
	      }
	    }
	  ],
	  "last": true,
	  "totalPages": 1,
	  "totalElements": 1,
	  "first": true,
	  "numberOfElements": 1,
	  "sort": null,
	  "size": 10,
	  "number": 0
	}

ではElasticsearchのサービスがないCloud Foundryはどうでしょうか。
例えば、ローカルで試すためのMicroPCF(インストール記事は[こちら](https://blog.ik.am/entries/361))だと、`cf create-service searchly starter blog-es`を実行してもサービスが見つからず、エラーになります。

これに対する方法はいくつかあるのですが、[User-Provided Service](https://docs.cloudfoundry.org/devguide/services/user-provided.html)という仕組みを使うのが一番簡単です。
User-Provider Serviceを使うと、DBやWebアプリなどの外部サービスに対する接続情報(credentials)を、これまで見てきたCloud Foundryのサービスと同じように`VCAP_SERVICES`に設定することができます。

`cf create-user-provided-servce`コマンドの`-p`に`VCAP_SERVICES`中の`credentials`のJSONを設定できます。ローカルのElasticesearchにアクセスするために次のコマンドを実行します。

	$ cf create-user-provided-service blog-es -p '{"uri" : "http://192.168.99.100:9200", "sslUri" : "http://192.168.99.100:9200"}'
	Creating user provided service blog-es in org maki-org / space development as admin...
	OK

これで、PWSを全く同じように`vcap.services.blog-es.credentials.sslUri`プロパティにElasticsearchへの接続情報(この場合、`http://192.168.99.100:9200`)が設定されます。

あとは上と全く同じく、

	$ cf push demo -p target/demo-0.0.1-SNAPSHOT.jar -m 512m --no-start
	$ cf bind-service demo blog-es
	$ cf start demo
	
でデプロイできます。jarは同じもので構いません。

この方法であれば、どのCloud Foundryでもデプロイできます。

ちなみに`VCAP_SERVICES`には以下のようなJSONが設定されます。

	
    {
     "user-provided": [
      {
       "credentials": {
        "sslUri": "http://192.168.99.100:9200",
        "uri": "http://192.168.99.100:9200"
       },
       "label": "user-provided",
       "name": "blog-es",
       "syslog_drain_url": "",
       "tags": []
      }
     ]
    }

----

Cloud Foundry版のソースコードは[こちら](https://github.com/categolj/categolj3-demo/tree/cloudfoundry)です。

Cloud Foundry、HerokuとPaaSに簡単にCategoLJ3をデプロイできることを見てきました。
このAPIサーバーを使って、オレオレブログ作ってみませんか？
