VScode × Docker × SpringBootでホットデプロイ環境構築
こんにちわ、将来の夢はジェダイマスターのカリーです。
今回はMacで、Dockerを使用したJavaのホットデプロイ環境を構築してみたので、ご紹介したいと思います。
Javaの環境構築するのは久しぶりで、以前はEclipseやNetBeansを使用していたのですが、極力開発環境は統一したいなと思い、普段使いしているVSCodeで試してみました。
動作環境
- M1 Mac(macOS Ventura)
- Docker Desktop for Mac(4.x)
- Spring Boot(3.1.3)
ディレクトリ構成
こちらが、完成系のディレクトリ構成です。(所々省略しています)
├── .vscode
│ └── launch.json
├── demo
│ ├── .gradle
│ ├── bin
│ ├── build
│ ├── gradle
│ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── demo
│ │ │ │ └── DemoApplication.java
│ │ │ └── resources
│ │ └── test
│ ├── .gitignore
│ ├── build.gradle
│ ├── gradlew
│ ├── gradlew.bat
│ ├── HELP.md
│ └── settings.gradle
└── docker-compose.yaml
環境構築
Docker環境を用意
プロジェクトディレクトリを作成し、ディレクトリ直下にdocker-compose.yamlを作成します。
version: "3.6"
services:
java:
image: openjdk:17-oracle
container_name: demo-java
tty: true
working_dir: /app
volumes:
- ./demo:/app
ports:
- 8080:8080 # 通常実行用
- 5050:5050 # デバッグ用
拡張機能の導入
VSCodeの拡張機能で「Extension Pack for Java」を入れます。
Extension Pack for JavaはVSCode環境でJavaアプリケーションの作成、テスト、デバッグを進めるための拡張機能パックとなっており、インストールすることで以下6つの拡張機能がインストールされます。
- Language Support for Java(TM) by Red Hat
- Debugger for Java
- Test Runner for Java
- Maven for Java
- Project Manager for Java
- IntelliCode
Spring Bootプロジェクトを作成
他にもSpringプロジェクトを用意する方法があるのですが、今回はSpring InitializerでSpring Bootプロジェクトの雛形を作成します。
Spring Initializerを使用することで、GUIベースで簡単にSpring Bootプロジェクトを作成することができます。
今回は、以下のような設定で作成しました。
作成してダウンロードしたSpring Bootプロジェクトを、プロジェクトディレクトリ直下に配置し、
その後、build.gradleファイルの中の末尾に以下を追記します。
jar {
enabled = false
}
bootJar {
archiveBaseName = "sample"
version = "0.0.1"
archiveClassifier = 'SNAPSHOT'
archiveExtension = 'jar'
}
bootRun {
systemProperties = System.properties
jvmArgs=["-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5050"]
}
VSCodeの設定
次に、プロジェクトディレクトリ直下に.vscode/launch.jsonを作成します。
{
"version": "0.2.0",
"configurations": [
{
"type": "java", // 言語を指定
"name": "java (Attach)", // デバッグ実行名
"request": "attach", // 起動中のプログラムにアタッチ
"hostName": "localhost",
"port": 5050 // 接続するポートを指定
}
]
}
コンテナ上でビルド実行
まずはターミナル上で以下のコマンドを叩き、Javaコンテナを起動します。
$ docker-compose up -d
[+] Building 0.0s (0/0)
[+] Running 2/2
✔ Network demoapp_default Created
✔ Container demo-java Started
コンテナを作成・起動したら、javaコンテナ内に入ります。
$ docker exec -it demo-java /bin/bash
bash-4.4#
コンテナ内に入れたら、pwdコマンドでappディレクトリにいることを確認し、ビルドしていきます。
bash-4.4# pwd
/app
# ビルド開始
bash-4.4# microdnf install findutils
bash-4.4# sh gradlew build --continuous
BUILD SUCCESSFUL in 3s
6 actionable tasks: 4 executed, 2 up-to-date
Waiting for changes to input files... (ctrl-d to exit)
<=============> 100% EXECUTING [1s]
> IDLE
> IDLE
sh gradlew buildに–continuousオプションを付けておくことで、一度ビルドしたのちに変更監視状態となり、ソース修正を行うたびに再ビルドされます。
終了しない限りは常に変更監視状態となるので、Springを起動する際は別のターミナルから再度コンテナ内に入って起動します。
# 別のターミナルから再度コンテナ内に入る
$ docker exec -it demo-java /bin/bash
bash-4.4#
# Spring起動
bash-4.4# sh gradlew bootRun
Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details
Springを起動したら、最後にVSCodeのデバッグモードで起動します。
VSCodeのデバッグビューを開いて、サイドバーの[実行とデバッグ]ビューを確認すると、「java(Attach)」と表示されているプルダウンがあると思います。
(これが、先ほどlaunch.jsonのconfigurations → nameに記載されていたデバッグ実行名です)
この状態で開始ボタンを押すことで、launch.jsonで定義した設定を元に、デバッグモードが起動されます。
ホットデプロイ動作確認
では、ちゃんとホットデプロイがされているのか確認します。
demo/src/main/java/com/example/demo/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 "Hello World"; // 追加
} // 追加
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
まずはこの状態でlocalhost:8080にアクセスすると、Hello Worldが表示されるかと思います。
次に、”Hello World”の部分を、別の文字に修正して、再度localhost:8080にアクセスしてみます。
@RequestMapping("/")
public String home() {
return "Hello Mavs";
}
正常にホットデプロイが行われ、修正した文字が表示されます!
まとめ
今回はVSCodeでSpring Bootのホットデプロイ環境の構築についてご紹介しました。
この環境を試すまでは修正するたび毎回Jarファイル生成 → Boot Runをしていたのですが、手間に耐えきれず「ホットデプロイって可能なのか?」と思い構築に至りました。
sh gradlew build –continuousの処理までをDockerfileに入れたら立ち上げ時楽になると試してみると、2度目以降は良かったのですが、初回が–continuousでDockerfileの処理が終わらず、コンテナが出来上がらなかったので断念しました。。
今回はこのような構成になりましたが、もっと良い方法(特にターミナルを一つで済ます方法)が見つかりましたら、この記事を更新したいなと思います。