Tech Blog

Spring Boot の active profile を docker-compose と ECS で切り替える設計

Spring Boot Docker AWS ECS

はじめに

Spring Boot アプリを複数の環境で動かすとき、「どのapplication.ymlが適用されているか」を正確に把握することが重要です。

  • ローカル開発: application-local.yml
  • Docker Compose: application-docker.yml
  • AWS ECS(本番): application-prod.yml

この記事は、profile の切り替え設計と、ECSでの設定の渡し方についての記録です。


Spring Boot Profile の基本

application-{profile}.yml という名前のファイルを作ると、そのprofileが有効なときだけ読み込まれます。

src/main/resources/
  application.yml          ← 全環境共通
  application-local.yml    ← ローカル開発用
  application-docker.yml   ← Docker Compose 用
  application-prod.yml     ← 本番(ECS)用

profileの指定方法:

# 起動時に指定
java -jar app.jar --spring.profiles.active=prod

# 環境変数で指定(Dockerフレンドリー)
SPRING_PROFILES_ACTIVE=prod java -jar app.jar

環境ごとの設定ファイル

application.yml(全環境共通)

spring:
  application:
    name: dvd-rental-customer-backend
  datasource:
    driver-class-name: org.postgresql.Driver
  jpa:
    open-in-view: false

server:
  port: 8082

application-local.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost:15433/dvdrental
    username: postgres
    password: postgres
  
  thymeleaf:
    cache: false

logging:
  level:
    com.example: DEBUG

application-docker.yml

spring:
  datasource:
    # Docker Compose のサービス名でDBに接続
    url: jdbc:postgresql://postgres:5432/dvdrental
    username: postgres
    password: postgres

application-prod.yml

spring:
  datasource:
    # 本番DBのURLは環境変数から取得
    url: ${DATABASE_URL}
    username: ${DATABASE_USERNAME}
    password: ${DATABASE_PASSWORD}

logging:
  level:
    root: WARN
    com.example: INFO

重要:本番の機密情報はyamlにハードコードしない。必ず環境変数経由で渡す。


Docker Compose でのprofile指定

# compose.yml
services:
  app:
    image: dvd-rental-customer-backend:latest
    environment:
      SPRING_PROFILES_ACTIVE: docker  # ← ここで指定
      TZ: Asia/Tokyo
    ports:
      - "8082:8082"
    depends_on:
      postgres:
        condition: service_healthy
  
  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: dvdrental
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

ECS(AWS Fargate)でのprofile指定

ECSのタスク定義でコンテナの環境変数を設定します。

CDK での設定例

// cdk/lib/app-stack.ts
const taskDefinition = new ecs.FargateTaskDefinition(this, 'AppTask', {
  memoryLimitMiB: 512,
  cpu: 256,
});

const container = taskDefinition.addContainer('AppContainer', {
  image: ecs.ContainerImage.fromEcrRepository(ecrRepo, 'latest'),
  
  environment: {
    // 環境変数(平文)
    SPRING_PROFILES_ACTIVE: 'prod',
    TZ: 'Asia/Tokyo',
  },
  
  secrets: {
    // 機密情報はSSM Parameter Store から取得
    DATABASE_URL: ecs.Secret.fromSsmParameter(
      ssm.StringParameter.fromStringParameterName(this, 'DbUrl', '/dvd-rental/db-url')
    ),
    DATABASE_USERNAME: ecs.Secret.fromSsmParameter(
      ssm.StringParameter.fromStringParameterName(this, 'DbUser', '/dvd-rental/db-username')
    ),
    DATABASE_PASSWORD: ecs.Secret.fromSsmParameter(
      ssm.StringParameter.fromStringParameterName(this, 'DbPassword', '/dvd-rental/db-password')
    ),
  },
  
  logging: ecs.LogDrivers.awsLogs({
    streamPrefix: 'dvd-rental',
    logGroup: logGroup,
  }),
});

ECS でのprofile確認方法

デプロイ後に正しいprofileが適用されているかを CloudWatch Logs で確認します。

Spring Boot は起動時に適用中のprofileをログに出力します:

INFO  o.s.b.SpringApplication - The following 1 profile is active: "prod"
INFO  o.s.b.w.embedded.tomcat.TomcatWebServer - Tomcat initialized with port 8082 (http)

"prod" になっていることを確認してからデプロイ完了とする。

# CloudWatch Logs でprofile確認
aws logs filter-log-events \
    --log-group-name /dvd-rental/app \
    --filter-pattern "profiles is active" \
    --region ap-northeast-1

よくあるミス

① Docker Compose でprofileを指定し忘れる

profileを指定しないと default profileが使われます。
application-docker.yml があっても読まれません。

# NG(profileの指定なし)
services:
  app:
    environment:
      TZ: Asia/Tokyo

# OK
services:
  app:
    environment:
      SPRING_PROFILES_ACTIVE: docker  # ← 必須
      TZ: Asia/Tokyo

② ローカルの application-local.yml をDockerイメージに含めてしまう

本番イメージに localhost:15433 などのローカル接続情報が含まれると、意図せず参照されることがあります。

# .dockerignore で除外
src/main/resources/application-local.yml

③ 環境変数の大文字・小文字を間違える

Spring Boot は SPRING_PROFILES_ACTIVE (すべて大文字、アンダースコア区切り)と
spring.profiles.active(ドット区切り)の両方を受け付けます。
Dockerの環境変数では大文字アンダースコア形式を使います。


まとめ

環境profile設定方法
ローカル開発localIDE のRun設定 or JVM引数
Docker Composedockerenvironment: SPRING_PROFILES_ACTIVE: docker
ECS(本番)prodタスク定義の environment
  • 機密情報は application-prod.yml にハードコードせず、環境変数またはSSM経由で渡す
  • デプロイ後は CloudWatch Logs で「active profile」を必ず確認する
  • profile名は環境の数だけ作るのではなく、「ローカル・Docker・本番」の3種類程度にシンプルに保つ

このシリーズの記事マップ

dvdrental 管理アプリと対になるエンドユーザー向けDVDレンタルアプリを作っている話 — Vue 3 + Spring Boot の全体構成と記事マップ
PostgreSQL のサンプル DB dvdrental をベースに Spring Boot + Thymeleaf で DVD レンタル管理アプリを作った話

気軽にメッセージください

技術相談・ご感想・ご質問があればメッセージをお願いします。