Spring Boot設定事故の防ぎ方|profiles/環境変数/秘密情報

Spring Bootの設定まわりは、最初は「application.ymlを書けばOK」で進みます。
でも実際の運用に入ると、次のような事故が起きがちです。

  • ローカルでは動くのに、本番で接続先が違って落ちる
  • どこで値が上書きされたのか分からず、原因調査が長引く
  • APIキーやパスワードが設定ファイルに残ってしまう

こういう事故は、コードの書き方より 設定の置き場所と上書きルール を整理するだけで、かなり減らせます。

目次

設定ファイルの優先順位

Spring Bootは、設定をいろいろな場所から読み込みます。
ポイントは 「後から来たものが上書きする」 というルールがあることです。

代表的な優先順位(上にあるほど強い)は次のとおりです。

  • コマンドライン引数(例:--server.port=9000
  • OSの環境変数
  • application.yml / application.properties(設定ファイル)

「なぜか設定が効かない」場合、だいたいは 別の場所から強い値が入っている のが原因です。

まずは設定ファイルはデフォルトで、環境変数や起動引数で上書きされることを押さえましょう。

複数環境の設定を安全に分ける方法

application.yml / application-{profile}.yml

DB接続先やログレベルなど、環境ごとに変わる値を同じファイルに書くと、
混在して事故が起きやすくなります。

Spring Bootでは、application-{profile}.yml のような profile別ファイル の自動読込機能があります。

以下は例です。

  • application.yml(共通・安全なデフォルト)
  • application-local.yml(ローカル専用)
  • application-prod.yml(本番専用)

application.yml は「どこでも成立する値」だけに寄せると、混乱が減ります。

# application.yml(共通)
spring:
  application:
    name: myapp

server:
  port: 8080

myapp:
  feature:
    new-ui: false  # 安全なデフォルトだけ置く
# application-local.yml(ローカル)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/myapp
    username: myapp
    password: localpass  # ※ローカル限定でも、できれば環境変数に寄せたい
# application-prod.yml(本番)
spring:
  datasource:
    url: jdbc:mysql://prod-db:3306/myapp
    username: myapp
    password: ${DB_PASSWORD} # 本番はファイルに直書きしない

profile別ファイルは 通常のapplication.ymlを上書きして動作します。

profilesの有効化

有効なprofileは spring.profiles.active で指定できます。
設定ファイルでも指定できますし、起動引数でも指定できます。

ただ、運用で事故が少ないのはこの形です。

  • ローカル:SPRING_PROFILES_ACTIVE=local
  • 本番:SPRING_PROFILES_ACTIVE=prod

spring.profiles.active 自体も、他の設定と同様に環境変数や起動引数で上書きされるルールです。

よくある事故:application-prod.ymlに spring.profiles.active を書く

spring.profiles.activeprofile別ファイル側(application-prod.ymlなど)には書けません
「本番用のファイルに本番profileを書く」という発想をするとハマります。

profileの選択は、基本的に 外から渡す。この方針にしておくと混乱しません。

本番での基本運用

jarの外の application.yml を優先される

Spring Bootは、起動時に決まった場所から application.yml を探します。主な場所は次のとおりです。

  • classpath(jarの中)
    • classpath root
    • classpath /config
  • カレントディレクトリ(jarの外)
    • ./
    • ./config/
    • ./config/*/

そして、jarの外にある設定ファイルは、jarの中の設定より後に読み込まれ、上書きできます

なので、運用の基本はこうなります。

  • jarの中:安全なデフォルト(環境に依存しない)
  • jarの外:環境固有の値(本番DB接続先など)

spring.config.location / additional-location で読み込み先を明示できる

設定ファイルの置き場所を固定したい場合、
spring.config.locationspring.config.additional-location が使えます。

ただしこれは 起動のかなり早い段階で参照されるので、
環境変数・システムプロパティ・起動引数で指定する必要があります。

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

秘密情報は「ファイルに残さない」

直書きが危ない理由

APIキーやDBパスワードを application-prod.yml に直書きすると、次の事故が起きやすいです。

  • Gitにコミットされる
  • ログや設定ダンプで漏れる
  • 人の作業でコピーされて広がる

なので本番では、基本方針を次のとおりにします。

  • 秘密情報は環境変数(またはSecret Manager)から注入
  • 設定ファイル側は ${...} 参照にする
spring:
  datasource:
    password: ${DB_PASSWORD}
myapp:
  api:
    key: ${MYAPP_API_KEY}

環境変数は「ドットをアンダースコアにする」

環境変数は myapp.api.key のようなドット区切りが使いにくいことが多いので、
Spring Bootはアンダースコア形式も想定しています。

例:

  • MYAPP_API_KEYmyapp.api.key 相当
  • SPRING_PROFILES_ACTIVEspring.profiles.active 相当

さらに安全に寄せるなら:外部の秘密管理

チーム規模が大きくなると、環境変数だけでも管理が辛くなります。
その場合は、Vaultなど外部の秘密管理に寄せる選択肢もあります。

Spring Boot 2.4以降は Config Data API があり、外部設定を「import」して取り込めます。
Spring Cloud Vaultも spring.config.import を使う方式を採用しています。

ここまでやるかは規模次第ですが、「秘密情報をアプリ配布物に入れない」という方向性だけは、
早めに固めておくと安心です。

「意図しない値」になったときの切り分け

最後に、事故調査で時間を溶かさないためのチェック順を残します。

  1. まず、どのprofileが有効か確認する(SPRING_PROFILES_ACTIVE / 起動引数)
  2. 次に、設定がどこで上書きされ得るか確認する(環境変数・起動引数が最優先)
  3. ./config/ など jar外の設定が紛れ込んでいないか確認する

もしSpring Boot Actuatorを有効化しているなら、
envconfigprops エンドポイントが「なぜその値になっているか」の調査に役立ちます。

まとめ

Spring Bootの設定事故は、設定の置き場所と上書きルールを整理することで大きく減らせます。
Spring Bootでは設定に優先順位があり、環境変数や起動引数など、より強い場所の値が最終的に適用されます。
意図しない値になった場合は、どこから設定が上書きされているかを確認することが重要です。

環境ごとの差分はprofilesで分離し、共通設定は application.yml
環境固有の設定は application-{profile}.yml に分けて管理すると安全です。
profileの選択は設定ファイルではなく、環境変数など外部指定する形にすると運用時の事故を防ぎやすいです。

また、本番環境では設定ファイルをjarの外に置き、環境ごとに上書きすることで柔軟に対応できます。
さらに、APIキーやDBパスワードなどの秘密情報は設定ファイルに直接書かず、
環境変数や外部の秘密管理から読み込む形にしておくと安全です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次