Spring Bootアプリケーションのコンテナ化を試してみた

この記事は[ZOZO Advent Calendar 2021](https://qiita.com/advent-calendar/2021/zozo) #5 23日目の記事になります。

# はじめに
Spring Bootアプリケーションのコンテナ化をしてみました。

またSpring BootではSpring Boot2.3からCloud Native Buildpacksに対応しているため、
Dockerfileを使ったパターンとCloud Native Buildpacksの2パターンでコンテナ化を行ってみました。

# コンテナとは
仮想化技術の一つでアプリケーションの実行環境も含めてコンテナとすることで
環境に依存せずアプリケーションを実行することができる技術です。

# Dockerとは
コンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンプラットフォームです。

# Cloud Native Buildpacksとは
Cloud Native Buildpacksはアプリケーションのソースコードから任意のクラウドで実行できるイメージに変換してくれるツールになります。

# まずはアプリケーションの準備
今回はコンテナ化ができれば良いのでHello Worldを表示するだけの
簡単なWebアプリケーションを用意します。
####pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>spring-docker-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

```
#### HelloController.java

```java

package com.example.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

    @GetMapping("/")
    public String root() {
        return "hello/index";
    }
}
```
#### index.html
```html
Hello World
```
# Docker Desktopのインストール
こちらから入手しました。
https://www.docker.com/products/docker-desktop

# Dockerfileを使ったコンテナ化
まずDockerfileを使ったコンテナ化を行います。
####Dockerfile
```dockerfile
FROM maven:3.6.3-jdk-11 AS builder
WORKDIR /tmp
COPY ./src ./src
COPY ./pom.xml .
RUN mvn package
FROM adoptopenjdk/openjdk11:debianslim-jre
COPY --from=builder /tmp/target/app.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
```
使用しているコマンドの概要は以下になります。

|コマンド名       |内容 |
|:-----------------|-------------------|
| FROM             |コンテナのベースイメージ指定|
| WORKDIR          |作業ディレクトリの指定|
| COPY             |追加したいファイル、ディレクトリをイメージのファイルシステム上のパスに追加|
| RUN              |ビルド時に任意のコマンドを実行する|
| EXPOSE           |コンテナーの実行時に、所定ネットワーク上のどのポートをリッスンするかを指定 |
| ENTRYPOINT       |コンテナーを実行モジュールのようにして実行する設定を行う|
上記コマンドの詳細やその他コマンドを知りたい方は
[Dockerfile リファレンス](https://docs.docker.jp/engine/reference/builder.html)をご確認ください。

#### コンテナイメージのビルド
以下のコマンドでコンテナイメージをビルドします。

```
docker image build -t [Docker Hubのユーザー名（任意）]/[イメージ名（必須）]:[タグ（任意）] [Dockerfileパス]
```
実行してみます。

```
docker image build -t spring-docker-demo:0.0.1 ./

[+] Building 3.0s (13/13) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                                               0.1s
 => => transferring dockerfile: 32B                                                                                                                                                                                                0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                  0.1s
 => => transferring context: 2B                                                                                                                                                                                                    0.0s
 => [internal] load metadata for docker.io/adoptopenjdk/openjdk11:debianslim-jre                                                                                                                                                   2.6s
 => [internal] load metadata for docker.io/library/maven:3.6.3-jdk-11                                                                                                                                                              2.7s
 => [stage-1 1/2] FROM docker.io/adoptopenjdk/openjdk11:debianslim-jre@sha256:a24a26c8d0f780b25efe8d61593e51ac35a502565d5e4b12bcce43807fb43fb2                                                                                     0.0s
 => [internal] load build context                                                                                                                                                                                                  0.0s
 => => transferring context: 711B                                                                                                                                                                                                  0.0s
 => [builder 1/5] FROM docker.io/library/maven:3.6.3-jdk-11@sha256:1d29ccf46ef2a5e64f7de3d79a63f9bcffb4dc56be0ae3daed5ca5542b38aa2d                                                                                                0.0s
 => CACHED [builder 2/5] WORKDIR /tmp                                                                                                                                                                                              0.0s
 => CACHED [builder 3/5] COPY ./src ./src                                                                                                                                                                                          0.0s
 => CACHED [builder 4/5] COPY ./pom.xml .                                                                                                                                                                                          0.0s
 => CACHED [builder 5/5] RUN mvn package                                                                                                                                                                                           0.0s
 => CACHED [stage-1 2/2] COPY --from=builder /tmp/target/app.jar /app/app.jar                                                                                                                                                      0.0s
 => exporting to image                                                                                                                                                                                                             0.0s
 => => exporting layers                                                                                                                                                                                                            0.0s
 => => writing image sha256:1f356d2363a438bf1a2a5ebf980acae48dbdbc22d0c47007331ce3c32d0c404d                                                                                                                                       0.0s
 => => naming to docker.io/library/spring-docker-demo:0.0.1
