Spring Bootでapplication.propertiesを外部化する方法を解説する記事のアイキャッチ。Java道場風の空間で若手エンジニアが環境変数とProfileを学ぶイラスト。

Spring

Spring Bootでapplication.propertiesを外部化する方法|環境変数とProfileの優先順位

AIによる要約

Spring Bootの設定は、jar内のapplication.propertiesへ本番値を直接書かず、環境変数やjar外の設定ファイルで上書きできます。開発・検証・本番の共通構造はProfileで分け、パスワードなどの秘密情報は環境変数やシークレット管理へ寄せます。外部ファイルを追加するspring.config.additional-locationと、既定の検索場所を置き換えるspring.config.locationの違いに注意が必要です。

新人SE
新人SE
本番DBの接続先をapplication.propertiesへ書いてjarを作り直すように言われました。普通ですか?
ポンコツSE
ポンコツSE
環境ごとに変わる値はアプリの外から渡せるようにします。特にパスワードをリポジトリへ入れない構成が重要です。

Spring Bootでは、DB接続先、外部APIのURL、タイムアウト、ログレベルなどをapplication.propertiesapplication.ymlへ定義します。しかし、開発環境と本番環境で値が違うたびにソースを変更すると、誤設定や秘密情報の流出につながります。

設定の外部化とは、アプリケーションの成果物を同じままにし、実行環境から値を差し替えられるようにすることです。この記事ではproperties形式を中心に、SIer・SES案件でよく使う環境変数、Profile、jar外ファイルの使い分けを説明します。

この記事のポイント

  • 環境ごとに変わる値をJavaコードへ直書きしない
  • 秘密情報はGit管理する設定ファイルへ入れない
  • Profileは環境別の共通設定、環境変数は実行時の値に向く
  • 外部ファイルの場所と優先順位を運用手順へ明記する

なぜ設定を外部化するのか

設定をJavaコードやjar内だけへ固定すると、値を変えるたびにビルドと再配布が必要です。また、本番パスワードを誤ってGitへコミットすると、履歴から削除する作業まで発生します。

// 避ける: 環境固有値と秘密情報の直書き
String url = "jdbc:postgresql://prod-db:5432/orderdb";
String username = "order_user";
String password = "production-password";

同じjarを開発、検証、本番へ配置し、環境側の設定だけを変えられる構成なら、成果物の取り違えも減らせます。設定値の変更権限を、開発者と運用担当で分けることも可能になります。

方法1: 環境変数から値を受け取る

properties内でプレースホルダーを使うと、OSやコンテナの環境変数から値を受け取れます。

spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}

external.payment.base-url=${PAYMENT_API_URL}
external.payment.timeout=${PAYMENT_API_TIMEOUT:3000}

${PAYMENT_API_TIMEOUT:3000}3000は、環境変数がない場合の既定値です。タイムアウトのように安全な既定値を持てる設定には便利ですが、DBパスワードのような必須値へ安易な初期値を付けるべきではありません。

export DB_URL='jdbc:postgresql://localhost:5432/orderdb'
export DB_USERNAME='order_user'
export DB_PASSWORD='local-password'

java -jar order-app.jar

コマンド履歴やプロセス一覧へ秘密情報を残さないよう、現場の運用方式を確認してください。本番ではクラウドやコンテナ基盤のシークレット管理機能を使うこともあります。

方法2: Profileで環境別ファイルを分ける

開発、検証、本番で設定のまとまりを分けたい場合は、Profile別のファイルを使えます。

src/main/resources/
  application.properties
  application-local.properties
  application-staging.properties
  application-production.properties

# application.properties: 全環境で共通する構造
spring.application.name=order-app
external.payment.timeout=3000

# application-local.properties: ローカル向け上書き
logging.level.com.example.order=DEBUG
spring.datasource.url=jdbc:h2:mem:orderdb

Profileは環境変数や起動引数などで有効化します。

java -jar order-app.jar --spring.profiles.active=production

Profileファイルを使っても、パスワードをapplication-production.propertiesへ直書きしてGit管理すれば安全にはなりません。Profileは設定の分類であり、秘密情報を守る仕組みではない点に注意します。

方法3: jarの外にapplication.propertiesを置く

Spring Bootは、jar内の設定だけでなく、実行時のカレントディレクトリやそのconfigディレクトリなど、外部の標準的な場所から設定ファイルを読み込めます。外部設定はjar内の設定を上書きできます。

/opt/order-app/
  order-app.jar
  config/
    application.properties
cd /opt/order-app
java -jar order-app.jar

どのディレクトリをカレントとしてサービスを起動するかによって、見える設定ファイルが変わります。手作業では動くのにsystemdやジョブ管理から起動すると読めない場合は、実行ユーザー、カレントディレクトリ、ファイル権限を確認します。

additional-locationとlocationの違い

標準以外の場所に設定ファイルを置く場合、spring.config.additional-locationで検索場所を追加できます。

java -jar order-app.jar \
  --spring.config.additional-location=optional:file:/etc/order-app/

optional:を付けると、その場所が存在しなくても起動を継続します。必須設定としてファイルの欠落を検知したいなら、無条件にoptionalを付けず、運用要件に合わせます。

設定動き注意点
spring.config.additional-location既定の検索場所へ追加するjar内や標準外部設定も引き続き使える
spring.config.location既定の検索場所を置き換える指定漏れで通常のapplication.propertiesを読まなくなることがある

既定設定を残して外部設定を足したいだけなら、まずadditional-locationを検討します。

設定値の優先順位を理解する

