【WSL】DevcontainerでSpring Boot環境を構築する

【WSL】DevcontainerでSpring Boot環境を構築する

はじめに

今回の記事では、Devcontainer 上で Spring Boot 環境を構築する手順を紹介します。

いつも開発環境は別マシンの Ubuntu 上に立てているのですが、今回は WSL 上に作成していきます。

Mac などでも Docker が動作できる環境であれば問題ないと思います。

注意点

エディタは最初は Cursor を使用していましたが、拡張機能のインストールでバグがあるようで一旦 VS Code を使用して環境を構築しています。Web サイトが表示されるところまで確認して、再度 Cursor を使用したところ特に問題なく起動できました。

WSL でコマンドから Cursor を起動できるようにする

VS Code が先にインストールされている状態だと、おそらくcode .では VS Code が起動してしまうので、コマンドから Cursor を起動できるようにパスを指定します。

ユーザー名は使用している環境に応じて変更して下さい。

echo 'export PATH="$PATH:/mnt/c/Users/[YourUsername]/AppData/Local/Programs/Cursor/resources/app/bin"' >> ~/.bashrc
source ~/.bashrc

WSL 上に適当な作業ディレクトリを作成し、そのディレクトリに移動後cursor .とコマンドを実行してエディタを開きます。

.devcontainer ファイルを作成する

.devcontainer ファイルは手動で作成しても問題ありませんが、今回はテンプレートを使用します。

Spring Boot Extension Packを拡張機能で検索し、歯車マークからdevcontainer.json に追加するを選択します。

extension.png

ダイアログが出るのでファイルを追加を選択します。

spring-boot-devcontainer.png

構成はJava devcontainersを選択します。

spring-boot-devcontainer2.png

イメージは現在最新の21-bullseyeを選択し、ビルドツールは Gradle を選択します。

※参考:プロジェクト構造と Gradle の理解(Maven との違い)

spring-boot-devcontainer3.png

spring-boot-devcontainer4.png

インストールする追加機能は選択せずに OK を選択します。

spring-boot-devcontainer5.png

.devcontainer\devcontainer.json.github\dependabot.ymlが自動で作成されたことを確認します。

devcontainer.jsonでコメントアウトされているforwardPortsにポートの設定を追加します。

{
  "name": "Java",
  "image": "mcr.microsoft.com/devcontainers/java:1-21-bullseye",
  "features": {
    "ghcr.io/devcontainers/features/java:1": {
      "version": "none",
      "installMaven": "false",
      "installGradle": "true"
    }
  },
  "customizations": {
    "vscode": {
      "extensions": ["vmware.vscode-boot-dev-pack"]
    }
  },
  // コンテナが使用するポートを設定
  "forwardPorts": [8080]
}

F1 キーでコマンドパレットを開き、devcontainers: Reopenと入力してコンテナーで再度開くを選択数

spring-boot-devcontainer6.png

コンテナの構築が実行されます。

spring-boot-devcontainer7.png

エラー無く終了し、エディタの左下に開発コンテナー: Javaと表示されていれば OK です。

spring-boot-devcontainer8.png

Spring Boot のプロジェクトを作成する

ここから新しいプロジェクトを作成します。

F1 キーでコマンドパレットを開き、spring initなどと入力しSpring Initializr: Create a Gradle Project...を選択します。

spring-boot-project.png

バージョンは 3.4.5 を選択。(サポート期間

spring-boot-project2.png

プロジェクトの言語は Java を選択。

spring-boot-project3.png

グループ ID はデフォルトまま Enter。

spring-boot-project4.png

プロジェクト名もデフォルトのまま Enter。

spring-boot-project5.png

パッケージタイプは Jar を選択。

spring-boot-project6.png

Java のバージョンを選択。

※イメージで使用しているバージョンと異なるバージョンを指定している記事を見かけましたが、環境とプロジェクト作成時に指定したバージョンが異なると、Spring Boot Dashboard にプロジェクトが表示されないので注意して下さい。

spring-boot-project7.png

依存関係(dependencies)を 2 つ選択(Spring Web と Spring Boot DevTools)

spring-boot-project8.png

spring-boot-project9.png

保存先を指定。

spring-boot-project10.png

ファイルが作成されたことを確認します。

spring-boot-project11.png

ブラウザで Hello World を表示するまで

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.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
    public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
    }
    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
      return String.format("Hello %s!", name);
    }
}

左サイドバーの Spring Boot Dashboard のアイコンをクリックして、APPS 横の RUN ボタンをクリックします。

spring-boot-run.png

http://localhost:8080/helloにアクセスしてアクセスできることを確認します。

spring-boot-run2.png

Dockerfile を作成

とりあえず動作させることはできましたのでdevcontainer.jsonだけで管理していたコンテナをDockerfiledocker-compose.ymlを作成して管理していきます。

".devcontainer/Dockerfile"
FROM mcr.microsoft.com/devcontainers/java:1-21-bullseye

# Gradleをインストール
RUN apt-get update && apt-get install -y gradle

# ワークディレクトリを設定
WORKDIR /app

# ポート8080を公開
EXPOSE 8080

# コンテナ起動時のコマンド
CMD ["bash"]

docker-compose.ymlを作成し以下の用に記述します。

".devcontainer/docker-compose.yml"
volumes:
  db-store:
    name: spring-boot-mysql-data

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: java-app
    ports:
      - "8080:8080"
    volumes:
      - ../:/app
    depends_on:
      - db
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/springdb
      - SPRING_DATASOURCE_USERNAME=springuser
      - SPRING_DATASOURCE_PASSWORD=password
      - SPRING_JPA_HIBERNATE_DDL_AUTO=update

  db:
    image: mysql:8.0
    container_name: mysql-db
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=springdb
      - MYSQL_USER=springuser
      - MYSQL_PASSWORD=password
      - MYSQL_ROOT_PASSWORD=rootpassword
    volumes:
      - db-store:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password

devcontainer.jsonを以下のように修正します。

".devcontainer/devcontainer.json"
{
	"name": "Java with MySQL",
	// Docker Composeを使用する設定
	"dockerComposeFile": "./docker-compose.yml",
	"service": "app",
	"workspaceFolder": "/app",
	"features": {
		"ghcr.io/devcontainers/features/java:1": {
			"version": "none",
			"installMaven": "false",
			"installGradle": "true"
		}
	},
	"customizations": {
		"vscode": {
			"extensions": [
				"vmware.vscode-boot-dev-pack"
			]
		}
	},
	"forwardPorts": [
		8080,
		3306
	],
	// コンテナが起動後も実行され続けるようにする
	// DockerfileのCMDで永続するコマンドを実行しているなら不要
	"overrideCommand": true
}

"overrideCommand": trueを記述していますが、その他に以下のような方法もあります。

  • Dockerfile の末尾にCMD ["tail", "-f", "/dev/null"]と記述
  • docker-compose.ymlで Java を起動するコンテナの箇所にtty: trueを記述する

最初に作成したコンテナを削除して、正常に起動するか確認します。

参考記事