```

コンテナイメージができたので以下のコマンドで確認してみます。

```
docker image ls

REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
spring-docker-demo   0.0.1     1f356d2363a4   48 minutes ago   251MB

```
確認できました。

#### 起動

以下のコマンドで起動します

```
docker run -it -p [ホスト側のポート番号]:[コンテナのポート番号] [イメージ名]:[タグ]
```


```
docker run -it -p 8080:8080 spring-docker-demo:0.0.1

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.1)

2021-12-23 00:39:47.873  INFO 1 --- [           main] com.example.Application                  : Starting Application v1.0-SNAPSHOT using Java 11.0.13 on a437d718d310 with PID 1 (/app/app.jar started by root in /)
2021-12-23 00:39:47.880  INFO 1 --- [           main] com.example.Application                  : No active profile set, falling back to default profiles: default
2021-12-23 00:39:49.961  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-12-23 00:39:49.985  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-12-23 00:39:49.985  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-12-23 00:39:50.088  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-12-23 00:39:50.088  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2029 ms
2021-12-23 00:39:50.444  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-12-23 00:39:50.867  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-12-23 00:39:50.900  INFO 1 --- [           main] com.example.Application                  : Started Application in 3.963 seconds (JVM running for 4.609)

```
runコマンドの詳細に関してはこちらの[リファレンス](https://docs.docker.jp/engine/reference/run.html)をご確認ください

起動が出来たらhttp://localhost:8080/ を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/ff129d79-b72d-ba90-0df7-611ebad50e40.png)
正常に実行できました。

# Cloud Native Buildpacksを使ったコンテナ化
次にCloud Native Buildpacksを使ったコンテナ化を行っていきます。

spring-boot-maven-pluginにはCloud Native Buildpacksとの連携機能が備わっているので、
以下のコマンドでコンテナイメージを作成できます。

```
mvn spring-boot:build-image -Dspring-boot.build-image.imageName=[イメージ名]:[タグ]
```

```
mvn spring-boot:build-image -Dspring-boot.build-image.imageName=spring-docker-cnb-demo:0.0.1


