- 前提
- やりたいこと
- JDKはどのイメージを使う?
- まずは空のJava環境を作る
- ローカルのソースをコンテナ内と同期させる
- コンテナ内でどうやって起動するの?
- デバッグ実行&ソース変更したら自動再起動もしたい
- 拡張機能を毎回インストールするのは面倒
- 続き(ReactをDockerで環境構築)
前提
下記は準備済み。
- 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に決定。
まずは空のJava環境を作る
docker run --name test -dit eclipse-temurin
docker desktopで中身を入るとUbutu22の中にJDK21をインストールしてあるようで。
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 to Running Continerを選択
※コンテナ起動してない場合→Dev containers: Add Dev container Configuration Fileを選択
どっちでもOK。上はコンテナの変更をローカルに反映しない。下はする。
今回はdocker-compose.ymlを選択。
拡張機能。今回はなしでOK。
Reopen in Container。初回はかなり時間かかる。
コンテナ内の環境でVsCodeが開く。
コンテナ内のVsCodeに拡張機能Extension Pack for Javaをインストール
ローカル環境の時と同じように、F5押してデバッグ実行。成功!
ローカルとコンテナ内に.devcontainerというフォルダが作られている。
その中にあるdevcontainer.jsonがDev Containerの設定ファイル。
拡張機能などを設定できる。
詳細は下記を参照。
qiita.com
拡張機能を毎回インストールするのは面倒
devcontainer.jsonに欲しい拡張機能を記述すると、コンテナ構築時にインストールしてくれる。
拡張機能の歯車マークをクリックして「Add a devcontainer.json」を選択すると追加される。
・devcontainer.json
{ "customizations": { "vscode": { "settings": {}, "extensions": [ "vscjava.vscode-java-pack", "vmware.vscode-boot-dev-pack" ] } } }