## 2019-04-17 追記
ブログ書くだけなのもあれだなと思って、こんな感じにしたらどうかな?ってIssueを書いた。
そしたら「1.1.0でnative image化が十分シンプルになったから、ビルド用のシェルスクリプトを削除したんだ」って教えてもらった。まぁ、確かにそうね。
なので、普通にビルドするってことでいいし、Dockerでやりたい場合でも、僕がこのブログ記事で書いてるようなので良さそう。かな。
それと、マルチステージビルドをしっかりやってるサンプルも教えてもらった。ふむふむー。
追記はここまでです!
## Native Image
MicronautにはGraalVMのサポートが入っていて、GraalVMを使ってMicronautアプリのNative Imageを生成することができる。
ドキュメントはこの辺: https://docs.micronaut.io/1.1.0/guide/index.html#graal
Micronautのバージョンは1.1.0。
## graal-native-image feature
Micronautのcreate-appをするときに、graal-native-imageをfeatureオプションにつける。
❯ mn create-app hello-graal --features graal-native-image
| Generating Java project...
| Application created at /home/bufferings/workspace/micronaut/hello-graal
と、プロジェクトの生成と同時に、GraalVMでNative Imageをビルドするときのためのファイルがいくつか生成される。
## Dockerでのビルドがいまいち?
その作成されるファイルの中にDockerfileとdocker-build.shがあって「docker-build.shを実行すればDockerのマルチステージビルドで、Native Imageがビルドされるよ!」ってドキュメントには書いてある。
んだけど、いまいちかなー。と思ったのでメモを書いとく。
## docker-build.sh
は、こうなってる
#!/bin/sh docker build . -t hello-graal echo echo echo "To run the docker container execute:" echo " $ docker run --network host hello-graal"
つまり、Dockerfileでビルドしてるよってだけね。じゃあDockerfileを見てみよう。
## Dockerfile
こうなってる。マルチステージビルドを使ってる。
FROM oracle/graalvm-ce:1.0.0-rc15 as graalvm COPY . /home/app/hello-graal WORKDIR /home/app/hello-graal RUN native-image --no-server -cp build/libs/hello-graal-*.jar FROM frolvlad/alpine-glibc EXPOSE 8080 COPY --from=graalvm /home/app/hello-graal . ENTRYPOINT ["./hello-graal"]
### まず前半の4行は
- graalvmのイメージを使って
- カレントディレクトリーを
/home/app/hello-graal
にコピーして - そこをWORKDIRにして
native-image
コマンドを実行してNative Imageをビルドしてる
んー。これだと、GradleによるJARファイルのビルドを事前に実行しておかないといけない・・・よね。もしDockerだけで完結させたいならこうかな?
RUN ./gradlew assemble \ && native-image --no-server -cp build/libs/hello-graal-*.jar
ただ、これだとビルドのたびにGradleをダウンロードしてきてビルドするから時間がかかるよね。
### 次に後半の4行は
この部分だけ
COPY --from=graalvm /home/app/hello-graal .
これ、前半でビルドしたイメージから、必要なファイルをコピーしてきてるんだけど、ソースコードまで要らんくない?しかもルートディレクトリーにガッと突っ込んでる。そうじゃなくて、
COPY --from=graalvm /home/app/hello-graal/hello-graal .
Native Imageだけ取ってこれたらいいかなと。あと、これは僕の好みだけなんだけど、ルート直下に置くよりは、なんかディレクトリーいっこ切っておきたいな。
FROM frolvlad/alpine-glibc EXPOSE 8080 WORKDIR /app COPY --from=graalvm /home/app/hello-graal/hello-graal . ENTRYPOINT ["/app/hello-graal"]
### ということで
こうなった
FROM oracle/graalvm-ce:1.0.0-rc15 as graalvm COPY . /home/app/hello-graal WORKDIR /home/app/hello-graal RUN ./gradlew assemble \ && native-image --no-server -cp build/libs/hello-graal-*.jar FROM frolvlad/alpine-glibc EXPOSE 8080 WORKDIR /app COPY --from=graalvm /home/app/hello-graal/hello-graal . ENTRYPOINT ["/app/hello-graal"]
### 実行するには
host networkモードを使うんだ!ってドキュメントに書いてある。
$ docker run --network=host hello-world
僕のマシンはUbuntuだからいいんだけど、Docker for Macだと現時点ではサポートされてないよね。。。
https://docs.docker.com/network/host/
素直にpublishオプションを使っていいんじゃないかな。
$ docker run -p 8080:8080 hello-world
## そこまでしてDocker使わなくても・・・
いいかなと思う。さっきも書いたけどDocker使うとgradlewの実行遅いし。だから、素直にホストマシンにsdkmanでGraalVM使ってやるといいのかなと。思うのであった。
❯ sdk use java 1.0.0-rc-15-grl Using java version 1.0.0-rc-15-grl in this shell. ❯ ./gradlew assemble Starting a Gradle Daemon, 2 incompatible Daemons could not be reused, use --status for details BUILD SUCCESSFUL in 11s 10 actionable tasks: 7 executed, 3 up-to-date <-------------> 0% WAITING > IDLE ❯ native-image --no-server -cp build/libs/hello-graal-*.jar [hello-graal:31214] classlist: 6,843.33 ms [hello-graal:31214] (cap): 1,346.60 ms [hello-graal:31214] setup: 3,216.68 ms [hello-graal:31214] (typeflow): 52,258.57 ms [hello-graal:31214] (objects): 38,803.47 ms [hello-graal:31214] (features): 2,844.33 ms [hello-graal:31214] analysis: 97,553.99 ms [hello-graal:31214] universe: 2,264.42 ms [hello-graal:31214] (parse): 7,780.03 ms [hello-graal:31214] (inline): 10,103.81 ms [hello-graal:31214] (compile): 85,401.85 ms [hello-graal:31214] compile: 106,246.90 ms [hello-graal:31214] image: 5,274.68 ms [hello-graal:31214] write: 1,565.77 ms [hello-graal:31214] [total]: 223,483.88 ms ❯ ./hello-graal 23:31:52.391 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 169ms. Server Running: http://localhost:8080 ^C ❯ ./hello-graal 23:32:00.775 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 64ms. Server Running: http://localhost:8080
お。何も設定してないから速いってのもあるけど200msとか100msとかで起動するのは良いなー。
ということで、もうちょっとMicronautとGraalVMのNative Image周りを勉強してみようと思う。