はじめに
こんにちは! @Keichan_15 です!
以前 Spring BootとPostgreSQLのローカル環境構築に関するハンズオン を執筆した際に、ちょうどDockerを学んでいたこともあってDockerでも構築できるのかな~って興味本位で調べてみたら、どうやらありました!
今回はそれらを参考にしつつ、Dockerを使用してローカル環境を汚さずに比較的シンプルな構成で環境構築を行っていきたいと思います!
よろしくお願い致します!
環境
- Windows11(Windows10)
- Docker Desktop
準備
任意のディレクトリにフォルダを作成します。
自分は今回 spring_boot
という名前のフォルダを作成しました。
> mkdir spring_boot
> cd spring_boot
この時点でVisual Studio Code
を起動し、Visual Studio Code
内のターミナル上で操作していきます。
> code .
上記コマンドを入力すると、Visual Studio Code
が開きます。
ここまで出来れば準備は完了です!
compose.yamlの作成・編集
続いてcompose.yaml
を作成・編集します。今回はDocker Compose V2に倣って作成していきます。
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ファイルを作成します。
$ 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
CREATE TABLE users (
id SERIAL,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO users (
name
) values (
'test'
);
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
を使用します。
左側の Aritfact
を demo
-> app
に変更しました。
連動して Name
と Package name
も変更されます。便利ですね。
また、右側の Dependencies
は計7つ追加しています。
- Spring Web
- Spring Boot DevTools
- Lombok
- Docker Compose Support
- Thymeleaf
- Spring Data JPA
- PostgreSQL Driver
全て入力・追加が完了したら、画面下部の GENERATE
ボタンを押下します。
押下後すぐにダウンロードが開始すると思います。
ダウンロードしたzipファイルを解凍し、appフォルダの中身全てを server
フォルダ内に移動させます。
次に 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
を作成します。
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.javapackage 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
を作成します。
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
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());
}
}
コンテナ起動 & 動作確認
一通り準備が完了したので、コンテナを起動して動作確認してみます。
# コンテナをバックグラウンドで起動
$ docker compose up -d
# コンテナに入る
$ docker compose exec app bash
# buildする
bash-4.4# sh gradlew build
ここまで入力すると、おそらく以下のエラーが表示されるかと思います。
bash-4.4# sh gradlew build
xargs is not available
解決方法が以下の記事中に紹介されています。
bashに microdnf install findutils
と入力することで解決するようです。
terminalbash-4.4# microdnf install findutils
実行すると、以下のように Complete.
が表示されていればOKです。
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
からですね。
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/ にアクセスします。
このような画面が表示されていればOKです!お疲れ様でした!
参考
おわりに
いかがでしたでしょうか。
今回はDockerを使用してSpring Boot × PostgreSQLの環境構築を行いました。
ローカル環境を汚さない & Visual Studio Codeでコードが書けるというメリット尽くしなので、eclipseもう飽きた!って人はおススメですね。
それではまた!