[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.example:spring-docker-demo >-------------------
[INFO] Building spring-docker-demo 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:2.4.1:build-image (default-cli) > package @ spring-docker-demo >>>
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ spring-docker-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] The encoding used to copy filtered properties files have not been set. This means that the same encoding will be used to copy filtered properties files as when copying other filtered resources. This might not be what you want! Run your build with --debug to see which files might be affected. Read more at https://maven.apache.org/plugins/maven-resources-plugin/examples/filtering-properties-files.html
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ spring-docker-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to C:\sources\spring-docker-demo\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ spring-docker-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] skip non existing resourceDirectory C:\sources\spring-docker-demo\src\test\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ spring-docker-demo ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ spring-docker-demo ---
[INFO] No tests to run.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ spring-docker-demo ---
[INFO] Building jar: C:\sources\spring-docker-demo\target\app.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.4.1:repackage (repackage) @ spring-docker-demo ---
[INFO] Replacing main artifact with repackaged archive
[INFO] 
[INFO] <<< spring-boot-maven-plugin:2.4.1:build-image (default-cli) < package @ spring-docker-demo <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.4.1:build-image (default-cli) @ spring-docker-demo ---
[INFO] Building image 'docker.io/library/spring-docker-cnb-demo:0.0.1'
[INFO] 
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 0%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 1%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 2%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 2%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 3%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 4%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 6%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 6%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 8%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 9%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 11%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 12%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 14%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 15%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 17%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 20%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 22%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 24%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 26%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 27%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 29%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 31%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 36%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 40%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 45%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 49%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 55%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 61%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 65%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 70%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 75%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 79%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 83%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 88%
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 100%
[INFO]  > Pulled builder image 'paketobuildpacks/builder@sha256:c212f4cde8f22e1517c4e919d64843c0d2287ad836b75449ae958f696183b458'
[INFO]  > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' 1%
[INFO]  > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' 47%
[INFO]  > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' 100%
[INFO]  > Pulled run image 'paketobuildpacks/run@sha256:50c74ebc95c169ea54ee4650d39d3c71d0fc738a3f0ad89b23d646cfd9ea36f2'
[INFO]  > Executing lifecycle version v0.13.2
[INFO]  > Using build cache volume 'pack-cache-c4b51991c14c.build'
[INFO] 
[INFO]  > Running creator
[INFO]     [creator]     ===> DETECTING
[INFO]     [creator]     6 of 19 buildpacks participating
[INFO]     [creator]     paketo-buildpacks/ca-certificates   3.0.1
[INFO]     [creator]     paketo-buildpacks/bellsoft-liberica 9.0.1
[INFO]     [creator]     paketo-buildpacks/syft              1.3.0
[INFO]     [creator]     paketo-buildpacks/executable-jar    6.0.1
[INFO]     [creator]     paketo-buildpacks/dist-zip          5.0.1
[INFO]     [creator]     paketo-buildpacks/spring-boot       5.2.0
[INFO]     [creator]     ===> ANALYZING
[INFO]     [creator]     Previous image with name "docker.io/library/spring-docker-cnb-demo:0.0.1" not found
[INFO]     [creator]     ===> RESTORING
[INFO]     [creator]     ===> BUILDING
[INFO]     [creator]     
[INFO]     [creator]     Paketo CA Certificates Buildpack 3.0.1
[INFO]     [creator]       https://github.com/paketo-buildpacks/ca-certificates
[INFO]     [creator]       Launch Helper: Contributing to layer
[INFO]     [creator]         Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper
[INFO]     [creator]     
[INFO]     [creator]     Paketo BellSoft Liberica Buildpack 9.0.1
[INFO]     [creator]       https://github.com/paketo-buildpacks/bellsoft-liberica
[INFO]     [creator]       Build Configuration:
[INFO]     [creator]         $BP_JVM_TYPE                 JRE             the JVM type - JDK or JRE
[INFO]     [creator]         $BP_JVM_VERSION              11.*            the Java version
[INFO]     [creator]       Launch Configuration:
[INFO]     [creator]         $BPL_DEBUG_ENABLED           false           enables Java remote debugging support
[INFO]     [creator]         $BPL_DEBUG_PORT              8000            configure the remote debugging port
[INFO]     [creator]         $BPL_DEBUG_SUSPEND           false           configure whether to suspend execution until a debugger has attached
[INFO]     [creator]         $BPL_HEAP_DUMP_PATH                          write heap dumps on error to this path
[INFO]     [creator]         $BPL_JAVA_NMT_ENABLED        true            enables Java Native Memory Tracking (NMT)
[INFO]     [creator]         $BPL_JAVA_NMT_LEVEL          summary         configure level of NMT, summary or detail
[INFO]     [creator]         $BPL_JFR_ARGS                                configure custom Java Flight Recording (JFR) arguments
[INFO]     [creator]         $BPL_JFR_ENABLED             false           enables Java Flight Recording (JFR)
[INFO]     [creator]         $BPL_JMX_ENABLED             false           enables Java Management Extensions (JMX)
[INFO]     [creator]         $BPL_JMX_PORT                5000            configure the JMX port
[INFO]     [creator]         $BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation
[INFO]     [creator]         $BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation
[INFO]     [creator]         $BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation
[INFO]     [creator]         $JAVA_TOOL_OPTIONS                           the JVM launch flags
[INFO]     [creator]       BellSoft Liberica JRE 11.0.13: Contributing to layer
[INFO]     [creator]         Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.13+8/bellsoft-jre11.0.13+8-linux-amd64.tar.gz
[INFO]     [creator]         Verifying checksum
[INFO]     [creator]         Expanding to /layers/paketo-buildpacks_bellsoft-liberica/jre
[INFO]     [creator]         Adding 128 container CA certificates to JVM truststore
[INFO]     [creator]         Writing env.launch/BPI_APPLICATION_PATH.default
[INFO]     [creator]         Writing env.launch/BPI_JVM_CACERTS.default
[INFO]     [creator]         Writing env.launch/BPI_JVM_CLASS_COUNT.default
[INFO]     [creator]         Writing env.launch/BPI_JVM_SECURITY_PROVIDERS.default
[INFO]     [creator]         Writing env.launch/JAVA_HOME.default
[INFO]     [creator]         Writing env.launch/JAVA_TOOL_OPTIONS.append
[INFO]     [creator]         Writing env.launch/JAVA_TOOL_OPTIONS.delim
[INFO]     [creator]         Writing env.launch/MALLOC_ARENA_MAX.default
[INFO]     [creator]       Launch Helper: Contributing to layer
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/active-processor-count
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/java-opts
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/jvm-heap
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/link-local-dns
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/memory-calculator
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/openssl-certificate-loader
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/security-providers-configurer
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/jmx
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/jfr
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/nmt
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/security-providers-classpath-9
[INFO]     [creator]         Creating /layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/debug-9
[INFO]     [creator]       Java Security Properties: Contributing to layer
[INFO]     [creator]         Writing env.launch/JAVA_SECURITY_PROPERTIES.default
[INFO]     [creator]         Writing env.launch/JAVA_TOOL_OPTIONS.append
[INFO]     [creator]         Writing env.launch/JAVA_TOOL_OPTIONS.delim
[INFO]     [creator]     
[INFO]     [creator]     Paketo Syft Buildpack 1.3.0
[INFO]     [creator]       https://github.com/paketo-buildpacks/syft
[INFO]     [creator]         Downloading from https://github.com/anchore/syft/releases/download/v0.33.0/syft_0.33.0_linux_amd64.tar.gz
[INFO]     [creator]         Verifying checksum
[INFO]     [creator]         Writing env.build/SYFT_CHECK_FOR_APP_UPDATE.default
[INFO]     [creator]     
[INFO]     [creator]     Paketo Executable JAR Buildpack 6.0.1
[INFO]     [creator]       https://github.com/paketo-buildpacks/executable-jar
[INFO]     [creator]       Class Path: Contributing to layer
[INFO]     [creator]         Writing env/CLASSPATH.delim
[INFO]     [creator]         Writing env/CLASSPATH.prepend
[INFO]     [creator]       Process types:
[INFO]     [creator]         executable-jar: java org.springframework.boot.loader.JarLauncher (direct)
[INFO]     [creator]         task:           java org.springframework.boot.loader.JarLauncher (direct)
[INFO]     [creator]         web:            java org.springframework.boot.loader.JarLauncher (direct)
[INFO]     [creator]     
[INFO]     [creator]     Paketo Spring Boot Buildpack 5.2.0
[INFO]     [creator]       https://github.com/paketo-buildpacks/spring-boot
[INFO]     [creator]       Creating slices from layers index
[INFO]     [creator]         dependencies
[INFO]     [creator]         spring-boot-loader
[INFO]     [creator]         snapshot-dependencies
[INFO]     [creator]         application
[INFO]     [creator]       Launch Helper: Contributing to layer
[INFO]     [creator]         Creating /layers/paketo-buildpacks_spring-boot/helper/exec.d/spring-cloud-bindings
[INFO]     [creator]       Spring Cloud Bindings 1.8.0: Contributing to layer
[INFO]     [creator]         Downloading from https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.8.0/spring-cloud-bindings-1.8.0.jar
[INFO]     [creator]         Verifying checksum
[INFO]     [creator]         Copying to /layers/paketo-buildpacks_spring-boot/spring-cloud-bindings
[INFO]     [creator]       Web Application Type: Contributing to layer
[INFO]     [creator]         Servlet web application detected
[INFO]     [creator]         Writing env.launch/BPL_JVM_THREAD_COUNT.default
[INFO]     [creator]       4 application slices
[INFO]     [creator]       Image labels:
[INFO]     [creator]         org.opencontainers.image.title
[INFO]     [creator]         org.opencontainers.image.version
[INFO]     [creator]         org.springframework.boot.version
[INFO]     [creator]     ===> EXPORTING
[INFO]     [creator]     Adding layer 'paketo-buildpacks/ca-certificates:helper'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/bellsoft-liberica:helper'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/executable-jar:classpath'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/spring-boot:helper'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[INFO]     [creator]     Adding layer 'paketo-buildpacks/spring-boot:web-application-type'
[INFO]     [creator]     Adding 5/5 app layer(s)
[INFO]     [creator]     Adding layer 'launcher'
[INFO]     [creator]     Adding layer 'config'
[INFO]     [creator]     Adding layer 'process-types'
[INFO]     [creator]     Adding label 'io.buildpacks.lifecycle.metadata'
[INFO]     [creator]     Adding label 'io.buildpacks.build.metadata'
[INFO]     [creator]     Adding label 'io.buildpacks.project.metadata'
[INFO]     [creator]     Adding label 'org.opencontainers.image.title'
[INFO]     [creator]     Adding label 'org.opencontainers.image.version'
[INFO]     [creator]     Adding label 'org.springframework.boot.version'
[INFO]     [creator]     Setting default process type 'web'
[INFO]     [creator]     Saving docker.io/library/spring-docker-cnb-demo:0.0.1...
[INFO]     [creator]     *** Images (3615490a772e):
[INFO]     [creator]           docker.io/library/spring-docker-cnb-demo:0.0.1
[INFO]     [creator]     Adding cache layer 'paketo-buildpacks/syft:syft'
[INFO] 
[INFO] Successfully built image 'docker.io/library/spring-docker-cnb-demo:0.0.1'
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:12 min
[INFO] Finished at: 2021-12-23T10:03:59+09:00
[INFO] ------------------------------------------------------------------------
```
JARの作成、必要なイメージのダウンロード、Dockerイメージのビルドが実行されました。

コンテナイメージの確認。

```
docker image ls

