Cloud Foundryハンズオン - 1. 簡単なアプリケーションをデプロイ (Java編)

Spring Bootを使ってとても簡単なWebアプリケーションを作成 & デプロイしましょう。

目次

プロジェクトの作成

以下のコマンドを実行すると、hello-cfフォルダに雛形プロジェクトが生成されます。

$ curl https://start.spring.io/starter.tgz \
       -d artifactId=hello-cf \
       -d baseDir=hello-cf \
       -d dependencies=web,actuator \
       -d packageName=com.example \
       -d applicationName=HelloCfApplication | tar -xzvf -

Spring Boot 2.1.7で動作確認しています。 また、Pivotal Application Service(Cloud Foundry)は次のバージョンで動作確認しています。

$ cf curl /v2/info
{
   "name": "Pivotal Application Service",
   "build": "2.7.0-build.192",
   "support": "https://support.pivotal.io",
   "version": 0,
   "description": "https://docs.pivotal.io/pivotalcf/2-7/pcf-release-notes/runtime-rn.html",
   "authorization_endpoint": "https://login.sys.pivotal.bosh.tokyo",
   "token_endpoint": "https://uaa.sys.pivotal.bosh.tokyo",
   "min_cli_version": "6.23.0",
   "min_recommended_cli_version": "6.23.0",
   "app_ssh_endpoint": "ssh.sys.pivotal.bosh.tokyo:2222",
   "app_ssh_host_key_fingerprint": "fb:c2:0c:69:aa:dd:98:52:73:f0:72:d8:ae:4d:7f:23",
   "app_ssh_oauth_client": "ssh-proxy",
   "doppler_logging_endpoint": "wss://doppler.sys.pivotal.bosh.tokyo:443",
   "api_version": "2.139.0",
   "osbapi_version": "2.15",
   "routing_endpoint": "https://api.sys.pivotal.bosh.tokyo/routing",
   "user": "5f2b4ad2-73fe-4078-83f4-6db19575614c"
}

cf CLIのバージョンは次の通りです。

$ cf version
cf バージョン 6.44.1+c3b20bfbe.2019-05-08

生成されたプロジェクトのソースを少しだけ修正します。任意のエディタ、IDEで hello-cf/src/main/java/com/example/HelloCfApplication.javaを開いてください。

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// ここから追加
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
// ここまで

@SpringBootApplication
@RestController // 追加
public class HelloCfApplication {

        // ここから追加
        @GetMapping("/") 
        public String hello() {
                return "Hello World!";
        }
        // ここまで

        public static void main(String[] args) {
                SpringApplication.run(HelloCfApplication.class, args);
        }
}

ソースコードを修正したら、アプリケーションをビルドします。

cd hello-cf
./mvnw package -DskipTests=true

HTTP Proxyがある場合、.mvn/jvm.configに次の設定を行ってください

-Dhttp.proxyHost=proxy.example.com 
-Dhttp.proxyPort=8080
-Dhttps.proxyHost=proxy.example.com 
-Dhttps.proxyPort=8080 
-Dhttp.proxyUser=username 
-Dhttp.proxyPassword=password

まずはローカルでアプリケーションを実行してみましょう。

$ java -jar target/hello-cf-0.0.1-SNAPSHOT.jar
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.7.RELEASE)

2019-08-19 23:05:26.289  INFO 71735 --- [           main] com.example.HelloCfApplication           : Starting HelloCfApplication v0.0.1-SNAPSHOT on makinoMacBook-puro.local with PID 71735 (/private/tmp/hello-cf/target/hello-cf-0.0.1-SNAPSHOT.jar started by maki in /private/tmp/hello-cf)
2019-08-19 23:05:26.292  INFO 71735 --- [           main] com.example.HelloCfApplication           : No active profile set, falling back to default profiles: default
2019-08-19 23:05:27.514  INFO 71735 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-08-19 23:05:27.546  INFO 71735 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-08-19 23:05:27.546  INFO 71735 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.22]
2019-08-19 23:05:27.649  INFO 71735 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-08-19 23:05:27.649  INFO 71735 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1310 ms
2019-08-19 23:05:28.359  INFO 71735 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-08-19 23:05:28.660  INFO 71735 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-08-19 23:05:28.760  INFO 71735 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-08-19 23:05:28.764  INFO 71735 --- [           main] com.example.HelloCfApplication           : Started HelloCfApplication in 3.038 seconds (JVM running for 3.423)
2019-08-19 23:05:29.162  INFO 71735 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-08-19 23:05:29.163  INFO 71735 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-08-19 23:05:29.168  INFO 71735 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms

