--- title: Cloud FoundryにSpring Boot/Java EEアプリケーションをデプロイしよう tags: ["Cloud Foundry", "Spring Boot", "Java EE"] categories: ["Service", "PaaS", "CloudFoundry"] date: 2015-12-05T10:15:32Z updated: 2015-12-07T06:54:32Z --- Java EE アドベントカレンダー 2015 5日目の記事です。 Cloud FoundryにJavaアプリをデプロイする方法を紹介します。 ## Cloud Foundryとは Cloud FoundryはオープンソースのPaaSプラットフォームです。 PaaSというとHerokuやGoogle App Engine、AWS Elastic Beanstalkあたりを思うかもしれませんが、これらはプロプライエタリなPaaSであり、Cloud Foundryとは若干カテゴリが異なります。Cloud FoundryはOSSのオープンPaaSなので、通常はIaaS([AWS](http://docs.cloudfoundry.org/deploying/ec2/), [OpenStack](http://docs.cloudfoundry.org/deploying/openstack/), [VMWare vSphere](http://docs.cloudfoundry.org/deploying/vsphere/)など)や[普通のLinux](http://docs.cloudfoundry.org/deploying/run-local.html)上にインストールすることもできます。先日、Azureでも利用できることがMicrosoftから[アナウンス](https://azure.microsoft.com/en-us/blog/general-availability-of-cloud-foundry-and-preview-access-of-pivotal-cloud-foundry/)されました。 同様なオープンPaaSにはOpenShiftがあります。 Cloud Foundryは[Cloud Foundry Foundation](https://www.cloudfoundry.org)というJavaでいうところのJCPのような標準団体で開発されています。PivotalやIBMが中心のようですが、日本からもNTT、富士通、日立が[参加しています](https://www.cloudfoundry.org/membership/members/)。 色々な会社がCloud FoundryをベースにパブリックなPaaSサービスを展開したり、自社開発向けのPaaS基盤を作成したりしています。 有名なパブリックCloud Foundryには * Pivotal Web Services (PWS) https://run.pivotal.io/ * IBM BlueMix https://console.ng.bluemix.net/ があります。自分でPaaSのインストールをする手間が省けます。 日本国内でも * Cloudn PaaS https://www.ntt.com/cloudn/data/paas.html * FUJITSU Cloud Service K5 http://jp.fujitsu.com/solutions/cloud/k5/ でCloud Foundryが使用されています。 Cloud Foundryを使用しているこれらのサービスに対してはどれも同じコマンドでアプリケーションをデプロイすることができ、移植性が高いです。 各社は周辺サービスや運用機能、管理画面、料金体系などで差別化しているようです。 自社のPaaS基盤を構築する場合は、OSSを自前でインストールして運用するか、Cloud foundryのディストリビューション(Linuxに対するRedHat Enterprise Linuxみたいなもの)を利用することになります。 ディストリビューションで有名なものには * Pivotal Cloud Foundry (PCF) https://pivotal.io/jp/platform があります。 PCFはOSS版に含まれていない様々なサービス(Hadoop, RabbitMQ, Neo4J, Riak, Cassandra, Jenkins, Spring Cloudなど)を含んでいたり、運用面でもOSパッチなどソフトウェアアップデートをダウンタイムなしに実施していく機能があったりで、使えている人が羨ましい限りです。 先日、NTTデータがアジャイル開発基盤としてPCFを利用することを[ニュースリリースしました](http://www.nttdata.com/jp/ja/news/release/2015/120201.html)。 また12/3に行われた[Pivotal Japan Summit 2015](https://omniattend.com/seminar/pivotal/pjs2015)でYahoo! Japanが自社の次期PaaS基盤としてPCFを採用することを[発表しました](https://omniattend.com/follow_up/pivotal/pjs2015/download_material/95)。 日本でもじわじわCloud Foundryの採用が進んできていますね。 Cloud Foundryの概要は↓の資料がわかりやすいです。 https://speakerdeck.com/ozzozz/tokyo ## Cloud Foundryを使ってみよう 前置きが長くなりましたが、早速Cloud Foundryを使ってアプリケーションをデプロイしましょう。 今回は[Pivotal Web Services](https://run.pivotal.io)を使用します。60日間の無料期間があります。無料期間はクレジットカードの登録も不要なので気軽に利用できると思います。それ以降はクレジットカードを登録し、起動しているアプリのメモリ量 x 時間に従って課金されます($0.03/GB-hour)。 無料期間は計2GB、10アプリまで運用することができます。 Cloud FoundryではアプリはHerokuと同じく[buildpack](http://docs.cloudfoundry.org/buildpacks/)という仕組みでビルドされます。 標準で対応している言語(というかランタイム)は * Java * Node.js * Ruby * Binary * Go * PHP * Python * Staticfile です。当然、本記事ではJavaを扱いますが、Java以外も使い方は同じです。 (ぶっちゃけ、JavaよりもGoで書くほうがメモリ使用量が少ないので安く運用できます) JavaアプリはSpring Bootのような実行可能なjarの相性が良いのは間違いありませんが、 普通のwar形式でもbuildpackがTomcatを埋め込んでくるので使えますし、Java EEも利用可能です。いまのところWebSphere Liberty Profileだけですが。 また、自分でbuildpackを作ることもできるので、標準ラインナップが気に入らなければ、自作すればだいたい何でもできるでしょう。 ちなみにCloud Foundryの最新版ではbuildpack以外にもDockerイメージや.NETアプリケーションに対応しています。 ### PWSにサインアップ [こちら](https://console.run.pivotal.io/register)からアカウントを作って下さい。 signup.png 私は既に登録済みで、再現できないのでこの後の手順は割愛します・・・簡単です。 ### Organizationの作成 サインアップがおわったら、まず最初にOrganizationを作成します。 Organizationはプロジェクト単位のようなもので、メンバー情報を紐づけることができます。課金もOrganization単位です。 アカウント作成後は[こちら](https://console.run.pivotal.io/)からログインして、左の「ORG」の右の「∨」時の記号をクリックしてOrganizationを作成します。 スクリーンショット 2015-12-05 14.09.53.png Org名を入力して、「Create Org」をクリックしてください。 Organizationができると以下のような画面ができます。 スクリーンショット 2015-12-05 14.33.48.png Organizationの下にはSpaceという単位があります。Spaceは環境のようなもので、「開発」、「ステージング」、「プロダクション」のような単位で作成します。デフォルトで`development`が作られています。Spaceの下にApplicationがデプロイされます。 ### コマンドラインインターフェースのインストール ここまで画面をぽちぽちしてきましたが、Cloud Foundryの操作はREST APIで用意されており、CLI(`cf`コマンド)で実行可能です。 CLIは[こちら](https://github.com/cloudfoundry/cli#downloads)からダウンロードしてください。 Macの場合はbrewで以下のようにインストールすることもできます。 ``` bash $ brew tap pivotal/tap $ brew install cloudfoundry-cli ``` 記事作成時点での`cf`コマンドの最新版は6.14です。 ``` bash $ cf -v cf version 6.14.0+2654a47-2015-11-18 ``` `cf`コマンドはPWS専用のツールではなく、全てのCloud Foundryサービスで利用可能です(CF v1のものを除く)。PWSを操作するには、まずAPIのエンドポイントを設定する必要があります。 ``` bash $ cf api api.run.pivotal.io Setting api endpoint to api.run.pivotal.io... OK API endpoint: https://api.run.pivotal.io (API version: 2.43.0) Not logged in. Use 'cf login' to log in. ``` 次にログインします。 ``` $ cf login API endpoint: https://api.run.pivotal.io Email> メールアドレス Password> パスワード Authenticating... OK Targeted org maki-org Targeted space development API endpoint: https://api.run.pivotal.io (API version: 2.43.0) User: メールアドレス Org: maki-org Space: development ``` 対象のOrgとSpaceが選択されます。先ほど作成したOrgが使用されていますことがわかります。 ### アプリケーションのデプロイ いよいよアプリケーションをデプロイします。まずは簡単なSpring Bootアプリを使います。一応、Java EEアドベントカレンダーなので、後でJava EEアプリもデプロイします。 Javaアプリのデプロイは基本的に 1. jar or warを作成 2. `cf push` 以上です。簡単。 以下のようなアプリケーションを使用します。`getenv`のところは今は気にしないでください。 ``` java package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class HelloPwsApplication { @RequestMapping("/") String hello() { return "Hello from " + System.getenv("CF_INSTANCE_ADDR"); } public static void main(String[] args) { SpringApplication.run(HelloPwsApplication.class, args); } } ``` GitHubに[push](https://github.com/making/hello-pws)してあるので、cloneしてビルドしてください。 ``` bash $ git clone https://github.com/making/hello-pws $ cd hello-pws $ ./mvnw package ``` デプロイは基本的に ``` bash $ cf push hello-pws -p target/hello-pws.jar ``` で良いのですが、今回はメモリをけちって`-m`オプションをつけます。 `cf push`の後はhello-pwsはドメイン内でユニークである必要があり、重複している場合はエラーになります。本記事の内容を試す場合は、別の名前を使用することをお勧めします。 ``` bash $ cf push hello-pws -p target/hello-pws.jar -m 256M Creating app hello-pws in org maki-org / space development as メールアドレス... OK Creating route hello-pws.cfapps.io... OK Binding hello-pws.cfapps.io to hello-pws... OK Uploading hello-pws... Uploading app files from: target/hello-pws.jar Uploading 485.1K, 89 files Done uploading OK Starting app hello-pws in org maki-org / space development as メールアドレス... Creating container Successfully created container Downloading app package... Downloaded app package (11.7M) No buildpack specified; fetching standard buildpacks to detect and build your application. Downloading buildpacks (staticfile_buildpack, java_buildpack, ruby_buildpack, nodejs_buildpack, go_buildpack, python_buildpack, php_buildpack, liberty_buildpack, binary_buildpack)... Downloading staticfile_buildpack... Downloading java_buildpack... (略) Staging... -----> Java Buildpack Version: v3.3.1 | https://github.com/cloudfoundry/java-buildpack.git#063836b -----> Downloading Open Jdk JRE 1.8.0_65 from https://download.run.pivotal.io/openjdk/trusty/x86_64/openjdk-1.8.0_65.tar.gz (3.9s) Memory Settings: -Xmx160M -Xms160M -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=64M -Xss853K -----> Downloading Spring Auto Reconfiguration 1.10.0_RELEASE from https://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.10.0_RELEASE.jar (0.0s) Exit status 0 Staging complete Uploading droplet, build artifacts cache... Uploading droplet... Uploading build artifacts cache... Uploaded build artifacts cache (44.7M) Uploaded droplet (56.7M) 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 hello-pws 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 hello-pws in org maki-org / space development as メールアドレス... OK requested state: started instances: 1/1 usage: 256M x 1 instances urls: hello-pws.cfapps.io package uploaded: Sat Dec 5 06:26:35 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-05 03:27:34 PM 0.0% 79M of 256M 162.7M of 1G ``` PWSではデフォルトで`[APPNAME].cfapps.io`にルーティングされます。 アクセスしてみましょう。 ``` bash $ curl http://hello-pws.cfapps.io Hello from 10.10.114.65:64587 ``` アプリケーションが簡単にデプロイできることがわかりました。 ログは ``` bash $ cf logs hello-pws --recent ``` で確認できます。 PWSのSpace管理画面では以下のように表示されます。 スクリーンショット 2015-12-05 15.37.07.png また、アプリケーションの画面では以下のように表示されます。 スクリーンショット 2015-12-05 15.39.45.png ## Cloud Foundryの運用面を試そう Cloud Foundryの良さはデプロイが簡単なことだけではありません。運用面でも色々な優れた機能があります。 ### 簡単スケール アプリケーション画面の右上の「Configuration」に「Instances」と「Memory Limit」が見えると思います。ここを変更するだけでアプリケーションをスケールさせることができます。奮発して4インスタンスにスケールアウトしてみます。 スクリーンショット 2015-12-05 15.43.06.png あっという間にスケールアウトしました。 スクリーンショット 2015-12-05 15.45.35.png Cloud Foundryにはルーターが含まれており、複数のインスタンスが設定不要でロードバランスされます。 `http://hello-pws.cfapps.io`に何度かアクセスすると、4種類のインスタンスからレスポンスが返ってきているのがわかります。 ``` bash $ for i in `seq 1 20`; do curl http://hello-pws.cfapps.io; echo ;done Hello from 10.10.115.91:60224 Hello from 10.10.114.65:64587 Hello from 10.10.114.43:61547 Hello from 10.10.115.78:62878 Hello from 10.10.115.91:60224 Hello from 10.10.114.43:61547 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.114.43:61547 Hello from 10.10.115.78:62878 Hello from 10.10.114.43:61547 Hello from 10.10.115.78:62878 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 Hello from 10.10.115.91:60224 Hello from 10.10.114.65:64587 Hello from 10.10.115.78:62878 Hello from 10.10.114.43:61547 Hello from 10.10.114.65:64587 ``` スケールの変更はコマンドラインからも行えます。 ``` bash $ cf scale hello-pws -i 4 ``` ### 自動復旧 今回デプロイしたアプリケーションにはSpring Boot Actuatorのシャットダウン機能を有効にしています。 以下のアクセスでインタンスが落ちます。 ``` bash $ curl -X POST http://hello-pws.cfapps.io/shutdown {"message":"Shutting down, bye..."} ``` この状態で再度アプリケーションにアクセスしましょう。 ``` bash $ for i in `seq 1 20`; do curl http://hello-pws.cfapps.io; echo; done Hello from 10.10.115.78:62878 Hello from 10.10.115.91:60224 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 Hello from 10.10.114.65:64587 Hello from 10.10.115.78:62878 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.114.65:64587 Hello from 10.10.114.65:64587 Hello from 10.10.115.78:62878 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 Hello from 10.10.115.78:62878 Hello from 10.10.114.65:64587 ``` さっきまでいた`10.10.114.43:61547`からのレスポンスがなくなっていることがわかります。 ルーターがインスタンスのダウンを検知して、ロードバランス対象から外してくれます。 そして、さらに素晴らしいことにCloud Foundryはダウンしたインスタンスの復旧を試みます。しばらくして再度アプリケーションにアクセスすると、 ``` bash $ for i in `seq 1 20`; do curl http://hello-pws.cfapps.io; echo; done Hello from 10.10.115.91:60224 Hello from 10.10.114.65:64587 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 Hello from 10.10.115.78:62878 Hello from 10.10.114.60:63367 Hello from 10.10.114.60:63367 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 Hello from 10.10.114.60:63367 Hello from 10.10.114.60:63367 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.114.65:64587 Hello from 10.10.115.91:60224 Hello from 10.10.115.78:62878 ``` 新たに`10.10.114.60:63367`が追加され、4インスタンスが保たれていることがわかります。 Cloud Foundryはアプリのデプロイが簡単なのはもちろんですが、ヘルスチェック付きLB構成のインフラを自分で構築する必要もなくて、とても楽チンです。 遊び終わったので1インスタンスに戻しておきます。 ``` bash $ cf scale hello-pws -i 1 Scaling app hello-pws in org maki-org / space development as メールアドレス... OK ``` ### オートスケール オートスケールの機能はCloud Foundry標準では用意されていません。自分で用意する必要があります。ただしPWSやPCFはオートスケール用のサービスを提供しています。 「Marketplace」という[サービス一覧](http://docs.run.pivotal.io/marketplace/)からアプリケーションへバインドするサービスとプランを選択できます。Marketplaceのラインナップは各社で異なります。 スクリーンショット 2015-12-05 17.15.59.png App Autoscalerがオートスケーリング用のサービスです。現時点でPWSには無償のプランのみが用意されています。 スクリーンショット 2015-12-05 17.16.12.png 詳細は[こちら](https://docs.pivotal.io/pivotalcf/customizing/autoscale-configuration.html)を参照してください。 ### Blue/Greenデプロイメントを実現 Cloud Foundryの機能を使うことでBlue/Greenデプロイメントというダウンタイムをできるだけ減らすリリーステクニックを[簡単に実現できます](https://docs.pivotal.io/pivotalcf/devguide/deploy-apps/blue-green.html)。 Blue/Greenデプロイメントは簡単にいうと、Blueと呼ばれる現行バージョンとGreenと呼ばれる次期バージョンを同時にプロダクション環境にデプロイし、Greenを十分にテストした後、Greenにルーティングを向くように変更し、Blueへのルーティングを外すという手法です。 まずは`cf routes`コマンドでルーティング情報を確認します。 ``` bash $ cf routes Getting routes as メールアドレス ... space host domain apps development hello-pws cfapps.io hello-pws ``` アプリケーションをバージョンアップします。(レスポンスの文字列を変えるだけ) ``` bash $ git checkout v2 $ ./mvnw clean package ``` これをGreenとして別のアプリ名でデプロイします。 ``` bash $ cf push hello-pws2 -p target/hello-pws.jar -m 256M ``` 再度`cf routes`コマンドでルーティング情報を確認しましょう。 ``` bash $ cf routes Getting routes as メールアドレス ... space host domain apps development hello-pws cfapps.io hello-pws development hello-pws2 cfapps.io hello-pws2 ``` ちなみにアプリ名とホスト名を別にしたい場合は`-n`オプションで指定できます。 ``` bash $ curl http://hello-pws2.cfapps.io Hello v2 from 10.10.115.76:62708 ``` Green環境にアクセスして問題ないことを確認したので、`hello-pws2`アプリを`hello-pws`へのアクセスでルーティングされるようにマッピングします。 ``` bash $ cf map-route hello-pws2 cfapps.io -n hello-pws Creating route hello-pws.cfapps.io for org maki-org / space development as メールアドレス... OK Route hello-pws.cfapps.io already exists Adding route hello-pws.cfapps.io to app hello-pws2 in org maki-org / space development as メールアドレス... OK ``` `cf routes`で確認すると ``` bash $ cf routes Getting routes as メールアドレス ... space host domain apps development hello-pws cfapps.io hello-pws,hello-pws2 development hello-pws2 cfapps.io hello-pws2 ``` この時点で`hello-pws.cfapps.io`はBlueとGreenのどちらかにルーティングされます。 ``` bash $ curl http://hello-pws.cfapps.io Hello from 10.10.114.65:64587 $ curl http://hello-pws.cfapps.io Hello v2 from 10.10.115.76:62708 ``` 次にBlueへのルーティングを外します。 ``` bash $ cf unmap-route hello-pws cfapps.io -n hello-pws Removing route hello-pws.cfapps.io from app hello-pws in org maki-org / space development as メールアドレス... OK ``` 再度ルーティング情報を確認しましょう。 ``` bash $ cf routes Getting routes as メールアドレス ... space host domain apps development hello-pws cfapps.io hello-pws2 development hello-pws2 cfapps.io hello-pws2 ``` これで無事に`hello-pws`がバージョンアップされました。 `hello-pws2`からのルーティングは不要なのでアンマップしておきます。 ``` bash cf unmap-route hello-pws2 cfapps.io -n hello-pws2 ``` この段階で前バージョンのアプリへのルーティングは無くなりましたが、アプリ自体は存在しています。 ``` bash $ cf apps Getting apps in org maki-org / space development as メールアドレス... OK name requested state instances memory disk urls hello-pws started 1/1 256M 1G hello-pws2 started 1/1 256M 1G hello-pws.cfapps.io ``` 新バージョンに予期せぬ不具合が生じた場合に前バージョンを切り戻すということも簡単です。 前バージョンが不要になった場合は削除すれば良いです。 ``` bash $ cf delete hello-pws Really delete the app hello-pws?> y Deleting app hello-pws in org maki-org / space development as メールアドレス... OK ``` Cloud Foundryを使うとデプロイが本当に簡単になります。 ## データベースの利用 Cloud Foundryではデータベースはサービスとして用意されており、それをアプリにバインドする形でアクセスできます。 Cloud FoundryではMarketplaceという形でサービスが公開されています。`cf marketplace`コマンドで一覧表示できます。 ``` bash $ cf marketplace Getting services from marketplace in org maki-org / space development as メールアドレス... OK service plans description 3scale free_appdirect, basic_appdirect*, pro_appdirect* API Management Platform app-autoscaler bronze, gold Scales bound applications in response to load (beta) blazemeter free-tier, basic1kmr*, pro5kmr* Performance Testing Platform cedexisopenmix opx_global*, openmix-gslb-with-fusion-feeds* Openmix Global Cloud & Data Center Load Balancer cedexisradar free-community-edition Free Website& Mobile App Performance Reports cleardb spark, boost*, amp*, shock* Highly available MySQL for your Apps. cloudamqp lemur, tiger*, bunny*, rabbit*, panda* Managed HA RabbitMQ servers in the cloud cloudforge free, standard*, pro* Development Tools In The Cloud elephantsql turtle, panda*, hippo*, elephant* PostgreSQL as a Service flashreport trial, basic*, silver*, gold*, platinum* Generate PDF from your data ironworker production*, starter*, developer* Job Scheduling and Processing loadimpact lifree, li100*, li500*, li1000* Automated and on-demand performance testing memcachedcloud 100mb*, 250mb*, 500mb*, 1gb*, 2-5gb*, 5gb*, 30mb Enterprise-Class Memcached for Developers memcachier dev, 100*, 250*, 500*, 1000*, 2000*, 5000*, 7500*, 10000*, 20000*, 50000*, 100000* The easiest, most advanced memcache. mongolab sandbox Fully-managed MongoDB-as-a-Service newrelic standard Manage and monitor your apps pubnub free Build Realtime Apps that Scale rediscloud 100mb*, 250mb*, 500mb*, 1gb*, 2-5gb*, 5gb*, 10gb*, 50gb*, 30mb Enterprise-Class Redis for Developers searchify small*, plus*, pro* Custom search you control searchly small*, micro*, professional*, advanced*, starter, business*, enterprise* Search Made Simple. Powered-by Elasticsearch sendgrid free, bronze*, silver* Email Delivery. Simplified. stamplay plus*, premium*, core, starter* API-first development platform statica starter, spike*, micro*, medium*, large*, enterprise*, premium* Enterprise Static IP Addresses temporize small*, medium*, large* Simple and flexible job scheduling for your application * The denoted service plans have specific costs associated with them. If a service instance of this type is created, a cost will be incurred. TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service. ``` サービス名はCloud Foundryの運用元によって異なります。例えば、PWSではelephantsqlがPostgreSQLのサービスです。 ここではPostgreSQLを使いましょう。プランは次の通りで、無償のプランはturtleです。 ``` bash $ cf marketplace -s elephantsql Getting service plan information for service elephantsql as メールアドレス... OK service plan description free or paid turtle 4 concurrent connections, 20MB Storage free panda 20 concurrent connections, 2GB Storage paid hippo 300 concurrent connections, 100 GB Storage paid elephant 300 concurrent connections, 1000 GB Storage, 500Mbps paid ``` 使用するサービスを作成しましょう。 ``` bash $ cf create-service elephantsql turtle dev-pg Creating service instance dev-pg in org maki-org / space development as メールアドレス... OK ``` サービスはアプリとか異なり月額制です。アプリを作成すると即月額分課金されるのプランを間違えないように注意してください。 次にアプリにサービスをバインドします。 ``` bash $ cf bind-service hello-pws2 dev-pg Binding service dev-pg to app hello-pws2 in org maki-org / space development as メールアドレス... OK TIP: Use 'cf restage' to ensure your env variable changes take effect ``` 使用しているサービス一覧は`cf services`で確認できます。 ``` bash $ cf services Getting services in org maki-org / space development as メールアドレス... OK name service plan bound apps last operation dev-pg elephantsql turtle hello-pws2 create succeeded ``` アプリがサービスへアクセスするための elephantsqlの場合、環境変数`DATABASE_URL`に `postgres://ahjtcdvn:-2C8oL3NGvyIbcgB5OJEG4eayBD2bZqI@pellefant-01.db.elephantsql.com:5432/ahjtcdvn`というような文字列が設定されます。 アプリに環境変数を埋め込み直すには`cf restage`(コンテナの再作成)または`cf restart`(アプリのみ再起動)を実行する必要があります。 通常は`cf restart hello-pws2`で良いです。ダウンタイムが発生するので、ここではBlue/Greenデプロイメントのことは忘れています。 そろそろ疲れてきたので、アプリ側の設定は割愛しますが、環境変数の文字列を元に`DataSource`Beanを作成することになります。 [Herokuのドキュメント](https://devcenter.heroku.com/articles/heroku-postgresql#spring-java)を参照してください。 特にSpring Bootアプリの場合はCloud Foundryにデプロイすると自動で`cloud`プロファイルが有効になるので、Cloud Foundry上でのみ有効にしたい設定は`@Profile("cloud")`を指定するか、`application-cloud.properties`に定義しておくと良いでしょう。 ## Java EE 7アプリをデプロイしよう 最後にJava EEアドベントカレンダーなので、Java EEアプリもデプロイしちゃいます。 Cloud Foundryのアプリはbuildpackでビルドされるといいました。登録されているbuildpackは`cf buildpacks`で確認できます。 ``` bash $ cf buildpacks Getting buildpacks... buildpack position enabled locked filename staticfile_buildpack 1 true false staticfile_buildpack-cached-v1.2.2.zip java_buildpack 2 true false java-buildpack-v3.3.1.zip ruby_buildpack 3 true false ruby_buildpack-cached-v1.6.8.zip nodejs_buildpack 4 true false nodejs_buildpack-cached-v1.5.2.zip go_buildpack 5 true false go_buildpack-cached-v1.6.3.zip python_buildpack 6 true false python_buildpack-cached-v1.5.1.zip php_buildpack 7 true false php_buildpack-cached-v4.2.1.zip liberty_buildpack 8 true false liberty_buildpack.zip binary_buildpack 9 true false binary_buildpack-cached-v1.0.1.zip ``` PWSではWebSphere Liberty Profileのbuildpackが初めから組み込まれているので、 Java EE 7のアプリを簡単にデプロイできます。詳しくは[こちら](https://www.ng.bluemix.net/docs/#starters/liberty/index.html#liberty)をご確認ください。 Spring Bootとほぼ同じJAX-RS版アプリをGitHubに[プッシュ](https://github.com/making/hello-pws-javaee)したのでcloneしてビルドしてください。 ``` bash $ git clone https://github.com/making/hello-pws-javaee $ cd hello-pws-javaee $ mvn package ``` これをPWSにデプロイします。本来は`server.xml`というLibety Profileの設定ファイルを用意するとLibety Profile用のビルドパックが自動で選択されるのですが、今回はそれを作らず明示的にビルドパックを指定します。 ``` $ cf push hello-pws-javaee -p target/hello-pws-javaee-1.0-SNAPSHOT -m 256M -b https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack.git --no-start ``` ここでは`--no-start`をつけてアプリケーションが起動しないようにしておきます。 Liberty Profileを使う場合はIBM JVMのライセンスコードとLiberty Profileのライセンスコードを環境変数で渡す必要があり、アプリケーション起動の前に環境変数を設定する必要があるからです。 [IBM Liberty-License](http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/wlp/8.5.5.7/lafiles/runtime/en.html)を読んで`D/N: <ライセンス番号>`を探してください。見つけたら ``` bash $ cf set-env hello-pws-javaee IBM_LIBERTY_LICENSE <ライセンス番号> ``` を実行してください。 同様に[IBM JVM-License](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=&li_formnum=L-JWOD-9SYNCP&title=IBM%C2%AE+SDK%2C+Java+Technology+Edition%2C+Version+8.0&l=en)を読んで`D/N: <ライセンス番号>`を探してください。見つけたら ``` bash $ cf set-env hello-pws-javaee IBM_JVM_LICENSE <ライセンス番号> ``` を実行してください。 環境変数の設定が完了したら、`cf start`で起動します。 ``` bash $ cf start hello-pws-javaee Starting app hello-pws-javaee in org maki-org / space development as メールアドレス... Creating container Successfully created container Downloading app package... Downloaded app package (2K) Downloaded buildpacks Staging... -----> Liberty Buildpack Version: f489cee | https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack.git#f489cee -----> Avoid Trouble: Specify a minimum of 512M as the Memory Limit for your apps when using IBM JDK. -----> Downloading IBM 1.8.0_sr1fp10 JRE from https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/jre/1.8.0/linux/ibm-java-jre-8.0-1.10-x86_64-archive.bin ... (11.3s) Expanding JRE to .java ... (20.3s) -----> Downloading from https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/wlp/8.5.5.7/wlp-webProfile7-8.5.5.7.zip ... (7.0s) Installing archive ... (0.7s) -----> Warning: Liberty feature set is not specified. Using the default feature set: ["beanValidation-1.1", "cdi-1.2", "ejbLite-3.2", "el-3.0", "jaxrs-2.0", "jdbc-4.1", "jndi-1.0", "jpa-2.1", "jsf-2.2", "jsonp-1.0", "jsp-2.3", "managedBeans-1.0", "servlet-3.1", "websocket-1.1"]. For the best results, explicitly set the features via the JBP_CONFIG_LIBERTY environment variable or deploy the application as a server directory or packaged server with a custom server.xml file. -----> Liberty buildpack is done creating the droplet Exit status 0 Staging complete Uploading droplet, build artifacts cache... Uploading build artifacts cache... Uploading droplet... Uploaded build artifacts cache (172.2M) Uploaded droplet (167.5M) Uploading complete 0 of 1 instances running, 1 starting 0 of 1 instances running, 1 starting 0 of 1 instances running, 1 starting 1 of 1 instances running App started OK App hello-pws-javaee was started using this command `.liberty/create_vars.rb wlp/usr/servers/defaultServer/runtime-vars.xml && WLP_SKIP_MAXPERMSIZE=true JAVA_HOME="$PWD/.java" WLP_USER_DIR="$PWD/wlp/usr" .liberty/bin/server run defaultServer` Showing health and status for app hello-pws-javaee in org maki-org / space development as メールアドレス... OK requested state: started instances: 1/1 usage: 256M x 1 instances urls: hello-pws-javaee.cfapps.io package uploaded: Sat Dec 5 09:54:17 UTC 2015 stack: cflinuxfs2 buildpack: https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack.git state since cpu memory disk details #0 running 2015-12-05 06:57:24 PM 0.0% 688K of 256M 27.8M of 1G ``` アクセスしてみましょう。 ``` bash $ curl http://hello-pws-javaee.cfapps.io/app/hello Hello from 10.10.115.89:64684 ``` できました。スケールアウトも同様。 ``` bash $ cf scale hello-pws-javaee -i 4 Scaling app hello-pws-javaee in org maki-org / space development as メールアドレス... OK $ for i in `seq 1 20`; do curl http://hello-pws-javaee.cfapps.io/app/hello; echo; done Hello from 10.10.114.39:64622 Hello from 10.10.115.89:64684 Hello from 10.10.115.65:60483 Hello from 10.10.115.65:60483 Hello from 10.10.115.89:64684 Hello from 10.10.115.89:64684 Hello from 10.10.115.65:60483 Hello from 10.10.115.65:60483 Hello from 10.10.114.75:60232 Hello from 10.10.114.75:60232 Hello from 10.10.115.89:64684 Hello from 10.10.115.65:60483 Hello from 10.10.114.75:60232 Hello from 10.10.114.39:64622 Hello from 10.10.114.75:60232 Hello from 10.10.115.89:64684 Hello from 10.10.115.89:64684 Hello from 10.10.115.89:64684 Hello from 10.10.115.65:60483 Hello from 10.10.114.75:60232 ``` できました。 ---- 本記事でCloud FoundryのPaaSプラットホームとしての素晴らしさを少し体験できたかと思います。本記事の内容は基本的にはPWS以外でも利用できます。[IBM Bluemix](https://console.ng.bluemix.net/home/)も無料期間があるので、是非にアプリをデプロイしてみてください。