--- title: Cloud Native Buildpacks Tutorial - 5.2. ┗ heroku/buildpacks:18 BuilderでJavaアプリ(Spring Boot)のOCIイメージを作成 tags: ["Cloud Native Buildpacks Tutorial", "Cloud Native Buildpacks", "Heroku", "Series"] categories: ["Dev", "Infrastructure", "CloudNativeBuildpacks", "Heroku"] date: 2020-04-28T09:53:51Z updated: 2020-05-11T03:34:53Z --- `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です。変更する方法は[こちら](https://devcenter.heroku.com/articles/java-support#specifying-a-java-version)を確認してください。 作成したイメージを`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 ```