http://localhost:8080にアクセスしてください。

image

Hello World!が表示されれば成功です。

アプリケーションをCloud FoundryにPush

ビルドしたアプリケーションをCloud FoundryにPushしましょう。 cfコマンドを使えばとても簡単です。以下のコマンドを実行してください。

cf push hello-<your name> -p target/hello-cf-0.0.1-SNAPSHOT.jar

<your name>は自分の名前などを置換して、一意にしてください。以下では<your name>tmakiとします。適宜自分の名前に読み替えてください。

$ cf push hello-tmaki -p target/hello-cf-0.0.1-SNAPSHOT.jar
admin としてアプリ hello-tmaki を組織 demo / スペース develop にプッシュしています...
アプリ情報を取得しています...
これらの属性でアプリを作成しています...
+ 名前:       hello-tmaki
  パス:       /private/tmp/hello-cf/target/hello-cf-0.0.1-SNAPSHOT.jar
  経路:
+   hello-tmaki.apps.pivotal.bosh.tokyo

アプリ hello-tmaki を作成しています...
経路をマップしています...
ローカル・ファイルをリモート・キャッシュと比較しています...
Packaging files to upload...
ファイルをアップロードしています...
 15.57 MiB / 15.57 MiB [===========================================================================================================================================================] 100.00% 26s

API がファイルの処理を完了するのを待機しています...

アプリをステージングし、ログをトレースしています...
   Downloading binary_buildpack...
   Downloading r_buildpack...
   Downloading staticfile_buildpack...
   Downloading ruby_buildpack...
   Downloading java_buildpack_offline...
   Downloaded binary_buildpack
   Downloading python_buildpack...
   Downloaded staticfile_buildpack
   Downloading php_buildpack...
   Downloaded r_buildpack
   Downloaded ruby_buildpack
   Downloading dotnet_core_buildpack...
   Downloading nodejs_buildpack...
   Downloaded java_buildpack_offline
   Downloading nginx_buildpack...
   Downloaded python_buildpack
   Downloading go_buildpack...
   Downloaded php_buildpack
   Downloaded nodejs_buildpack
   Downloaded dotnet_core_buildpack
   Downloaded go_buildpack
   Downloaded nginx_buildpack
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b creating container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b successfully created container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   Downloading app package...
   Downloaded app package (15.6M)
   -----> Java Buildpack v4.20 (offline) | https://github.com/cloudfoundry/java-buildpack.git#2cd7e3e
   -----> Downloading Jvmkill Agent 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/jvmkill-1.16.0-RELEASE.so (found in cache)
   -----> Downloading Open Jdk JRE 1.8.0_222 from https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/openjdk-jre-1.8.0_222-bionic.tar.gz (found in cache)
          Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s)
          JVM DNS caching disabled in lieu of BOSH DNS caching
   -----> Downloading Open JDK Like Memory Calculator 3.13.0_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/bionic/x86_64/memory-calculator-3.13.0-RELEASE.tar.gz (found in cache)
          Loaded Classes: 12105, Threads: 250
   -----> Downloading Client Certificate Mapper 1.8.0_RELEASE from https://java-buildpack.cloudfoundry.org/client-certificate-mapper/client-certificate-mapper-1.8.0-RELEASE.jar (found in cache)
   -----> Downloading Container Security Provider 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-security-provider/container-security-provider-1.16.0-RELEASE.jar (found in cache)
   -----> Downloading Spring Auto Reconfiguration 2.7.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-2.7.0-RELEASE.jar (found in cache)
   Exit status 0
   Uploading droplet, build artifacts cache...
   Uploading droplet...
   Uploading build artifacts cache...
   Uploaded build artifacts cache (129B)
   Uploaded droplet (59.1M)
   Uploading complete
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b stopping instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b destroying container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b successfully destroyed container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660

アプリが開始するのを待機しています...

