8
3

More than 1 year has passed since last update.

Spring Boot × PostgreSQL × Docker(Compose V2)でお手軽環境構築

Last updated at Posted at 2023-08-08

はじめに

こんにちは! @Keichan_15 です!

以前 Spring BootとPostgreSQLのローカル環境構築に関するハンズオン を執筆した際に、ちょうどDockerを学んでいたこともあってDockerでも構築できるのかな~って興味本位で調べてみたら、どうやらありました!:clap:

今回はそれらを参考にしつつ、Dockerを使用してローカル環境を汚さずに比較的シンプルな構成で環境構築を行っていきたいと思います!

よろしくお願い致します!

環境

  • Windows11(Windows10)
  • Docker Desktop

準備

任意のディレクトリにフォルダを作成します。
自分は今回 spring_boot という名前のフォルダを作成しました。

Windows PowerShell
> mkdir spring_boot
> cd spring_boot

この時点でVisual Studio Codeを起動し、Visual Studio Code内のターミナル上で操作していきます。

Windows PowerShell
> code .

上記コマンドを入力すると、Visual Studio Codeが開きます。

image.png

ここまで出来れば準備は完了です!

compose.yamlの作成・編集

続いてcompose.yamlを作成・編集します。今回はDocker Compose V2に倣って作成していきます。

compose.yaml
services:
  app:
    image: openjdk:17
    container_name: app
    ports:
      - 8080:8080
    tty: true
    volumes:
      - ./server:/srv:cached
    working_dir: /srv
    depends_on:
      - db

  db:
    image: postgres:13.1
    container_name: db
    environment:
      POSTGRES_USER: "root"
      POSTGRES_PASSWORD: "root"
      POSTGRES_DB: "dev"
    ports:
      - "5432:5432"
    volumes:
      - dbvol:/var/lib/postgresql/data
      - ./forDocker/db/initdb:/docker-entrypoint-initdb.d

volumes:
  dbvol:

PostgreSQL DB準備

DBに初期データを登録します。こちらは以下記事のデータをお借りさせて頂きました。

まずは初期データ登録用のディレクトリとSQLファイルを作成します。

terminal
$ mkdir -p forDocker/db/initdb
$ touch forDocker/db/initdb/1_create_users.sql
$ touch forDocker/db/initdb/2_insert_users.sql
$ touch forDocker/db/initdb/3_create_role_appuser.sql
forDocker/db/initdb/1_create_users.sql
CREATE TABLE users (
  id SERIAL,
  name VARCHAR(255) NOT NULL,
  PRIMARY KEY (id)
);
forDocker/db/initdb/2_insert_users.sql
INSERT INTO users (
  name
) values ( 
  'test'
);
forDocker/db/initdb/3_create_role_appuser.sql
CREATE ROLE appuser WITH LOGIN PASSWORD 'apppass';
GRANT SELECT,UPDATE,INSERT,DELETE ON ALL TABLES IN SCHEMA public TO appuser;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO appuser;

ファイル名の順番(1 → 2 → 3)に処理を実行します。

今回はテストデータなので簡易的ですが、実際にWebアプリケーションを作成していく場合はテーブル定義をよく検討した上で作成することになると思います。

プロジェクト作成

次にGradleプロジェクトを作成します。今回は spring initializr を使用します。

image.png

左側の Aritfactdemo -> app に変更しました。
連動して NamePackage name も変更されます。便利ですね。

また、右側の Dependencies は計7つ追加しています。

  • Spring Web
  • Spring Boot DevTools
  • Lombok
  • Docker Compose Support
  • Thymeleaf
  • Spring Data JPA
  • PostgreSQL Driver

全て入力・追加が完了したら、画面下部の GENERATE ボタンを押下します。
押下後すぐにダウンロードが開始すると思います。

ダウンロードしたzipファイルを解凍し、appフォルダの中身全てを server フォルダ内に移動させます。

image.png

次に application.properties を編集します。

server/src/main/resources/application.properties
spring.datasource.url=jdbc:postgresql://db:5432/dev
spring.datasource.username=appuser
spring.datasource.password=apppass
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=none

Entity & Repository 作成

DBへアクセスする場合、Spring Data JPAによってEntityとRepositoryを作成することで接続が可能です。
こちらは以前自身の記事でも紹介しましたね。

$ mkdir server/src/main/java/com/example/app/entity
$ touch server/src/main/java/com/example/app/entity/User.java
$ mkdir server/src/main/java/com/example/app/repository
$ touch server/src/main/java/com/example/app/repository/UserRepository.java

まずEntityを作成します。