REPOSITORY                 TAG        IMAGE ID       CREATED        SIZE
spring-docker-demo         0.0.1      1f356d2363a4   2 hours ago    251MB
paketobuildpacks/run       base-cnb   a6fc5afbe7bb   7 days ago     87.2MB
paketobuildpacks/builder   base       73430d4688f2   42 years ago   760MB
spring-docker-cnb-demo     0.0.1      3615490a772e   42 years ago   262MB

```
ビルド時にダウンロードしてきたイメージと作成されたDockerイメージが確認できました。

#### 起動

```
docker run -it -p 8080:8080 spring-docker-cnb-demo:0.0.1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/81012ff3-eec3-69e0-7a26-a3ce742c9d82.png)

起動することができました。

# 最後に
今回二つの方法でコンテナ化を行いましたがCloud Native Buildpacksを使ったやり方が簡単でした。
Dockerfileを使ったやり方ではセキュリティやパフォーマンスを全く考慮していない簡易的な記載で行いましたが、本番環境レベルにするにはもっと詳細な記載が必要になるようなので、その差はさらに顕著になるかと思います。

Cloud Native BuildpacksはDockerfileを書くことなく脆弱性の入りづらい状態のイメージを作成することができるため、できるだけCloud Native Buildpacksを使うのが良さそうでした。

ただし全て自動で行ってくれることにより細かい設定ができないため、自分のプロジェクトで問題なく利用できるのか十分な検証が必要になるかと思うので、引き続き調査検証を行っていきたいと思います。