名前:                   hello-tmaki
要求された状態:         started
経路:                   hello-tmaki.apps.pivotal.bosh.tokyo
最終アップロード日時:   Mon 19 Aug 23:04:03 JST 2019
スタック:               cflinuxfs3
ビルドパック:           client-certificate-mapper=1.8.0_RELEASE container-security-provider=1.16.0_RELEASE
                        java-buildpack=v4.20-offline-https://github.com/cloudfoundry/java-buildpack.git#2cd7e3e java-main java-opts java-security jvmkill-agent=1.16.0_RELEASE
                        open-jdk-...

タイプ:           web
インスタンス:     1/1
メモリー使用量:   1024M
開始コマンド:     JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=$TMPDIR -XX:ActiveProcessorCount=$(nproc)
                  -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext
                  -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security $JAVA_OPTS" &&
                  CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE -totMemory=$MEMORY_LIMIT -loadedClasses=13405 -poolType=metaspace
                  -stackThreads=250 -vmOptions="$JAVA_OPTS") && echo JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2
                  SERVER_PORT=$PORT eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher
     状態   開始日時               cpu    メモリー      ディスク      詳細
#0   実行   2019-08-19T14:04:18Z   0.0%   1G の中の 0   1G の中の 0 

これでデプロイに成功しました。 cf appsでデプロイされているアプリケーションの一覧を取得できます。

$ cf apps
admin として組織 demo / スペース develop 内のアプリを取得しています...
OK

名前          要求された状態   インスタンス   メモリー   ディスク   URL
hello-tmaki   started          1/1            1G         1G         hello-tmaki.apps.pivotal.bosh.tokyo

urlsの列に出力されている値がアプリケーションのURLです。この場合はhttps://hello-tmaki.apps.pivotal.bosh.tokyoです。

image

Cloud Foundry上にデプロイされたアプリケーションにもアクセスできました。

cf set-env hello-tmaki MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE info,health,env
cf restart hello-tmaki

https://hello-tmaki.apps.pivotal.bosh.tokyo/actuator/envにアクセスすると環境変数やプロパティを確認できます。

image

Apps Manager(アプリケーションの管理画面)を見てみましょう。

image

「Space development」をクリックしてください。developmentというスペースにデプロイされているアプリケーションの一覧を確認できます。hello-<your name>が表示されています。

image

hello-<your name>をクリックしてください。

image

アプリケーションの情報が確認できます。

直近のログはcf logs <App> --recentで確認できます。

