Docker 環境で Spring Boot Webサービスを起動する
こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu 24.04 の Docker 環境で Spring Boot Web アプリケーションをコンテナーとして起動する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
ローカル環境の Ubuntu の Docker 環境で、Dockerfile からビルドした Spring Boot Web サービスのカスタムコンテナーを起動します。
JAR ファイル形式のアプリをコンテナーとして起動
実行環境
要素 | 概要 |
---|---|
terminal | ターミナル |
Ubuntu | OS |
Docker | コンテナー実行環境 |
Web サービス コンテナー
要素 | 概要 |
---|---|
app-hello-spring-boot | カスタムコンテナー |
JVM | Java 実行環境 |
app.jar | Java アプリケーション |
tomcat | Web サーバー |
Spring Boot では、コマンドで簡単にコンテナイメージを作成できる機能があります。しかし、この記事では Dockerfile を使用してコンテナイメージをビルドすることで、Docker の基礎的な使い方を学習することを目的としています。ご注意ください。
技術トピック
Dockerfile とは?
こちらを展開してご覧いただけます。
Dockerfile
Dockerfile は、Docker コンテナーを構築するためのテキストファイルです。Docker コンテナーはアプリケーションやサービスを実行するための環境を含む軽量でポータブルな仮想化ユニットです。
キーワード | 内容 |
---|---|
スクリプト形式 | Dockerfile はシンプルなスクリプト形式で記述されるため、コンテナーのビルドプロセスを自動化することが容易です。 |
レイヤー構造 | Docker イメージは Dockerfile の各命令が実行される際にレイヤーとして生成され、再利用やキャッシュが可能な構造となっています。 |
バージョン管理 | Dockerfile はテキストベースであるため、コードと同様にバージョン管理システムで管理しやすいです。 |
ポータビリティ | Dockerfile により、アプリケーションとその依存関係が1つのコンテナイメージにパッケージ化されるため、異なる環境間での移植性が高まります。 |
自動化と効率化 | Dockerfile を使用することで、アプリケーションのビルドや環境構築を自動化できます。これにより、手動での作業時間やヒューマンエラーが減り、開発・デプロイプロセスが効率的になります。 |
再現性 | Dockerfile はビルド手順を完全に定義するため、異なる環境で同じアプリケーションを再現できます。これにより、開発、テスト、本番環境間での一貫性が確保されます。 |
環境の分離 | Docker コンテナーはホストシステムから分離されるため、アプリケーションの依存関係やライブラリの衝突を回避し、より安全な環境で実行できます。 |
拡張性 | Dockerfile を使用することで、カスタムイメージを作成できます。このため、特定のニーズに合わせてカスタマイズされたコンテナイメージを容易に作成できます。 |
開発環境
- Windows 11 Home 23H2 を使用しています。
WSL の Ubuntu を操作しますので macOS の方も参考にして頂けます。
WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl --version
WSL バージョン: 2.2.4.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.61
Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04 LTS
Release: 24.04
Codename: noble
Java JDK ※ こちらの関連記事からインストール方法をご確認いただけます
$ java -version
openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment (build 11.0.24+8-post-Ubuntu-1ubuntu324.04.1)
OpenJDK 64-Bit Server VM (build 11.0.24+8-post-Ubuntu-1ubuntu324.04.1, mixed mode, sharing)
Maven ※ こちらの関連記事からインストール方法をご確認いただけます
$ mvn -version
Apache Maven 3.8.7
Maven home: /usr/share/maven
Java version: 11.0.24, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker --version
Docker version 27.0.3, build 7d4bcd8
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法をはじめて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
作成する Web アプリケーションの仕様
No | エンドポイント | HTTPメソッド | MIME タイプ |
---|---|---|---|
1 | /api/data | GET | application/json |
/api/data というエンドポイントに対して HTTP GET リクエストを送信すると、JSON データがレスポンスされるシンプルな Web サービスを実装します。
{"message":"Hello World!"}
Hello World を表示する手順
Spring Boot Web サービスの作成
こちらの関連記事で手順がご確認いただけます。
プロジェクトフォルダーに移動
プロジェクトフォルダーに移動します。
※ ~/tmp/hello-spring-boot をプロジェクトフォルダーとします。
$ cd ~/tmp/hello-spring-boot
構成を単純にする為に、全ての要素をアプリケーションクラス記述した例
コントローラークラスを削除して、アプリケーションクラスを修正します。
$ rm src/main/java/com/example/springboot/controller/HelloController.java
$ vim src/main/java/com/example/springboot/Application.java
ファイルの内容
package com.example.springboot;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
@RequestMapping("/api")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping("/data")
public Map<String, String> getData() {
Map<String, String> map = Map.of("message", "Hello World!");
return map;
}
}
アプリのビルド
Java アプリをビルドします。
※ target/app.jar が作成されます。
$ mvn clean package
ここまでの手順で、ローカル環境の Ubuntu に JAR ファイル形式のアプリをビルドすることができました。
コンテナイメージの作成
Dockerfile を作成します。
$ vim Dockerfile
ファイルの内容
# from the base image of a jdk 11 container on Ubuntu 20.04.
FROM adoptopenjdk/openjdk11:x86_64-ubuntu-jdk-11.0.18_10-slim
# create a work dir.
WORKDIR /app
# copy a jvm app.
COPY target/*.jar app.jar
# open port 8080 for a jvm app.
EXPOSE 8080
# startup a jvm app.
ENTRYPOINT ["java","-jar","app.jar"]
説明を開きます。
Dockerfile は、コンテナイメージをビルドするために必要な指示を記述したファイルです。
今回の例では以下のようなステップを実行します。
命令 | 内容 |
---|---|
FROM | ベースとなるコンテナイメージを指定します。この場合は、Ubuntu の slim バージョンのイメージを使用しています。 |
WORKDIR | コンテナー内で作業するディレクトリを指定します。ここでは、/app ディレクトリを作成しています。 |
COPY | ホストマシンからコンテナー内にファイルをコピーします。target/*.jar の部分は、target ディレクトリにあるすべての .jar ファイルを指定しています。また、app.jar という名前でコンテナー内にコピーされます。 |
EXPOSE | コンテナーが使用するポートを指定します。ここでは、8080 ポートを指定しています。 |
ENTRYPOINT | コンテナーが起動する際に実行されるコマンドを指定します。この場合は、java -jar app.jar が実行されます。 |
このように Dockerfile を記述し、docker build コマンドでビルドすることで、コンテナイメージを作成できます。
Docker デーモンを起動します。
$ sudo service docker start
* Starting Docker: docker [ OK ]
Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。
コンテナイメージをビルドします。
$ docker build \
--no-cache \
--tag app-hello-spring-boot:latest .
説明を開きます。
docker build コマンドは、現在のディレクトリにある Dockerfile を使用して、app-hello-spring-boot という名前のコンテナイメージをビルドします。ビルドされたイメージは、Docker ホスト上のローカルリポジトリに保存されます。. は、現在のディレクトリをビルドコンテキストとして使用することを指定します。
コンテナイメージを確認します。
$ docker images | grep app-hello-spring-boot
REPOSITORY TAG IMAGE ID CREATED SIZE
app-hello-spring-boot latest 39115028afa6 12 seconds ago 390MB
説明を開きます。
docker images コマンドは、コンテナイメージのリストを表示します。grep コマンドは、指定された文字列を含む行をフィルタリングします。
ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。
コンテナーを起動
ローカルでコンテナーを起動します。
※ コンテナーを停止するときは ctrl + C を押します。
$ docker run --rm \
--publish 8080:8080 \
--name app-local \
app-hello-spring-boot
説明を開きます。
docker run コマンドで、app-hello-spring-boot というコンテナイメージから、app-local という名前のコンテナーを作成し、ホストの 8080 ポートとコンテナーの 8080 ポートをマッピングします。つまり、ホストの 8080 ポートからアクセス可能なコンテナーが作成されます。
ここまでの手順で、ローカル環境の Docker でアプリのカスタムコンテナーを起動することができました。
コンテナーの動作確認
別ターミナルから curl コマンドで確認します。
$ curl -v http://localhost:8080/api/data -w '\n'
出力
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /api/data HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Fri, 09 Aug 2024 23:17:58 GMT
<
* Connection #0 to host localhost left intact
{"message":"Hello World!"}
ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することができました。
コンテナーの状態を確認してみます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
377111ffea02 app-hello-spring-boot "java -jar app.jar" 4 minutes ago Up 3 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp app-local
説明を開きます。
docker ps コマンドは、現在実行中のコンテナーの一覧を表示します。実行中のコンテナーの情報には、コンテナーID、コンテナー名、使用しているイメージ、ポートマッピング、作成された時間、状態などが含まれます。
コンテナーに接続
別ターミナルからコンテナーに接続します。
$ docker exec -it app-local /bin/bash
説明を開きます。
docker exec コマンドで、コンテナー app-local に対して、対話的な bash シェルでコンテナー内部にログインします。-i と -t のオプションは、対話的な操作が可能な状態を作り出します。/bin/bash は、bash シェルを起動するためのコマンドです。
コンテナーに接続後ディレクトリを確認します。
※ コンテナーから出るときは ctrl + D を押します。
# pwd
/app
# ls -lah
total 17M
drwxr-xr-x 1 root root 4.0K Aug 2 00:00 .
drwxr-xr-x 1 root root 4.0K Aug 2 09:07 ..
-rw-r--r-- 1 root root 17M Aug 1 23:46 app.jar
top コマンドで状況を確認します。
top - 10:49:52 up 1:32, 0 users, load average: 0.01, 0.04, 0.01
Tasks: 3 total, 1 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 7763.1 total, 6218.8 free, 668.9 used, 875.5 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 6859.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 6504924 253188 20960 S 0.3 3.2 0:08.18 java
52 root 20 0 7244 3816 3264 S 0.0 0.0 0:00.01 bash
61 root 20 0 9072 3564 3060 R 0.0 0.0 0:00.05 top
コンテナーの情報を表示してみます。
# cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
このコンテナーは Ubuntu をベースに作成されています。つまり、Ubuntu と同じように扱うことができます。
まとめ
WSL Ubuntu の Docker 環境で、Dockerfile からビルドした Spring Boot Web サービスのカスタムコンテナーを起動することができました。
クラウド開発においては、Dockerfile の理解は重要です。自動ビルドツールもありますが、手動で書く必要があるケースもあります。Ubuntu を使うと Linux の知識も身に付きます。最初は難しく感じるかもしれませんが、徐々に進めていけば自信を持って書けるようになります。
どうでしたか? WSL Ubuntu で、Spring Boot Web アプリケーションを Docker 環境でコンテナーとして手軽に起動できます。ぜひお試しください。今後も Java の開発環境などを紹介しますので、ぜひお楽しみにしてください。
推奨コンテンツ
関連記事
ネイティブイメージビルドと比較してみましょう!