【Kotlin】【Spring Boot】Dockerにデプロイしてリモートデバッグする(Spring Boot v3)

Contents

環境の準備

実行環境

  • Intellij IDEA Community 2024.3.1.1
  • open JDK 21.0.5
  • Kotlin 1.9.25
  • Docker Desktop 4.36.0

SpringBootの準備

依存関係

  • spring initializrでプロジェクト作成したあと、下記コードで上書きしてください。
plugins {
	kotlin("jvm") version "1.9.25"
	kotlin("plugin.spring") version "1.9.25"
	id("org.springframework.boot") version "3.4.1"
	id("io.spring.dependency-management") version "1.1.7"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(21)
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-data-jpa")
	implementation("org.springframework.boot:spring-boot-starter")
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("org.jetbrains.kotlin:kotlin-reflect")
	developmentOnly("org.springframework.boot:spring-boot-devtools")
	testImplementation("org.springframework.boot:spring-boot-starter-test")
	testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
	testRuntimeOnly("org.junit.platform:junit-platform-launcher")
	runtimeOnly("org.postgresql:postgresql")
}

kotlin {
	compilerOptions {
		freeCompilerArgs.addAll("-Xjsr305=strict")
	}
}

tasks.withType<Test> {
	useJUnitPlatform()
}

Kotlin配下のソース

package com.example.demo.controller

import com.example.demo.repository.entitiy.DemoTbl
import com.example.demo.service.DemoService
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController

@RestController
class DemoController
    (private val service: DemoService) {

    @RequestMapping(path = ["/"], method = [RequestMethod.GET])
    fun search(): List<DemoTbl> {
        return service.demoTblSearch()
    }
}
package com.example.demo.service

import com.example.demo.repository.DemoTblRepository
import com.example.demo.repository.entitiy.DemoTbl
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional
class DemoService
@Autowired
constructor(private val repository: DemoTblRepository) {
    fun demoTblSearch(): List<DemoTbl> {
        return repository.findAll()
    }
}
package com.example.demo.repository

import com.example.demo.repository.entitiy.DemoTbl
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface DemoTblRepository : JpaRepository<DemoTbl, Int> {
}
package com.example.demo.repository.entitiy

import jakarta.persistence.*

@Entity
@Table(name = "demo_tbl")
data class DemoTbl(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int? = 0,

    @Column(name = "demo_name")
    var name: String? = null)

application.ymlの設定

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/testdb
    username: postgres
    password: postgres
    sql-script-encoding: UTF-8
  jpa:
    show-sql: true

docker-composeの準備(プロジェクト配下に作成)

Java実行環境(docker-compose-springboot.yml)

version: '3.8'
services:
  springboot:
    container_name: demo_springboot
    image: amazoncorretto:21
    ports:
      - "18080:8080"
      - "80:80"
      - "443:443"
      - "5005:5005"
    volumes:
      - ./:/var/tmp
    working_dir: /var/tmp
    environment:
      spring.datasource.driver-class-name: "org.postgresql.Driver"
      spring.datasource.url: "jdbc:postgresql://demo_db:5432/testdb"
      spring.datasource.username: "postgres"
      spring.datasource.password: "postgres"
      spring.datasource.sql-script-encoding: "UTF-8"
      spring.jpa.show-sql: true
      TZ: "Asia/Tokyo"
    command: bash -c "java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 -jar build/libs/demo-0.0.1-SNAPSHOT.jar"

DB実行環境(docker-compose-db.yml)

※下記dockerイメージを作成した後に、postgresのバージョンを14→17.2に変更したところ、volumeで使用されているバージョンと合わないエラーが出た。同じようにはまった人は、dockerにログインして、「/var/lib/postgresql/data」ディレクトリ配下のファイルを削除する。

version: '3.8'
services:
  db:
    container_name: demo_db
    image: postgres:17.2
    ports:
      - "5432:5432"
    volumes:
      - ./dbdata:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: testdb
      TZ: "Asia/Tokyo"

Jarファイル作成からDockerにデプロイ

Jarファイルの作成

  • GradleのTaskを実行(./build/libs配下にdemo-0.0.1-SNAPSHOT.jarが作成される)

Dockerでコンテナ作成

  • ターミナルから実行すると、Docker上にコンテナが作成される
docker compose -f docker-compose-db.yml -f docker-compose-springboot.yml up -d
  • コンテナを削除したい場合はこちら
docker compose -f docker-compose-db.yml -f docker-compose-springboot.yml down

テストデータの用意

  • SQLクライアントツールでDBに接続する(接続情報はdocker-compose-db.yml参照)
DROP TABLE IF EXISTS DEMO_TBL;

CREATE TABLE DEMO_TBL (
    ID int PRIMARY KEY,
    DEMO_NAME VARCHAR(100) NOT NULL
);
INSERT INTO DEMO_TBL(ID, DEMO_NAME) VALUES (1,'demo01');
INSERT INTO DEMO_TBL(ID, DEMO_NAME) VALUES (2,'demo02');
INSERT INTO DEMO_TBL(ID, DEMO_NAME) VALUES (3,'demo03');

SpringBootアプリケーションの起動からリモートデバッグ

Intellijでの操作

  • 「実行」メニュー > 「実行構成の編集」を選択
  • 「+」ボタン > 「リモートJVMデバッグ」を選択
  • 下記情報を入力してOKボタン押下
デバッグモード:リモートJVMに接続
トランスポート:Socket
ホスト:localhost
ポート:5005
使用するモジュールのクラスパス:demo.main
  • 作成した構成情報を選択してデバッグボタン押下

Dockerでの操作

  • 特になし
  • リモートデバッグで接続すると、SpringBootアプリケーションのmainクラスが実行され、起動状態になります。

ブレークポイントの設定

  • ブレークポイントで止まれば、成功です。

あとがき

Springboot v3で動作することが確認できました。