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


Spring Bootでは、DB接続先、外部APIのURL、タイムアウト、ログレベルなどをapplication.propertiesやapplication.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には複数の設定元があり、後から優先される値で上書きされます。すべての細かな順序を暗記するより、現場でよく使う次の流れを押さえます。
- jar内のapplication.propertiesに共通の既定値を書く
- jar外のapplication.propertiesで環境固有値を上書きする
- 環境変数やJavaシステムプロパティで実行環境の値を上書きする
- コマンドライン引数でその起動だけの値を上書きする
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入門
Spring Bootを、動くWebアプリを作りながら覚える。
Controller、画面、DB連携などを一つのアプリとして実装できます。Java基礎からSpringの現場へ進む橋渡しに向く一冊です。
- Spring Bootを手を動かして学びたい
- Webアプリ開発の流れをつかみたい
当サイトはAmazonアソシエイト・プログラムの参加者です。価格・在庫・配送条件はAmazonでご確認ください。
この記事とあわせて読みたい
まとめ
Spring Bootでは、jar内のapplication.propertiesに共通の既定値を置き、環境変数、Profile、jar外ファイルで環境固有値を上書きできます。秘密情報はソース管理へ含めず、現場のシークレット管理方式へ寄せます。
設定が反映されないときは、Profile名、外部ファイルの場所、実行ユーザー、優先度の高い設定元を順番に確認します。spring.config.locationとspring.config.additional-locationの違いも、起動手順へ明記しておきましょう。