server/src/main/java/com/example/app/entity/User.java
package com.example.app.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "users")
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;

  protected User() {}

  public User(String name) {
    this.name = name;
  }

  public Long getId() {
    return id;
  }

  public String getName() {
    return name;
  }

  @Override
  public String toString() {
    return String.format("{id:%d,name:%s}", id, name);
  }
}

1点注意が必要な部分として import が挙げられます。

SQLの章でご紹介した以下の記事内では javax から import を行っています。

server/src/main/java/com/example/app/entity/User.java
package com.example.app.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "users")
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;

  protected User() {}

  public User(String name) {
    this.name = name;
  }

  public Long getId() {
    return id;
  }

  public String getName() {
    return name;
  }

  @Override
  public String toString() {
    return String.format("{id:%d,name:%s}", id, name);
  }
}

上記のままでは後のビルド時にエラーが出ます。

こちらはSpring Bootが3系に移行するにあたり、名前空間の変更 が必要になったことが理由です。

公式ブログでも以下のように紹介されています。

_Even more importantly, there might be some changes required in your application source code: e.g. the javax to jakarta namespace change in Jakarta EE 9 wherever you're touching the Servlet API, JPA, Bean Validation, etc.

さらに重要なこととして、アプリケーションのソースコードに変更が必要になるかもしれません。例えば、サーブレットAPI、JPA、Bean Validationなどを触っているところでは、Jakarta EE 9でjavaxからjakartaへの名前空間の変更があります。

- import javax.persistence.Entity;
+ import jakarta.persistence.Entity;

上記のように javax の部分を jakarta に全て変更しておきましょう。

続いてRepositoryを作成します。

server/src/main/java/com/example/app/entity/User.java
package com.example.app.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.app.entity.User;

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
}

Controller作成

続いてControllerを作成します。こちらも参考記事からお借りしました。

$ mkdir server/src/main/java/com/example/app/controller
$ touch server/src/main/java/com/example/app/controller/UserController.java
server/src/main/java/com/example/app/controller/UserController.java
package com.example.app.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.app.repository.UserRepository;

@RestController
public class UserController {

  private final UserRepository repository;

  @Autowired
  public UserController(UserRepository repository) {
    this.repository = repository;
  }

  @RequestMapping("/")
  public String user() {
    return String.valueOf(repository.findAll());
  }
}

コンテナ起動 & 動作確認

一通り準備が完了したので、コンテナを起動して動作確認してみます。

terminal
# コンテナをバックグラウンドで起動
$ docker compose up -d

# コンテナに入る
$ docker compose exec app bash

# buildする
bash-4.4# sh gradlew build

ここまで入力すると、おそらく以下のエラーが表示されるかと思います。

terminal
bash-4.4# sh gradlew build

xargs is not available

解決方法が以下の記事中に紹介されています。

bashに microdnf install findutils と入力することで解決するようです。

terminal
bash-4.4# microdnf install findutils

実行すると、以下のように Complete.が表示されていればOKです。

terminal
bash-4.4# microdnf install findutils
Downloading metadata...
Downloading metadata...
Package                                                                                                                                       Repository                                              Size
Installing:
 findutils-1:4.6.0-20.el8.x86_64                                                                                                              ol8_baseos_latest                                   540.6 kB
Transaction Summary:
 Installing:        1 packages
 Reinstalling:      0 packages
 Upgrading:         0 packages
 Obsoleting:        0 packages
 Removing:          0 packages
 Downgrading:       0 packages
Downloading packages...
Running transaction test...
Installing: findutils;1:4.6.0-20.el8;x86_64;ol8_baseos_latest
Complete.

再度コマンドを入力していきます。
build からですね。

terminal
bash-4.4# sh gradlew build
BUILD SUCCESSFUL in 2m 7s
7 actionable tasks: 7 executed

# buildしたjarファイルが存在するか確認
bash-4.4# ls build/libs/
app-0.0.1-SNAPSHOT-plain.jar  app-0.0.1-SNAPSHOT.jar

# jarファイルを実行
bash-4.4# java -jar build/libs/app-0.0.1-SNAPSHOT.jar

ここまで実行が完了したら、http://localhost:8080/ にアクセスします。

image.png

このような画面が表示されていればOKです!お疲れ様でした!

参考

おわりに

いかがでしたでしょうか。
今回はDockerを使用してSpring Boot × PostgreSQLの環境構築を行いました。

ローカル環境を汚さない & Visual Studio Codeでコードが書けるというメリット尽くしなので、eclipseもう飽きた!って人はおススメですね。

それではまた!:wave:

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3