SpringBoot

Spring BootアプリケーションをDockerでデプロイする意義とベストプラクティス

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

なぜDockerがSpring Boot開発者に適しているのか

Dockerは、アプリケーションとその依存関係をコンテナ化することで、「開発環境で動いたものが本番でも動く」という信頼性を提供します。Spring Bootアプリケーションの場合、Javaランタイムやライブラリのバージョン管理が複雑になるため、Dockerを使うことで以下のメリットがあります:

  • 依存関係の明確化:コンテナ内で必要なライブラリや環境変数を一括で定義できます。
  • スケーラビリティ向上:Kubernetesなどと連携させることで、負荷に応じて動的にスケールアウト可能です。
  • セキュリティ強化:非rootユーザーでの実行や、最小限のイメージ構築が可能になります。

ただし、Dockerfile内に環境変数を明記するなどした場合、セキュリティリスクが生じるため注意が必要です。


開発環境と本番環境の一致性の重要性

本番で動作しないコードが開発環境では動くケースはよくあります。Dockerを使うことで、以下のような不一致を防ぐことができます:

ケース 問題点 Dockerでの解決策
JDKバージョンの違い ランタイムエラー発生 Base ImageでJDKバージョンを統一
ファイルパスの相違 ログ出力やファイル操作の障害 コンテナ内での設定を一貫させることで回避

DockerエンジンとJavaランタイムのバージョン管理は、デプロイ前の準備として必須です。環境ごとの差異を解消するには、Dockerfileの作成が第一ステップとなります。


Dockerfileのベストプラクティスとサンプルコード

Spring Bootアプリケーション向けに最適化されたDockerfileは、イメージサイズの最小化やセキュリティ強化に大きく寄与します。以下に記載するテンプレートでは、「非rootユーザーでの実行」や「不要なライブラリの排除」を意識しています。

Base Imageの選定基準

Dockerfileの最初のステップで選ぶBase Imageは、アプリケーションの要件とセキュリティに大きく影響します。

ベースイメージ 特徴 推奨用途
adoptium/openjdk OpenJDKをベースにした軽量イメージ Spring Bootアプリ向けに最適
eclipse-temurin:17-jre 最新Javaランタイムが含まれる 常時起動されるサービス向き
alpine シェルやツールが限られる ミニマルなイメージ構築を目的とする場合

Spring Bootアプリでは、adoptium/openjdk:17-jdkなどの最新版Javaベースのイメージを使うのが一般的です。これは、Java 17のサポート期間が長く、セキュリティパッチも頻繁に提供されるためです。

Layer最適化のポイント

Dockerイメージは「Layer(層)」ごとに構成されており、「一時的な作業や不要なファイルを含むとイメージサイズが膨大になります」。以下のような工夫でリソース効率を向上させましょう:

  1. RUNコマンドのまとめ:複数のRUNをマージしてLayer数を減らす
  2. 非rootユーザーの作成USERディレクティブでrootではないユーザーを作成し、セキュリティを強化
  3. キャッシュ有効活用ADDCOPYで変更が少ないファイル(例:依存関係)を先に配置

以下はSpring Bootアプリ向けのDockerfileサンプルです:

注意点mvn clean packageの実行は、開発環境と本番環境で差異が生じる可能性があるため、CI/CDパイプラインで一括処理するのが推奨されます。以下にCI/CD連携例を示します。

CI/CDとの連携方法(GitLab CI/CD例)

このようにすることで、ローカルでの手動ビルドではなく、自動化された環境で一貫性を保つことができます


マルチステージビルドでイメージサイズを最適化する方法

Dockerfileのマルチステージビルドは、「開発環境と本番環境の分離」に強力な機能です。特に、ローカルでのテストに必要なビルドツールやテストコードを本番環境には含めないことで、「イメージサイズの削減」と「セキュリティの向上」が図れます。

開発環境と本番環境の分離シーン

マルチステージビルドでは、1つのDockerfile内で「複数のBase Imageを指定」し、必要な段階でイメージを切り替えます。以下はその例です:

このようにすることで、「第一ステージで必要なビルドツールやテストコードを含むイメージが第二ステージに残らない」ため、最終的な本番用イメージは非常にコンパクトになります。

実行イメージの最小化戦略

実行イメージでは以下の点に注意します:

  • 非rootユーザーでの実行USER nobodyなどでrootではないユーザーを作成
  • 不要なライブラリの削除apt-get purgeなどで不要なパッケージを削除
  • ファイルの最小限配置:アプリケーションに必要なファイルのみをCopy