Spring Bootには複数の設定元があり、後から優先される値で上書きされます。すべての細かな順序を暗記するより、現場でよく使う次の流れを押さえます。

  1. jar内のapplication.propertiesに共通の既定値を書く
  2. jar外のapplication.propertiesで環境固有値を上書きする
  3. 環境変数やJavaシステムプロパティで実行環境の値を上書きする
  4. コマンドライン引数でその起動だけの値を上書きする

Spring Bootの完全な優先順位には、テスト用プロパティやJSON形式の設定なども含まれます。障害調査では推測せず、利用中のSpring Bootバージョンの公式ドキュメントと実際の起動方法を確認してください。

# その起動だけポートを変更する例
java -jar order-app.jar --server.port=9090

@ConfigurationPropertiesで関連設定をまとめる

設定が1つなら@Valueでも読めますが、外部APIのURL、接続時間、読取時間など関連項目が増えたら@ConfigurationPropertiesで型へまとめると管理しやすくなります。

external.payment.base-url=https://payment.example.com
external.payment.connect-timeout=1s
external.payment.read-timeout=3s

@ConfigurationProperties(prefix = "external.payment")
public record PaymentProperties(
        URI baseUrl,
        Duration connectTimeout,
        Duration readTimeout) {
}

型変換されるため、文字列を各Serviceで解析する必要がありません。設定クラスをBean登録する方法はSpring Bootの構成によって異なるため、@ConfigurationPropertiesScan@EnableConfigurationPropertiesなど、プロジェクトの既存方式へ揃えます。

Dockerで環境変数を渡す例

services:
  order-app:
    image: example/order-app:1.0.0
    environment:
      DB_URL: jdbc:postgresql://db:5432/orderdb
      DB_USERNAME: order_user
      DB_PASSWORD: ${DB_PASSWORD}
      SPRING_PROFILES_ACTIVE: production

Composeファイルへ本番パスワードを直接書かず、実行環境からDB_PASSWORDを渡す形にしています。ただし、環境変数なら無条件に安全という意味ではありません。閲覧権限、デプロイログ、障害調査時の出力を含め、基盤側の管理方法を確認します。

よくある「設定が反映されない」原因

  • 環境変数を設定したシェルと、アプリを起動したサービスの実行環境が違う
  • 有効なProfile名とファイル名が一致していない
  • 外部ファイルを置いたが、カレントディレクトリが想定と違う
  • spring.config.locationで既定の検索場所を置き換えてしまった
  • より優先度の高いコマンドライン引数や環境変数が残っている
  • プロパティ名のタイプミスで別の設定として扱われている
  • 設定ファイルの読取権限が実行ユーザーにない

値をログへ出して確認したくなりますが、パスワードやトークンを出力してはいけません。接続先ホスト、Profile名、設定ファイルの配置場所など、秘密ではない情報から切り分けます。Actuatorの設定公開機能も、アクセス制御なしで外部公開しないようにします。

現場での設定管理ルール例

設定の種類置き場所の例
全環境共通の既定値jar内application.properties
開発用の非機密設定application-local.properties
本番の接続先や運用値jar外設定、環境変数
パスワード・APIキーシークレット管理、権限制御された環境変数
一時的な起動変更コマンドライン引数

設定をどこへ置くかだけでなく、誰が変更するか、変更履歴をどこに残すか、再起動が必要か、切り戻し方法は何かまで運用手順へ書きます。本番障害はコードではなく設定変更から起きることも珍しくありません。

現場レビューでよくある指摘

// レビューコメント例
本番DBのURLがJavaコードへ直書きされています。
application.propertiesへ移し、環境変数で上書きできるようにしてください。

// レビューコメント例
application-production.propertiesにパスワードが含まれています。
Git管理から外し、プロジェクトのシークレット管理方式へ移してください。

// レビューコメント例
spring.config.locationは既定場所を置き換えます。
追加が目的ならadditional-locationでよいか確認してください。

提出・リリース前のセルフチェック

  • 環境固有値をJavaコードへ直書きしていないか
  • 秘密情報がGit履歴や配布jarへ含まれていないか
  • 有効化するProfileと設定ファイル名が一致しているか
  • 外部設定ファイルのパス、権限、実行ユーザーを確認したか
  • どの設定元が最終的に優先されるか説明できるか
  • 設定変更と切り戻しの手順が文書化されているか

Spring Boot設定を体系的に学ぶ参考書

設定ファイルだけを断片的に覚えるより、Bean登録やDIを含めたSpring Bootの起動構造と一緒に学ぶと、なぜ値が反映されないかを追いやすくなります。

書籍「作って学ぶ Spring Boot入門」の表紙
商品画像:Amazon.co.jp
PR Java新人・若手向け

作って学ぶ Spring Boot入門

多田 真敏 (著)

Spring Bootを、動くWebアプリを作りながら覚える。

Controller、画面、DB連携などを一つのアプリとして実装できます。Java基礎からSpringの現場へ進む橋渡しに向く一冊です。

  • Spring Bootを手を動かして学びたい
  • Webアプリ開発の流れをつかみたい

当サイトはAmazonアソシエイト・プログラムの参加者です。価格・在庫・配送条件はAmazonでご確認ください。

この記事とあわせて読みたい

まとめ

Spring Bootでは、jar内のapplication.propertiesに共通の既定値を置き、環境変数、Profile、jar外ファイルで環境固有値を上書きできます。秘密情報はソース管理へ含めず、現場のシークレット管理方式へ寄せます。

設定が反映されないときは、Profile名、外部ファイルの場所、実行ユーザー、優先度の高い設定元を順番に確認します。spring.config.locationspring.config.additional-locationの違いも、起動手順へ明記しておきましょう。

-Spring
-, , , ,