$ cf logs hello-tmaki --recent
admin として組織 demo / スペース develop 内のアプリ hello-tmaki のログを取得しています...

   2019-08-19T23:03:14.45+0900 [API/0] OUT Created app with guid df48cd5d-a895-4cf0-b8b5-476bb94e3835
   2019-08-19T23:03:41.97+0900 [API/0] OUT Uploading bits for app with guid df48cd5d-a895-4cf0-b8b5-476bb94e3835
   2019-08-19T23:03:46.05+0900 [API/0] OUT Creating build for app with guid df48cd5d-a895-4cf0-b8b5-476bb94e3835
   2019-08-19T23:03:46.33+0900 [API/0] OUT Updated app with guid df48cd5d-a895-4cf0-b8b5-476bb94e3835 ({"state"=>"STARTED"})
   2019-08-19T23:03:46.34+0900 [STG/0] OUT Downloading binary_buildpack...
   2019-08-19T23:03:46.34+0900 [STG/0] OUT Downloading r_buildpack...
   2019-08-19T23:03:46.34+0900 [STG/0] OUT Downloading staticfile_buildpack...
   2019-08-19T23:03:46.34+0900 [STG/0] OUT Downloading ruby_buildpack...
   2019-08-19T23:03:46.35+0900 [STG/0] OUT Downloading java_buildpack_offline...
   2019-08-19T23:03:46.35+0900 [STG/0] OUT Downloaded binary_buildpack
   2019-08-19T23:03:46.35+0900 [STG/0] OUT Downloading python_buildpack...
   2019-08-19T23:03:46.35+0900 [STG/0] OUT Downloaded staticfile_buildpack
   2019-08-19T23:03:46.35+0900 [STG/0] OUT Downloading php_buildpack...
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloaded r_buildpack
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloaded ruby_buildpack
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloading dotnet_core_buildpack...
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloading nodejs_buildpack...
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloaded java_buildpack_offline
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloading nginx_buildpack...
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloaded python_buildpack
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloading go_buildpack...
   2019-08-19T23:03:46.36+0900 [STG/0] OUT Downloaded php_buildpack
   2019-08-19T23:03:46.37+0900 [STG/0] OUT Downloaded nodejs_buildpack
   2019-08-19T23:03:46.37+0900 [STG/0] OUT Downloaded dotnet_core_buildpack
   2019-08-19T23:03:46.37+0900 [STG/0] OUT Downloaded go_buildpack
   2019-08-19T23:03:46.37+0900 [STG/0] OUT Downloaded nginx_buildpack
   2019-08-19T23:03:46.37+0900 [STG/0] OUT Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b creating container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   2019-08-19T23:03:47.01+0900 [STG/0] OUT Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b successfully created container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   2019-08-19T23:03:47.50+0900 [STG/0] OUT Downloading app package...
   2019-08-19T23:03:48.52+0900 [STG/0] OUT Downloaded app package (15.6M)
   2019-08-19T23:03:50.93+0900 [STG/0] OUT -----> Java Buildpack v4.20 (offline) | https://github.com/cloudfoundry/java-buildpack.git#2cd7e3e
   2019-08-19T23:03:51.02+0900 [STG/0] OUT -----> Downloading Jvmkill Agent 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/jvmkill-1.16.0-RELEASE.so (found in cache)
   2019-08-19T23:03:51.02+0900 [STG/0] OUT -----> Downloading Open Jdk JRE 1.8.0_222 from https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/openjdk-jre-1.8.0_222-bionic.tar.gz (found in cache)
   2019-08-19T23:03:52.18+0900 [STG/0] OUT        Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s)
   2019-08-19T23:03:52.18+0900 [STG/0] OUT        JVM DNS caching disabled in lieu of BOSH DNS caching
   2019-08-19T23:03:52.18+0900 [STG/0] OUT -----> Downloading Open JDK Like Memory Calculator 3.13.0_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/bionic/x86_64/memory-calculator-3.13.0-RELEASE.tar.gz (found in cache)
   2019-08-19T23:03:52.86+0900 [STG/0] OUT        Loaded Classes: 12105, Threads: 250
   2019-08-19T23:03:52.88+0900 [STG/0] OUT -----> Downloading Client Certificate Mapper 1.8.0_RELEASE from https://java-buildpack.cloudfoundry.org/client-certificate-mapper/client-certificate-mapper-1.8.0-RELEASE.jar (found in cache)
   2019-08-19T23:03:52.88+0900 [STG/0] OUT -----> Downloading Container Security Provider 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-security-provider/container-security-provider-1.16.0-RELEASE.jar (found in cache)
   2019-08-19T23:03:52.88+0900 [STG/0] OUT -----> Downloading Spring Auto Reconfiguration 2.7.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-2.7.0-RELEASE.jar (found in cache)
   2019-08-19T23:04:02.40+0900 [STG/0] OUT Exit status 0
   2019-08-19T23:04:02.40+0900 [STG/0] OUT Uploading droplet, build artifacts cache...
   2019-08-19T23:04:02.40+0900 [STG/0] OUT Uploading droplet...
   2019-08-19T23:04:02.40+0900 [STG/0] OUT Uploading build artifacts cache...
   2019-08-19T23:04:02.49+0900 [STG/0] OUT Uploaded build artifacts cache (129B)
   2019-08-19T23:04:03.46+0900 [API/0] OUT Creating droplet for app with guid df48cd5d-a895-4cf0-b8b5-476bb94e3835
   2019-08-19T23:04:05.64+0900 [STG/0] OUT Uploaded droplet (59.1M)
   2019-08-19T23:04:05.65+0900 [STG/0] OUT Uploading complete
   2019-08-19T23:04:06.20+0900 [STG/0] OUT Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b stopping instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   2019-08-19T23:04:06.20+0900 [STG/0] OUT Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b destroying container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   2019-08-19T23:04:06.49+0900 [CELL/0] OUT Cell 9e8357a5-eded-44da-94a7-26ab24e2e5f7 creating container for instance a8c14db3-b6e4-4f39-779b-da70
   2019-08-19T23:04:06.72+0900 [STG/0] OUT Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b successfully destroyed container for instance bf2b6d55-415e-4445-9f4f-d35acfc68660
   2019-08-19T23:04:07.92+0900 [CELL/0] OUT Cell 9e8357a5-eded-44da-94a7-26ab24e2e5f7 successfully created container for instance a8c14db3-b6e4-4f39-779b-da70
   2019-08-19T23:04:08.15+0900 [CELL/0] OUT Downloading droplet...
   2019-08-19T23:04:10.53+0900 [CELL/0] OUT Downloaded droplet (59.1M)
   2019-08-19T23:04:10.83+0900 [CELL/0] OUT Starting health monitoring of container
   2019-08-19T23:04:11.54+0900 [APP/PROC/WEB/0] OUT JVM Memory Configuration: -Xmx446977K -Xss1M -XX:ReservedCodeCacheSize=240M -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=89598K
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT   .   ____          _            __ _ _
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT   '  |____| .__|_| |_|_| |_\__, | / / / /
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT  =========|_|==============|___/=/_/_/_/
   2019-08-19T23:04:13.14+0900 [APP/PROC/WEB/0] OUT  :: Spring Boot ::        (v2.1.7.RELEASE)
   2019-08-19T23:04:13.49+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:13.490  INFO 27 --- [           main] pertySourceApplicationContextInitializer : 'cloud' property source added
   2019-08-19T23:04:13.51+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:13.509  INFO 27 --- [           main] nfigurationApplicationContextInitializer : Reconfiguration enabled
   2019-08-19T23:04:13.53+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:13.528  INFO 27 --- [           main] com.example.HelloCfApplication           : Starting HelloCfApplication on a8c14db3-b6e4-4f39-779b-da70 with PID 27 (/home/vcap/app/BOOT-INF/classes started by vcap in /home/vcap/app)
   2019-08-19T23:04:13.53+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:13.528  INFO 27 --- [           main] com.example.HelloCfApplication           : The following profiles are active: cloud
   2019-08-19T23:04:15.46+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:15.467  INFO 27 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
   2019-08-19T23:04:15.52+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:15.525  INFO 27 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
   2019-08-19T23:04:15.52+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:15.525  INFO 27 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.22]
   2019-08-19T23:04:15.66+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:15.659  INFO 27 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
   2019-08-19T23:04:15.66+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:15.660  INFO 27 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2035 ms
   2019-08-19T23:04:16.34+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:16.340  INFO 27 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
   2019-08-19T23:04:16.73+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:16.731  INFO 27 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
   2019-08-19T23:04:16.81+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:16.815  INFO 27 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
   2019-08-19T23:04:16.82+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:04:16.820  INFO 27 --- [           main] com.example.HelloCfApplication           : Started HelloCfApplication in 4.374 seconds (JVM running for 5.275)
   2019-08-19T23:04:17.67+0900 [CELL/0] OUT Container became healthy
   2019-08-19T23:06:44.40+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:06:44.400  INFO 27 --- [nio-8080-exec-7] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
   2019-08-19T23:06:44.40+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:06:44.401  INFO 27 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
   2019-08-19T23:06:44.40+0900 [APP/PROC/WEB/0] OUT 2019-08-19 14:06:44.409  INFO 27 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