本番イメージに余計なツールやライブラリが含まれていると、攻撃面が広がるため、「セキュリティ的には最小限の構成が推奨されます」。


Docker Composeでローカル環境を再現する手順

Docker Composeは、複数コンテナ構成のローカル環境を一括で管理できるツールです。特にSpring BootアプリとMySQLやRedisなどの外部サービスを連携させたい場合に有用です。

サービス定義ファイルの構成例

docker-compose.ymlは以下のように記述します:

この設定により、アプリケーションコンテナ(app)はMySQLとRedisコンテナに依存し、ローカルで動作します。また、「depends_on」によって起動順序が制御され、アプリケーションがデータベース接続前に起動しないようになります。

リンク先サービスとの連携方法

外部サービス(MySQLやRedis)とSpring Bootアプリの連携には、「環境変数をDocker Composeで設定する方法」が有効です。例えば、以下のような設定により、アプリケーションはローカルのMySQLに接続できます:

ポイント:Docker Composeでサービス名(例:db)を指定すると、自動的にDNSレコードが生成され、IPアドレスで接続可能になります。


Kubernetesへのスムーズな移行アプローチ

Kubernetesに移行する際には、Dockerイメージのプッシュ手順やDeployment YAMLファイルの作成が不可欠です。特にセキュリティポリシーを再現することが重要です。

Dockerイメージのプッシュ手順

Kubernetes向けにDockerイメージをプッシュするには、以下のような流れが必要です:

  1. ローカルでビルドdocker build -t myapp:latest .を実行
  2. リポジトリにPushdocker push myregistry/myapp:latestを実行(Docker Hubやプライベートリポジトリ)

注意点:Kubernetesで利用するイメージは、「常に最新バージョンをプッシュし、タグ管理を明確にする必要があります」。

Deployment YAMLファイルの作成ポイント

Deployment YAMLでは、以下の設定が重要です:

この例では、「3つのレプリカを起動」し、外部のConfigMapから環境変数を取得しています。また、ロールアウト戦略として「rolling update(段階的な更新)」を採用するなど、可用性向上につながります。

セキュリティ設定例:Kubernetes Secretに保存されたパスワードやAPIキーを、「envFromで参照することで、Dockerfileに情報を明記する必要がなくなります**。以下に具体的なSecret導入手順を示します。

Kubernetes Secretの導入手順

  1. Secretを作成(YAMLファイルから):
    yaml
    apiVersion: v1
    kind: Secret
    metadata:
    name: app-secret
    type: Opaque
    data:
    DB_PASSWORD: c2VjdXJlZGF0aW5nLmFwcA==

    c2VjdXJlZGF0aW5nLmFwcA==securedata.appのBase64エンコード

  2. DeploymentでSecret参照(YAMLファイルから):
    yaml
    env:

    • name: DB_PASSWORD
      valueFrom:
      secretKeyRef:
      name: app-secret
      key: DB_PASSWORD

上記により、Dockerfileに秘密情報を直接書く必要がなくなります。この方法は本番環境で強く推奨されます。


環境変数管理とセキュリティ強化の実践

Spring Bootアプリケーションでは環境変数を適切に管理し、「プロダクション向けのセキュリティ設定」を導入することが重要です。DockerやKubernetesでも同様な原則が適用されます。

Secrets Managementの実装方法

秘密情報を安全に扱うには、以下のような対応が必要です:

手法 説明 推奨用途
Docker ENV指定 コンテナ起動時に環境変数を設定 ローカル開発やテスト
Kubernetes Secret YAMLファイルで定義し、コンテナに注入 本番環境での運用
外部Secrets Manager(Vaultなど) API経由でシークレット取得 高セキュリティ要求の環境

例として、Docker Composeでの環境変数設定は以下の通りです:

この場合、「.envファイルに以下のように定義しておくことで、実行時に自動で読み込まれます」。

プロダクション向け設定例

プロダクション環境では以下のセキュリティ対策を導入することが推奨されます:

  • 暗号化通信:HTTPSでの接続を強制(SSL証明書をDockerイメージに含める)
  • アクセス制限:KubernetesのNetwork Policiesで外部からの不要なアクセスをブロック
  • ログ出力の最小化:敏感情報(パスワードやトークン)がログに出力されないよう設定

重要:DockerfileにENVで秘密情報を直接記述すると、「docker historyなどで見られてしまうリスクがあります」。このようなケースではKubernetes Secretを利用してください。


スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-SpringBoot