Contents
Spring BootとDockerの基礎知識
Spring BootアプリケーションをDockerでデプロイすることで、開発環境と本番環境の不一致や手動設定の煩雑さを解消できます。Dockerはコンテナ技術を活用し、アプリケーションをそのままで動作させるため、移行コストが低く、再現性が高く、運用の一貫性が保たれます。特にJava開発者にとって、Spring Bootの簡単なビルドとDockerの軽量性は相性が良く、デプロイワークフローを簡素化します。
DockerでSpring Bootアプリをデプロイするメリット
以下に、Spring BootアプリケーションをDockerでデプロイする主なメリットを整理しました。
- 再現性: コンテナ内にすべての依存関係を含めることで、開発環境と本番環境が一致します。
- 軽量性: Dockerイメージはアプリケーションのみを含むため、伝統的な仮想マシンよりリソース効率が良いです。
- 運用の一貫性: Docker ComposeやKubernetesとの連携により、複数コンテナの管理が容易になります。
必要な準備(Java環境・プロジェクト構成)
Spring BootアプリをDockerでデプロイするには、以下の前提条件があります:
- Java 17以降の環境(OpenJDKまたはEclipse Temurinなど)
- Spring Bootプロジェクト(MavenまたはGradleでビルド可能な構成)
- Docker DesktopやLinux環境でのDocker CLI
プロジェクト構成としては、src/main/java以下にSpring Bootアプリケーションのコードがあり、pom.xml(Mavenの場合)が存在する状態を想定します。この準備ができていれば、すぐにDockerfileを作成できます。
Dockerfileの作成手順(マルチステージビルド)
Dockerfileは、アプリケーションをコンテナ化するための「レシピ」です。特にマルチステージビルドを使うことで、イメージサイズの削減と安全性の向上が可能になります。以下に、基本構造から具体的な手順までをステップバイステップで説明します。
基本構造と各コマンドの役割
Dockerfileは以下のような構造を持ちます:
|
1 2 3 4 5 6 7 8 9 10 |
FROM openjdk:17-jdk as build-stage COPY . /app WORKDIR /app RUN ./mvnw package FROM eclipse-temurin:21-jre-alpine COPY --from=build-stage /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] |
FROM: ベースイメージを指定。ビルド用とランタイム用のステージを分けることができます。COPY: ローカルのファイルをコンテナ内にコピーします。WORKDIR: 作業ディレクトリを設定します。RUN: コンテナ内でコマンドを実行。ここではMavenでJARファイルをビルドしています。EXPOSE: コンテナが使用するポートを指定。ホストとのマッピングに使われます。ENTRYPOINT: コンテナ起動時に実行されるコマンド。
マルチステージビルドの選定根拠
マルチステージビルドは、開発環境(JDK)と運用環境(JRE)を分離することで、不要なファイル(開発用ツールや依存ライブラリなど)を除去します。結果としてイメージサイズが50%以上削減される場合があります。
サンプルDockerfile比較
| ステージ | ベースイメージ | イメージサイズ(例) |
|---|---|---|
| ビルド用 | openjdk:17-jdk |
500MB |
| ランタイム用 | eclipse-temurin:17-jre-alpine |
100MB |
blockquote
マルチステージビルドは、セキュリティ対策としても効果的です。ランタイムにJDKを含めないことで、不要なコマンドやライブラリのリスクが軽減されます。
JARファイルのビルドとコンテナ化
Spring BootアプリケーションをDockerで実行するには、まずJARファイルを作成し、それをDockerイメージに含めます。この手順はMavenまたはGradleで実施可能です。
Spring Bootアプリを実行可能なJARに変換
以下はMavenを使った例です:
|
1 2 |
mvn clean package |
これによりtarget/your-app.jarが生成されます。Gradleの場合は、以下のコマンドを使用します:
|
1 2 |
./gradlew build |
作成されたJARファイルは、Dockerコンテナ内で直接実行できます。
Dockerイメージのビルドコマンド実行
準備ができたら、以下のようにDockerfileがあるディレクトリで実行します:
|
1 2 |
docker build -t your-springboot-app . |
-tでタグを指定し、コンテナイメージに名前を付与します。.は現在のディレクトリにあるDockerfileを使用することを表します。
ビルドが成功すると、docker imagesコマンドで確認できるようになります。
Docker Composeによる複数コンテナ構成
Spring Bootアプリケーションとデータベース(例: PostgreSQL)を連携させるには、Docker Composeを使うのが効率的です。以下に具体的な手順とyamlファイルの書き方を示します。
DB連携例(PostgreSQLとの接続)
Docker ComposeでSpring BootアプリとPostgreSQLを同時に起動する際は、.envファイルとdocker-compose.ymlを使用します:
|
1 2 3 4 |
DB_HOST=db DB_PORT=5432 SPRING_DATASOURCE_URL=jdbc:postgresql://$DB_HOST:$DB_PORT/mydb |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
version: '3.8' services: db: image: postgres:15-alpine environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb volumes: - db_data:/var/lib/postgresql/data app: build: . ports: - "8080:8080" depends_on: - db environment: SPRING_DATASOURCE_URL: jdbc:postgresql://$DB_HOST:$DB_PORT/mydb SPRING_DATASOURCE_USERNAME: user SPRING_DATASOURCE_PASSWORD: password volumes: db_data: |
servicesで定義するコンテナを指定します。depends_onで依存関係を設定し、アプリケーションがDBが起動した後に実行されるようにします。
サービス定義とネットワーク設定
Docker Composeではデフォルトでブリッジネットワークが自動生成され、コンテナ同士の通信が可能です。上記例のようにdb:5432と接続するだけで、アプリケーション側はIPアドレスを指定せずに済みます。
環境変数・ポートマッピングの設定
DockerでSpring Bootアプリケーションをデプロイする際には、環境変数やポートマッピングの設定が不可欠です。これらはアプリケーションの挙動やホストとの通信に大きく影響します。
.envファイルの使い方
.envファイルを使用することで、Docker Composeやdocker runコマンドで環境変数を簡単に指定できます:
|
1 2 3 4 |
DB_HOST=db DB_PORT=5432 SPRING_DATASOURCE_URL=jdbc:postgresql://$DB_HOST:$DB_PORT/mydb |
このように、環境変数はDocker Composeやアプリケーション内から参照可能です。
コンテナとホスト間の通信設定
ポートマッピングはdocker runやdocker-compose.ymlで指定します:
|
1 2 |
docker run -p 8080:8080 your-springboot-app |
-pオプションでホスト側のポート(左)とコンテナ内のポート(右)をマッピングします。- 上記では、ホストの8080番ポートからアクセスすると、アプリケーションが動作するコンテナにリクエストが飛ぶようになります。
blockquote
ポートマッピングは、セキュリティ上も重要です。必要以上のポートを開けることは避け、最小限に抑えることが推奨されます。
イメージサイズの最適化ポイント
Dockerイメージは軽量であるほど、デプロイや起動が速くなります。ここでは、マルチステージビルド以外にも実践可能な最適化方法を紹介します。
不要なファイルの削除
アプリケーションのJARファイルに含まれない以下のファイルは削除しましょう:
target/以下の一時ファイルやログnode_modules/(Node.jsプロジェクトの場合).git/などの開発用ディレクトリ
例: Dockerfileで不要なファイルを排除するコード
|
1 2 3 |
RUN rm -rf /app/target/*.txt && \ find /app -type d -name '.git' -exec rm -rf {} \; |
ベースイメージ選定のコツ
ベースイメージは、アプリケーションの用途に応じて選びましょう。
| タイプ | 推奨イメージ | 特徴 |
|---|---|---|
| Javaアプリ | eclipse-temurin:17-jre-alpine |
Alpine Linuxなので軽量 |
| 大規模なJavaアプリ | adoptium:21-hotspot |
リソースが多いが安定性が高め |
blockquote
Alpineベースのイメージは軽量ですが、一部のライブラリやツールが含まれていない場合があります。用途に応じて慎重に選ぶことが重要です。
実践課題:Dockerfileを作成してみましょう
ここまでの知識を活かし、実際にSpring Bootアプリケーション用のDockerfileを作成してみましょう。以下の手順に従ってください:
手順1: プロジェクトディレクトリに移動
|
1 2 |
cd your-springboot-project |
手順2: Dockerfileを新規作成
以下のようにDockerfileという名前のファイルを作成し、内容を入力します:
|
1 2 3 4 5 6 7 8 9 10 |
FROM openjdk:17-jdk as build-stage COPY . /app WORKDIR /app RUN ./mvnw package FROM eclipse-temurin:17-jre-alpine COPY --from=build-stage /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] |
手順3: Dockerイメージをビルド
|
1 2 |
docker build -t my-springboot-app . |
実行してみよう!
|
1 2 |
docker run -p 8080:8080 my-springboot-app |
これで、Spring BootアプリケーションがDockerコンテナ内で正常に動作するか確認できます。問題があれば、docker logsコマンドでログを確認してください。