...

またcf logs <App>で今後流れるログを確認することができます(tail -f相当)。

アプリケーションの削除

cf deleteでアプリケーションを削除できます。

$ cf delete hello-tmaki

アプリ hello-tmaki を削除しますか?> y
admin として組織 demo / スペース develop 内のアプリ hello-tmaki を削除しています...
OK

Note cf delete-rオプションをつけると、ルーティング情報も合わせて削除されます。-fオプションをつけると、確認を聞かれません。

--random-routeを使う

このセクションはスキップして良いです。

先ほどはアプリケーション名に-<your name>をつけ一意にしました。helloだと重複する可能性が高いためです。実はアプリケーション名自体はスペース内で一意であればよく、一意にすべきはホスト名(xxxx.cfapps.ioxxxxの部分)です。これは-nまたは--hostnameで指定できます。 一意なホスト名にするには--random-routeを追加すれば良いです。

$ cf push hello -p target/hello-cf-0.0.1-SNAPSHOT.jar --random-route

cf appsを確認すると、ホスト名がhello-sleepy-warthogになっていることがわかります。

$ cf apps
admin として組織 demo / スペース develop 内のアプリを取得しています...
OK

名前    要求された状態   インスタンス   メモリー   ディスク   URL
hello   started          1/1            1G         1G         hello-sleepy-warthog.apps.pivotal.bosh.tokyo

