SpringBootでRESTApiのDocker環境構築

# はじめに
最近SpringBootを触ることが多くて、Dockerと合わせて試してみました！
SpringBootのREST APIを使って、Docker環境を作ってみましょう〜

### まず、SpringBootのプロジェクト作成から始まります
コマンドとツールがあるので、好きな方で大丈夫です。

コマンドの場合

```
curl https://start.spring.io/starter.tgz -d dependencies=web \
   -d bootVersion=3.0.0 \
   -d groupId=com.cat-docker \
   -d artifactId=cat-docker \
   -d type=maven-project \
   -d language=java \
   -d javaVersion=17 \
   -d packageName=com.cat.cat-docker| tar -xzvf -
```
参考：https://developer.okta.com/blog/2020/12/28/spring-boot-docker

Initializrツールの場合
https://start.spring.io/

![スクリーンショット 2022-12-19 17.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982506/b4dda2a1-d2cd-8e0d-1ab1-83f23161ebf7.png)
生成されたZipファイルはプロジェクトのもとになります

今回最終的にREST APIとして使っている想定なので、プロジェクトを開いて簡単なコントローラーを用意しました
![スクリーンショット 2022-12-19 17.52.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982506/2ff65d61-3c6d-7c4f-2ca4-ced9d4890cff.png)

念のため、プロジェクトをrunすると`localhost::8080/catinfo?name=Fluffy`でレスポンスを試すことができます
![スクリーンショット 2022-12-19 17.55.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982506/7af8353e-dcf3-a510-a07d-b798a5808313.png)

動いているプロジェクトの作成ができたので、次Docker化を進めましょう〜

### Docker化
#### Dockerfileの作成
最初にDockerfileが必要なので、ダイレクトリーのトップでDockerfileを作成します
今回ローカルの手間を減らすため、Multi-stage buildを利用します
大きく三つのことをやります

一つ目はbuild用のjavaイメージを作ります
17のところを使っているバージョンを合わせて修正が必要です
alpineを使うとより小さいイメージを使うことができます。
必要なリソースをコンテナにコピーします。
```
FROM eclipse-temurin:17-jdk-alpine as build
WORKDIR /workspace/app

COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src

```

次、MavenのinstallコマンドでJARファイルが生成されます。
JARファイルが大きいので、先に分割してキャッシングなどを使えば初回以降の立ち上がりが速くなります

```
RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
```

最後に分割したJARファイルを正しいダイレクトリーにコピーして、
Applicationを起動するためのコマンドを追加します。
「com.cat.catdocker.CatDockerApplication」のところに自分自身のApplicationファイルに修正してください！
```
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.cat.catdocker.CatDockerApplication"]
```
参考：https://spring.io/guides/topicals/spring-boot-docker

### Docker Compose
起動が楽になるため、docker-composeファイルも用意します。
また、今後DBやフロントのコンテナを追加したい時簡単に追加できます！


Dockerfileと同じく、プロジェクトのトップにdocker-compose.ymlファイルを作成してください〜
今回まだ一つのコンテナのみなので、シンプルなファイル内容になります。

```
version: '3'  
services:  
  app:  
    build: 
      context: ./
    ports:  
      - 8080:8080
```
buildのcontextはDockerfileの場所になります。
portsは好きなポートに設定でも大丈夫です
例：
```
    ports:  
      - 3030:8080
```

### 起動してみましょう！
docker-compose.ymlがあるダイレクトリーで`docker-compose up`を初回で実行したらコンテナが自動的にBuildされます
![スクリーンショット 2022-12-19 18.56.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982506/370052a7-2062-240c-1fe0-8dc4a845bc83.png)

終わったらSpringBootのアプリケーションが起動されます
![スクリーンショット 2022-12-19 18.57.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982506/7e5e7f88-3f0c-0ab1-4e11-b7a888bab3c4.png)

上と同じくアクセスしてみるとレスポンが確認できます
（わかりやすいため、ポートを3030に変更しました）
![スクリーンショット 2022-12-19 19.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982506/8e52a84e-5f9d-4995-a1b7-568b84e61e77.png)

### 終わり
毎回ソースが変わったら再Buildが必要なのですが、
Dockerを使えば環境構築やバージョン管理はより楽になります

様々なニーズによってDockerをカスタマイズできるので、使ってみてはいかがでしょうか〜

Have a nice Christmas🎄!