okinawa

IT勉強メモ

DockerでSpringBoot環境構築(デバッグ実行と自動再起動あり)

前提

下記は準備済み。

  • VsCode
  • Docker DeskTop
  • WSL2
  • SpringBootプロジェクト

やりたいこと

  • Dockerコンテナ内にSpringBootプロジェクトを配置
  • ローカル環境と同じようにデバッグ実行可能
  • コード直したら自動再起動もしたい

※自動再起動はSpring Boot Devtoolsの機能。

pom.xmlに以下を記述。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

JDKはどのイメージを使う?

DockerHubをみるとOpenJDKが非推奨になっていた。

下記サイトを参考にeclipse-temurinに決定。

zenn.dev

まずは空のJava環境を作る

docker run --name test -dit eclipse-temurin

docker desktopで中身を入るとUbutu22の中にJDK21をインストールしてあるようで。

eclipse-temurinのDockerfile↓

eclipse-temurinのDockerfile

ローカルのソースをコンテナ内と同期させる

ローカルでソースを編集したら、コンテナ内のソースも同期させたい。

コンテナ内にソースを置くworkspceを作ろうと思ったが、どこが良いかわからなかったので参照したサイト↓
qiita.com

ルートディレクトリにworkspaceディレクトリを作ることにした。

ここにローカルのソースコードを同期させる。

# docker run --name コンテナ名 -v ローカルのパス:コンテナ内のパス -dit イメージ名
docker run --name test -v C:\VsCode_Workspace\weather_app\backend:/workspace  -dit eclipse-temurin

Dockerデスクトップで見るとworkspceディレクトリが作られている。

ローカル側でworspce内にファイルを作ってみる。

コンテナ内にもnewfile.txtができている。同期OK。

コンテナ内でどうやって起動するの?

mvn clean→mnv installでjarファイルを作成→実行、という流れで起動できる。

以下に詳しい手順。

VsCodeのターミナルで.mvnファイルがある場所に移動する。

VsCodeのサイドバーでmaven clean → maven install

targetフォルダにjarファイルができる

コンテナ内のtargeディレクトリまで移動してjava -jar jarファイル名で実行。起動OK。

しかし、これだとデバッグ実行ができないし、手動で毎回起動するのはしんどい。

デバッグ実行&ソース変更したら自動再起動もしたい

ここが大変だった。

大きく2つの方法があるみたい。

方法1:デバッグ実行中のプロセスにattachする

Dockerfileでデバッグ実行&launch.jsonデバッグ実行中のプロセスにattachする。

一応ChatGPTに聞いた内容を記載する。未検証なので動かないかも。

・Dockerfile

# ベースとなるDockerイメージを指定します
FROM adoptopenjdk/openjdk11:alpine

# アプリケーションのJARファイルをコピーします
COPY target/my-spring-boot-app.jar /app/my-spring-boot-app.jar

# デバッグポートを開放します(デフォルトは5005ポート)
EXPOSE 5005

# コンテナ内での作業ディレクトリを指定します
WORKDIR /app

# Dockerコンテナが起動する際に実行されるコマンドを指定します
# -agentlib:jdwp~がデバッグ実行らしい
CMD ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-jar", "my-spring-boot-app.jar"]

・launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "java",
      "name": "Debug (Attach) - Docker",
      "request": "attach", // launchだと新規起動。attachだと実行中プロセスに接続
      "hostName": "localhost",
      "port": 5005
    }
  ]
}

方法2:Dev Container(VsCode拡張機能

Dev Containerとは大雑把に言えば、VsCodeごとコンテナ内に環境を移植するもの。

引用元:https://code.visualstudio.com/docs/devcontainers/containers

■特徴
ローカルのVsCodeでできることは、コンテナ内でも大体できる。

もちろんデバッグ実行やSpringBootの自動再起動も。

■手順
拡張機能Dev Containerをインストール。

docker-compose.ymlを作成。
中身は特に変わったことはなく、eclipse-temurinイメージでコンテナ作成し、ローカルのソースとコンテナ内のソースを同期させる。

version: '3'
services:
  javatest:
    image: eclipse-temurin
    # ローカルのソースコードをコンテナ内と同期
    volumes:
      - C:\VsCode_Workspace\weather_app\backend:/workspace
    # コンテナ起動状態を維持する
    tty: true

コンテナ起動

docker compose -f ymlのパス  up -d

先程作ったdocker-compose.ymlを配置したフォルダをVsCodeで開く

VsCodeでCtrl + Shift + P → Dev containers Attach Dev container configuration filesを選択

どっちでもOK。上はコンテナの変更をローカルに反映しない。下はする。

今回はdocker-compose.ymlを選択。

拡張機能。今回はなしでOK。

Reopen in Container。初回はかなり時間かかる。

コンテナ内の環境でVsCodeが開く。

コンテナ内のVsCode拡張機能Extension Pack for Javaをインストール

ローカル環境の時と同じように、F5押してデバッグ実行。成功!

ローカルとコンテナ内に.devcontainerというフォルダが作られている。
その中にあるdevcontainer.jsonがDev Containerの設定ファイル。
拡張機能などを設定できる。

詳細は下記を参照。
qiita.com

公式
containers.dev

拡張機能を毎回インストールするのは面倒

devcontainer.jsonに欲しい拡張機能を記述すると、コンテナ構築時にインストールしてくれる。

拡張機能の歯車マークをクリックして「Add a devcontainer.json」を選択すると追加される。

・devcontainer.json

{
    "customizations": {
        "vscode": {
            "settings": {},

            "extensions": [
                "vscjava.vscode-java-pack",
                "vmware.vscode-boot-dev-pack"
            ]
        }
    }
}

続き(ReactをDockerで環境構築)

dodosu.hatenablog.jp