warning
この記事は2年以上前に更新されたものです。情報が古くなっている可能性があります。

heroku/buildpacks:18でJava(Spring Boot)のアプリケーションのOCIイメージを作成します。

BuilderとStackを予めpullしておいてください。

docker pull heroku/buildpacks:18
docker pull heroku/pack:18

次のコマンドで"Hello World"アプリケーションを作成します。

curl https://start.spring.io/starter.tgz \
       -d artifactId=hello-spring-boot \
       -d baseDir=hello-spring-boot \
       -d dependencies=webflux \
       -d packageName=hello \
       -d applicationName=HelloSpringBootApplication | tar -xzvf -

cd hello-spring-boot
cat <<'EOF' > src/main/java/hello/HelloSpringBootApplication.java
package hello;

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 HelloSpringBootApplication {
    
    @GetMapping("/") 
    public String hello() {
        return "Hello World!";
    }

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

}
EOF

pack buildコマンドでイメージを作成します。

pack build making/pack-spring-boot --no-pull --builder heroku/buildpacks:18

BuilderとStackを事前にpullしていない場合は--no-pullを外せば、ビルド時にBuilderとStackもpullしますが、ビルドが遅くなります。

次のようなログが出力されます。

===> DETECTING
[detector] heroku/jvm      0.1
[detector] heroku/maven    0.1
[detector] heroku/procfile 0.5
===> ANALYZING
[analyzer] Warning: Image "index.docker.io/making/pack-spring-boot:latest" not found
===> RESTORING
===> BUILDING
[builder] 
[builder] [Installing Java]
[builder] JDK 1.8 installed
[builder] JRE 1.8 installed
[builder] 
[builder] [Executing Maven]
[builder] $ ./mvnw -DskipTests clean dependency:list install
[builder] [INFO] Scanning for projects...
[builder] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.6.RELEASE/spring-boot-starter-parent-2.2.6.RELEASE.pom
[builder] [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.6.RELEASE/spring-boot-starter-parent-2.2.6.RELEASE.pom (8.1 kB at 9.6 kB/s)
(途中略)
[builder] [INFO] ------------------------------------------------------------------------
[builder] [INFO] BUILD SUCCESS
[builder] [INFO] ------------------------------------------------------------------------
[builder] [INFO] Total time:  03:29 min
[builder] [INFO] Finished at: 2020-04-28T12:38:34Z
[builder] [INFO] ------------------------------------------------------------------------
[builder] -----> Discovering process types
[builder]        Procfile declares types     -> (none)
===> EXPORTING
[exporter] Adding layer 'launcher'
[exporter] Adding layer 'heroku/jvm:jre'
[exporter] Adding 1/1 app layer(s)
[exporter] Adding layer 'config'
[exporter] *** Images (8ab2865d1291):
[exporter]       index.docker.io/making/pack-spring-boot:latest
[exporter] Adding cache layer 'heroku/jvm:jdk'
[exporter] Adding cache layer 'heroku/jvm:utils'
[exporter] Adding cache layer 'heroku/maven:maven'
Successfully built image making/pack-spring-boot

pack build時に--publishオプションをつけると、Docker Registryでのpushを行います。事前にdocker loginが必要です。

Mavenによるソースコードから始まるため、初回ビルド時には依存ライブラリのダウンロードが始まります。
依存ライブラリはキャッシュされ、二回目以降はキャッシュが使用されます。

JDKのバージョンはデフォルトで8です。変更する方法はこちらを確認してください。

作成したイメージをdocker runで起動します。

docker run --rm -p 8080:8080 making/pack-spring-boot

起動時に次のようなログが出力されます。

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

2020-04-28 12:40:25.073  INFO 1 --- [           main] hello.HelloSpringBootApplication         : Starting HelloSpringBootApplication v0.0.1-SNAPSHOT on 6e99094d8e7a with PID 1 (/workspace/target/hello-spring-boot-0.0.1-SNAPSHOT.jar started by heroku in /workspace)
2020-04-28 12:40:25.080  INFO 1 --- [           main] hello.HelloSpringBootApplication         : No active profile set, falling back to default profiles: default
2020-04-28 12:40:27.167  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2020-04-28 12:40:27.175  INFO 1 --- [           main] hello.HelloSpringBootApplication         : Started HelloSpringBootApplication in 2.703 seconds (JVM running for 3.399)

PaketoのJava Buildpackとは異なり、JVMのメモリ設定が自動で行われないので環境変数JAVA_OPTSに適切に設定する必要があります。

アプリケーションにアクセスします。

$ curl localhost:8080 -w '\n'
Hello World!

Docker Imageのサイズを確認します。

$ docker images | grep making/pack-spring-boot
making/pack-spring-boot              latest              8ab2865d1291        40 years ago        624MB

pack inspect-imageでイメージを解析します。

$ pack inspect-image making/pack-spring-boot
Inspecting image: making/pack-spring-boot

REMOTE:
(not present)

LOCAL:

Stack: heroku-18

Base Image:
  Reference: 60f9e03398de7d6a5268be95224246f05eed9f1eecb1fe7605753261f2bd871a
  Top Layer: sha256:ceefbd5b67bc32a9d87867c8c8d375675246e9db9b470cb95133b4e93429b113

Run Images:
  heroku/pack:18

Buildpacks:
  ID                     VERSION
  heroku/jvm             0.1
  heroku/maven           0.1
  heroku/procfile        0.5

Processes:
  TYPE                 SHELL        COMMAND                                                                                     ARGS
  web (default)        bash         java -Dserver.port=$PORT $JAVA_OPTS -jar target/hello-spring-boot-0.0.1-SNAPSHOT.jar        

Java Buildpackの細かい設定は
https://github.com/heroku/java-buildpack
を確認してください。

おわったらDocker Imageを削除します。

docker rmi making/pack-spring-boot
Found a mistake? Update the entry.
Share this article: