Dockerを使った環境構築 Java(Spring)×Maven 

最終的にAWS上でデプロイすることを想定して、Java(Spring)の環境構築をDockerでやってみた。Mavenでライブラリ管理する前提。

手順や考え方についてコメントいただけると嬉しいです。

実現したいこと

  • なるべく簡単に実行環境を構築する。
    (Docker使うことでサーバー立てたりする作業を省く)
  • vscodeで開発する(Eclipseを使わない)

前提

  • Dockerをインストールして、Dockerコマンドを使える
  • ローカルにJava17をインストールしている

作業手順

環境構築から、アプリケーション起動まで。

雛形プロジェクトの作成

spring initializrで、以下の設定内容でspringプロジェクトの雛形を作成する。

雛形プロジェクトにあるDemoApplication.javaの中身は以下のようにする。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

    @RequestMapping("/")
    public String home() {
        return "Dockerizing Spring Boot Application";
    }

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

}

docker-compose.ymlの作成

version: '3.6'
services:
  app:
    image: openjdk:17 # Javaのバージョンはpom.xmlの記載と同じである必要がある
    ports:
      - 80:80
    tty: true
    volumes:
      - ./server:/srv:cached # ymlファイルから見た相対パスで、雛形PJの配置場所をマウントする
    working_dir: /srv

mavenをローカルにインストール

以下の記事を参考に、インストール、PATHを通すところまで実施。
MacにMavenをインストールする - Qiita

コンテナを起動

(base) YondaHouse % docker compose up -d                           
[+] Running 1/1
 ⠿ Container yondahouse-app-1  Started         
(base) YondaHouse % docker ps    # 起動してることの確認                       
CONTAINER ID   IMAGE        COMMAND    CREATED              STATUS              PORTS                NAMES
8d12857b89c7   openjdk:17   "jshell"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp   yondahouse-app-1

プロジェクトのビルド

Javaプロジェクトを実行するには、ビルドして実行ファイル(jar)を作成する必要がある。
pom.xmlのあるディレクトリに移動して、以下のコマンドを実行。

(base) server % mvn install  
・
・
・
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  28.005 s
[INFO] Finished at: 2023-03-05T09:33:37+09:00
[INFO] ------------------------------------------------------------------------

最終的にBUILD SUCCESSが表示されることを確認する。

Webサービスを起動する

コンテナ内にログインした状態で、作成されたjarファイルを実行して、Webサービスを起動する。

YondaHouse % docker exec -it yondahouse-app-1 bash # コンテナ内にログイン
bash-4.4# java -jar target/demo-0.0.1-SNAPSHOT.jar # jar実行

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

docker-compose.ymlにentrypointを追記することで、コンテナと起動と同時にjarファイルを実行することもできる。こうすると、コンテナに入ってjarを実行する手間が省ける。

version: '3.6'
services:
  app:
    image: openjdk:17
    ports:
      - 80:8080
    tty: true
    volumes:
      - ./server:/srv:cached
    working_dir: /srv
    entrypoint: ["java","-jar","target/demo-0.0.1-SNAPSHOT.jar"] # コンテナ側のjarファイルを指定する。

ブラウザに接続してみる

https://localhost:80/にアクセスして、DemoApplication.java(雛形プロジェクトの/server/src/main/java/com/example/demo/DemoApplication.java)で指定した文字が表示されることを確認。

気づき

本番環境で不要な環境条件(maven)について

mavenを使った開発をするのであれば、openjdkとmaven両方のイメージが必要。
そして、mavenはビルドするのに必要だけど、本番環境では使わないものなので本来ならコンテナを分けるべき。

ただ、Mavenのコンテナだけ分けて立てるのは結構面倒そう(たぶんDockerfileで別に定義して別で起動することになる?)

openjdkのみのコンテナにして、mavenはローカルにインストールする。
mavenをローカルに入れるということは、開発環境(mavenを使う環境)としてローカルにJavaをインストールする必要がある。

ローカルにJavaをインストールしておく。

結果的に、Dockerを使うメリットの一つである「ローカルを汚さない」ということは今回諦めた。。