Kotlin 基礎 Part 13 -- Spring アプリを Docker イメージにビルドして実行する_delete
Published: 2023-02-09 02:45:23

## why

AWS の ECR にデプロイし、ECS のタスクとして動作させるため。
ECR はコンテナ・レジストリのため、Docker イメージにする必要があった。

---

## コンテナイメージへのビルドを調査

Spring のアプリは別の記事で作った。

Docker イメージにビルドすれば docker push できると考えた。

---

## Spring 公式を見て、Dockerfile を作成

https://spring.io/guides/topicals/spring-boot-docker/

Spring 公式を見て作る。

```Dockerfile
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```

temurin の jdk17 を使い
/tmp に永続化し？
JAR_FILE を受け取り(引数で渡す)
JAR_FILE を app.jar にコピー
app.jar を実行するエントリーポイント？を決める

このように解釈した。

---

### なぜ　openJDK ではなく temurin?

Docker 公式で非推奨になっているからだった。

https://stackoverflow.com/a/70355582

openjdk もあるのはわかった。

https://hub.docker.com/_/openjdk

ただ、Docker Hub には openJDK は非推奨で、
amazon correto や temurin を使えと書いてあった。

なので temurin を使う。

----
---


# Spring 公式通りに　Docker イメージを作成して失敗。

---

## Spring 公式を参考に Docker build で Docker イメージを作る

---

### Spring 公式の引数を使ってビルドに失敗

https://spring.io/guides/topicals/spring-boot-docker/

```php
docker build \
--build-arg JAR_FILE=target/*.jar \
-t myorg/myapp .
```

これでは Mac の自分の環境ではビルドできなかった。
Spring 公式ではこのコマンドでビルドできると書いてあった。
一方、下記の 2 つのエラーが出た。

---

### Docker の並列実行がエラーになる

```php
dockerfile.v0: failed to create LLB definition
```

https://qiita.com/takkeybook/items/2214892b45f9044de01d#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A

この takkeybook さんの記事を参考に

```php
export DOCKER_BUILDKIT=0
export COMPOSE_DOCKER_CLI_BUILD=0
```

.zshrc に上記の設定を追記して zsh を再起動したら解決した。
これは Docker の並列実行の設定を　OFF にしている。

---

### Linux/arm64 でビルドされていないエラー

次にビルドする Docker イメージが Mac のコアのアーキテクチャと違うエラーが出た。

```php
no matching manifest for linux/arm64 in the manifest list entries
```

https://qiita.com/jizya/items/38f15271903de629d1ab#%E3%82%A8%E3%83%A9%E3%83%BC%E5%86%85%E5%AE%B9

https://stackoverflow.com/questions/65612411/forcing-docker-to-use-linux-amd64-platform-by-default-on-macos

これらの 記事を参考にして

```php
--platform=linux/amd64
```

これを docker ビルド時に追加すると、上記のエラーが消えた。

----
----





# 改善を加えて実際に動作を確認

---

## 実際に動かすために必要だったファイルとコマンドたち

プロジェクト名は spring302

Dockerfile

```dockerfile
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
COPY build/libs/spring302-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```

イメージのビルドコマンド

```php
docker build -t spring302 . 
```

イメージの実行コマンド

```php
docker run -p 8080:8080 spring302
```

このコマンドで実際に動かすことができた。

---

## -t とは？

https://qiita.com/saitoshi/items/a931399e81e63e8e4f1e#%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89

この記事によると、-t の引数は

-t {DockerHub のユーザー名}/イメージ名:タグ名

になっていて、ユーザー名とタグ名はオプショナルだ。

---

## 動作の詳細

```php
docker build -t spring302 .                      
Sending build context to Docker daemon  24.91MB
Step 1/4 : FROM eclipse-temurin:17-jdk-alpine
 ---> ce2d65591ecf
Step 2/4 : VOLUME /tmp
 ---> Using cache
 ---> 2bb51666c4a9
Step 3/4 : COPY build/libs/spring302-0.0.1-SNAPSHOT.jar app.jar
 ---> 3b3b9921a589
Step 4/4 : ENTRYPOINT ["java","-jar","/app.jar"]
 ---> [Warning] The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
 ---> Running in 413b5bbec2fe
Removing intermediate container 413b5bbec2fe
 ---> 67cbf2faa084
Successfully built 67cbf2faa084
Successfully tagged spring302:latest
```

Dockerfile に従ってビルドが成功。

```php
docker images

REPOSITORY                TAG             IMAGE ID       CREATED          SIZE
spring302                 latest          67cbf2faa084   14 seconds ago   382MB
```

イメージが生成されている。

```php
docker run -p 8080:8080 spring302

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

Started Spring302ApplicationKt in 14.871 seconds
```

イメージから起動できる。

---

## まとめ

MacOS を使って Spring アプリを Docker イメージにして実行する。
そのためには

1. zshrc などで Docker の並列ビルドを無効化
2. COPY する jar ファイルとして、build/...SNAPSHOT.jar を指定
3. docker build して　docker run する

これらの手順で実行できる。

---

## 今後

コンテナ化が完了したので、ECR にデプロイする。