この場合、https://hello-sleepy-warthog.apps.pivotal.bosh.tokyoにアクセスできます。

Buildpackを指定する

cf pushでアプリケーションをアップロードした後、ステージングとよばれるフェーズでランタイム(JREやサーバーなど)を追加し実行可能なDropletという形式(コンテナイメージ)を作成します。Dropletを作るためのBuildpackとよばれる仕組みが使われます。

アップロードしたファイル群(アーティファクト)から自動で適用すべきBuildpackが判断され、Cloud Foundryに他言語対応はここで行われています。

利用可能なBuildpack一覧はcf buildpacksで取得できます。

$ cf buildpacks
ビルドパックを取得しています...

buildpack                位置   有効   ロック済み   ファイル名                                            stack
staticfile_buildpack     1      true   false        staticfile_buildpack-cached-cflinuxfs3-v1.4.43.zip    cflinuxfs3
java_buildpack_offline   2      true   false        java-buildpack-offline-cflinuxfs3-v4.20.zip           cflinuxfs3
ruby_buildpack           3      true   false        ruby_buildpack-cached-cflinuxfs3-v1.7.42.zip          cflinuxfs3
nginx_buildpack          4      true   false        nginx_buildpack-cached-cflinuxfs3-v1.0.15.zip         cflinuxfs3
nodejs_buildpack         5      true   false        nodejs_buildpack-cached-cflinuxfs3-v1.6.52.zip        cflinuxfs3
go_buildpack             6      true   false        go_buildpack-cached-cflinuxfs3-v1.8.42.zip            cflinuxfs3
r_buildpack              7      true   false        r_buildpack-cached-cflinuxfs3-v1.0.11.zip             cflinuxfs3
python_buildpack         8      true   false        python_buildpack-cached-cflinuxfs3-v1.6.36.zip        cflinuxfs3
php_buildpack            9      true   false        php_buildpack-cached-cflinuxfs3-v4.3.78.zip           cflinuxfs3
dotnet_core_buildpack    10     true   false        dotnet-core_buildpack-cached-cflinuxfs3-v2.2.12.zip   cflinuxfs3
binary_buildpack         11     true   false        binary_buildpack-cached-cflinuxfs3-v1.0.33.zip        cflinuxfs3
binary_buildpack         12     true   false        binary_buildpack-cached-windows2012R2-v1.0.33.zip     windows2012R2
binary_buildpack         13     true   false        binary_buildpack-cached-windows2016-v1.0.33.zip       windows2016
binary_buildpack         14     true   false        binary_buildpack-cached-windows-v1.0.33.zip           windows

デフォルトでは、cf pushでアーティファクトをアップロードした後、利用可能なBuildpackを全てダウンロードし、優先順(position順)にチェックし、対象のBuildpackを特定しDroplet(実行可能な形式)を作成します。

今回の場合は、jarファイルからjava_buildpack_offline(PWSの場合はjava_buildpack)が検知され、かつjarの内部にlib/spring-boot-.*.jarが存在することからSpring Boot用のDropletが作成されます。

Buildpackは-bで明示的に指定できます。明示することで自動検出のための時間を短縮できます。

$ cf push hello-tmaki -p target/hello-cf-0.0.1-SNAPSHOT.jar -b java_buildpack_offline
admin としてアプリ hello-tmaki を組織 demo / スペース develop にプッシュしています...
アプリ情報を取得しています...
これらの属性でアプリを作成しています...
+ 名前:           hello-tmaki
  パス:           /private/tmp/hello-cf/target/hello-cf-0.0.1-SNAPSHOT.jar
  ビルドパック:
+   java_buildpack_offline
  経路:
+   hello-tmaki.apps.pivotal.bosh.tokyo

