Spring BootのProfileを使って環境によって違う設定を安全に切り替える方法
Profileとは何か
Spring BootのProfileは、「今どの環境で動いているか(開発・検証・本番など)」を表すスイッチです。
このスイッチに応じて、Beanの有効/無効や設定値(DB接続先、ログレベル、外部APIのURLなど)を切り替えられます。
たとえば次のような切り替えを安全に行えます。
- 開発ではH2、本番ではPostgreSQL
- 開発では詳細ログ、本番ではINFO中心
- 開発ではモックの外部API、本番では実API
「設定を手で書き換えてデプロイ」みたいな事故を減らせるのが、Profileの大きな価値です。
Profileで何が切り替わるのか
Profileで主に切り替える対象は次の2つです。
- 設定ファイル(application.yml / properties)の値
- SpringのBean定義(@Bean / @Component など)の有効化
設定ファイルをProfileごとに分ける基本
一番よく使うのが、application-<profile>.yml(または.properties)での分割です。
たとえば、以下のように分割することができます。
application.yml(共通)application-dev.yml(開発用)application-prod.yml(本番用)application-test.yml(テスト用)
application.yml(共通)
spring:
application:
name: demo
logging:
level:
root: INFO
application-dev.yml(開発)
spring:
datasource:
url: jdbc:h2:mem:testdb
jpa:
hibernate:
ddl-auto: create-drop
logging:
level:
root: DEBUG
application-prod.yml(本番)
spring:
datasource:
url: jdbc:postgresql://db.prod.example.com:5432/app
jpa:
hibernate:
ddl-auto: validate
logging:
level:
root: INFO
application-test.yml(テスト)
spring:
datasource:
url: jdbc:h2:mem:testdb
jpa:
hibernate:
ddl-auto: create-drop
logging:
level:
root: WARN
ポイントは「共通はapplication.ymlに置き、環境差分だけをprofile側に書く」ことです。
差分が見やすくなり、設定の重複も減ります。
Profileを有効化する方法
Profileの有効化(どれを使うか)はいくつか方法があります。よく使う順に紹介します。
起動引数で指定する
ローカル実行や一時的な切り替えで便利です。
java -jar app.jar --spring.profiles.active=dev
環境変数で指定する
DockerやKubernetesなど、コンテナ運用でよく使います。
export SPRING_PROFILES_ACTIVE=prod
application.ymlで指定する(おすすめしない場面もある)
spring:
profiles:
active: dev
これは「常にdevで動く」状態になりやすいので注意です。
CI/CDや本番デプロイが絡むなら、環境変数やデプロイ設定側で制御する方が安全です。
Gradleでテスト実行時だけ常にtest Profileを有効にする
「./gradlew test でテストを走らせるときだけ、毎回 test Profileにしたい」なら、Gradleのtestタスクにシステムプロパティとして渡すのが簡単です。
Groovy DSL(build.gradle)
tasks.named('test') {
useJUnitPlatform()
systemProperty 'spring.profiles.active', 'test'
}
これで、Gradle経由でテストを実行する限り test Profileが常に有効になります。
環境変数で渡したい場合は次のようにも書けます。
tasks.named('test') {
useJUnitPlatform()
environment 'SPRING_PROFILES_ACTIVE', 'test'
}
Kotlin DSL(build.gradle.kts)
tasks.test {
useJUnitPlatform()
systemProperty("spring.profiles.active", "test")
}
注意点
- この設定は「Gradleの
testタスク」にだけ効きます。bootRunなどには影響しません。 - IDEの「JUnitを直接実行(Gradleを使わない実行設定)」だと、この設定が反映されないことがあります。その場合はIDE側を「Gradleでテスト実行」に切り替えるか、テストクラスに
@ActiveProfiles("test")を付ける方法も検討してください。
ProfileでBeanを切り替える
設定値だけでなく、BeanそのものもProfileで出し分けできます。
@Profileでクラス単位に切り替え
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Profile("dev")
@Component
public class DevOnlyInitializer {
}
このBeanはdev Profileのときだけ登録されます。
@Configuration + @Beanにも使える
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class ClientConfig {
@Profile("dev")
@Bean
public ApiClient mockClient() {
return new ApiClient("http://localhost:8081");
}
@Profile("prod")
@Bean
public ApiClient realClient() {
return new ApiClient("https://api.example.com");
}
}
これで、外部APIクライアントを環境で差し替える、といった構成が作れます。
1つだけじゃないProfileの指定
Profileは複数同時に有効化できます。
--spring.profiles.active=dev,feature-x
この場合、dev と feature-x の両方が有効になります。
「環境」と「機能フラグ」を分ける設計にすると、切り替えがスムーズです。
groupでまとめて有効化する
Profileが増えてくると「devを選ぶと、dev用+ローカル用も一緒にONにしたい」みたいな要望が出ます。
そのときはProfile Groupが便利です。
spring:
profiles:
group:
dev:
- dev
- local
これで spring.profiles.active=dev とすると dev と local がまとめて有効になります。
よくある落とし穴と対策
本番にdev設定で起動してしまう
原因はだいたい次のどれかです。
application.ymlにspring.profiles.active=devを書いている- デプロイ環境で環境変数が設定されていない
- 起動スクリプトが古い
対策としては、「本番は必ずデプロイ設定でSPRING_PROFILES_ACTIVE=prodを明示する」を強くおすすめします。
設定の優先順位がわからなくなる
同じキーが複数箇所にあると混乱します。基本イメージはこうです。
- 「より外側(環境変数や起動引数)」が強い
- 「より具体(profile側)」が強いことが多い
困ったら、起動ログにどのProfileが有効かが出るので、まずそこを確認すると解決が早いです。
application-xxx.ymlが読み込まれていない
Profile名のタイプミスが多いです。
application-prod.ymlを用意したのに--spring.profiles.active=productionで起動している
→ ファイル名とProfile名は一致させる必要があります
開発と運用でのおすすめ構成
迷ったらこの形が扱いやすいです。
application.yml:共通設定application-dev.yml:開発環境の差分application-prod.yml:本番環境の差分application-test.yml:テスト環境の差分- 起動時に
SPRING_PROFILES_ACTIVEを必ず明示(特に本番)
「本番にだけ置くべき値(パスワード、APIキーなど)」は、設定ファイルに直書きせず、環境変数やシークレット管理(Kubernetes Secretなど)で渡すのが安全です。
まとめ
Spring BootのProfileを使うと、環境ごとの設定やBeanを安全に切り替えられます。
application-<profile>.ymlで設定値を分ける--spring.profiles.activeやSPRING_PROFILES_ACTIVEで有効化する@ProfileでBeanを環境ごとに差し替えられる- Gradleの
testタスクでspring.profiles.active=testを渡すと、テスト実行時だけProfileを固定できる - 本番は「必ず明示的にprodを指定」して事故を防ぐ
Profileを活用して、安全に環境を分離してみてください!