アプリ hello-tmaki を作成しています...
経路をマップしています...
ローカル・ファイルをリモート・キャッシュと比較しています...
Packaging files to upload...
ファイルをアップロードしています...
 253.90 KiB / 253.90 KiB [==========================================================================================================================================================] 100.00% 1s

API がファイルの処理を完了するのを待機しています...

アプリをステージングし、ログをトレースしています...
   Downloading java_buildpack_offline...
   Downloaded java_buildpack_offline
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b creating container for instance 3fa95a53-3eef-44f6-929c-700fe2fecae1
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b successfully created container for instance 3fa95a53-3eef-44f6-929c-700fe2fecae1
   Downloading app package...
   Downloaded app package (15.5M)
   -----> Java Buildpack v4.20 (offline) | https://github.com/cloudfoundry/java-buildpack.git#2cd7e3e
   -----> Downloading Jvmkill Agent 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/jvmkill-1.16.0-RELEASE.so (found in cache)
   -----> Downloading Open Jdk JRE 1.8.0_222 from https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/openjdk-jre-1.8.0_222-bionic.tar.gz (found in cache)
          Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s)
          JVM DNS caching disabled in lieu of BOSH DNS caching
   -----> Downloading Open JDK Like Memory Calculator 3.13.0_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/bionic/x86_64/memory-calculator-3.13.0-RELEASE.tar.gz (found in cache)
          Loaded Classes: 12105, Threads: 250
   -----> Downloading Client Certificate Mapper 1.8.0_RELEASE from https://java-buildpack.cloudfoundry.org/client-certificate-mapper/client-certificate-mapper-1.8.0-RELEASE.jar (found in cache)
   -----> Downloading Container Security Provider 1.16.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-security-provider/container-security-provider-1.16.0-RELEASE.jar (found in cache)
   -----> Downloading Spring Auto Reconfiguration 2.7.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-2.7.0-RELEASE.jar (found in cache)
   Exit status 0
   Uploading droplet, build artifacts cache...
   Uploading droplet...
   Uploading build artifacts cache...
   Uploaded build artifacts cache (129B)
   Uploaded droplet (59.1M)
   Uploading complete
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b stopping instance 3fa95a53-3eef-44f6-929c-700fe2fecae1
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b destroying container for instance 3fa95a53-3eef-44f6-929c-700fe2fecae1
   Cell 0aeb36f2-f081-4c64-8334-2627d2d82d4b successfully destroyed container for instance 3fa95a53-3eef-44f6-929c-700fe2fecae1

アプリが開始するのを待機しています...

名前:                   hello-tmaki
要求された状態:         started
経路:                   hello-tmaki.apps.pivotal.bosh.tokyo
最終アップロード日時:   Mon 19 Aug 23:26:15 JST 2019
スタック:               cflinuxfs3
ビルドパック:           java_buildpack_offline

タイプ:           web
インスタンス:     1/1
メモリー使用量:   1024M
開始コマンド:     JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.16.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=$TMPDIR -XX:ActiveProcessorCount=$(nproc)
                  -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext
                  -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security $JAVA_OPTS" &&
                  CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.13.0_RELEASE -totMemory=$MEMORY_LIMIT -loadedClasses=13405 -poolType=metaspace
                  -stackThreads=250 -vmOptions="$JAVA_OPTS") && echo JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2
                  SERVER_PORT=$PORT eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher
     状態   開始日時               cpu    メモリー      ディスク      詳細
#0   実行   2019-08-19T14:26:32Z   0.0%   1G の中の 0   1G の中の 0 

Manifestファイルを作成

ここまでcfコマンドで指定してきたオプションはmanifest.ymlというyamlファイルに定義できます。

  • cf push hello-tmaki -p target/hello-cf-0.0.1-SNAPSHOT.jar -b java_buildpack_offline
  • cf set-env hello-tmaki MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE info,health,env

manifest.ymlで表すと、

applications:
- name: hello-tmaki
  path: target/hello-cf-0.0.1-SNAPSHOT.jar
  buildpacks:
  - java_buildpack_offline
  # - java_buildpack (PWSの場合)
  env:
    MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: info,health,env

となります。

このManifestファイルがあれば実行コマンドはcf pushだけで良いです。

$ cf push
Using manifest file /Users/makit/git/hello-cf/manifest.yml
(以下、略)