본문 바로가기
개발

Spring Boot(Kotlin) — 10편. application.yml 프로필 분리 (local/dev/prod)

by 새싹 아빠 2025. 11. 27.

이번 글에서는 Spring Boot 멀티 모듈 기반 프로젝트에서 프로필(Profile)을 활용해 환경별 설정(local/dev/prod)을 분리하는 방법을 정리합니다.
프로필 분리는 실무 백엔드 프로젝트에서 거의 필수이며, 운영 환경과 개발 환경의 설정이 섞이지 않도록 하는 매우 중요한 개념입니다.

 

📌 Spring Boot(Kotlin) 기본 셋팅 — 전체 시리즈

  1. 왜 멀티 모듈 구조인가? (아키텍처 철학 & 전체 설계 편)
  2. API Response 포맷 설계
  3. 글로벌 예외 처리(GlobalExceptionHandler)
  4. Swagger(OpenAPI) 설정
  5. Security(JWT) 기본 골격
  6. JWT TokenProvider
  7. Redis 설정
  8. Validation 설정
  9. Logging + MDC(traceId) 설정
  10. application.yml 프로필 분리 (local/dev/prod) ← 지금 글
  11. 멀티모듈 + JPA 기본 구조 정리
  12. 완성된 프로젝트 템플릿 git 공유

 

✔ 왜 프로필(Profile) 분리가 필요한가?

백엔드 애플리케이션은 환경마다 서로 다른 설정값을 필요로 합니다.
예를 들어,

  • 로컬 개발 환경(local) → 로컬 DB, 로컬 Redis
  • 개발 서버(dev) → 개발용 DB, 개발용 JWT 키
  • 운영 서버(prod) → 운영 DB, 운영 보안 설정

이를 하나의 application.yml에 모두 넣어버리면 다음과 같은 문제가 발생합니다:

  • 운영용 비밀번호/보안키가 로컬 코드에 섞여 보안 위험 발생
  • 로컬에서 테스트하는데 dev 또는 prod 설정 적용 → 장애 발생 가능
  • 환경별 설정 차이를 관리하기 어려움

따라서 Spring Boot에서는 프로필(profile)을 사용해 설정 파일을 분리하는 것을 강력히 추천하며, 실무에서는 거의 필수적으로 local/dev/prod 3단계를 구분합니다.

 

✔ application.yml 기본 구조

기본 application.yml은 “공통 설정”과 “기본 활성 프로필” 정도만 포함합니다.

application.yml
server:
  port: 8080

spring:
  profiles:
    active: local  # 기본은 local 환경

logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [traceId=%X{traceId}] [eventId=%X{eventId}] [userId=%X{userId}] [ip=%X{clientIp}] %-5level %logger{36} - %msg%n"

 

여기서는 console 로그 패턴과 기본 프로필(local)만 지정하고 있습니다.


이 로그 패턴은 이전 글에서 정리한 Logging + MDC(traceId) 설정에 맞춰 구성되어 있으며,
traceId, eventId, userId, clientIp 등이 모두 로그에 자동 포함됩니다.

아래는 해당 패턴을 적용했을 때 실제로 출력되는 로그 예시입니다:

2025-02-01 23:10:22 [traceId=ca21ef01] [eventId=ABCD1234] [userId=42] [ip=123.45.67.89] ERROR c.e.a.UserService - [Unexpected Error]
method=com.example.UserService.createUser(L52)
rootCause=java.lang.IllegalStateException: something went wrong

이처럼 traceId와 eventId, userId가 함께 출력되기 때문에 특정 사용자의 요청 흐름을 추적하거나
오류 발생 시 동일한 eventId로 전체 로그를 빠르게 검색하는 것이 훨씬 쉬워집니다.

 

✔ application-dev.yml — 개발 서버 설정

application-dev.yml

spring:
  config:
    activate:
      on-profile: dev

  datasource:
    url: ${DEV_DB_URL}
    username: ${DEV_DB_USERNAME}
    password: ${DEV_DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        format_sql: false
    open-in-view: false

jwt:
  secret: ${DEV_JWT_SECRET}

redis:
  host: ${REDIS_HOST}
  port: ${REDIS_PORT}

개발 서버(dev)는 대부분 AWS / GCP / 내부 개발 서버 등에 배포되는 단계입니다.
DB 정보·Redis·JWT 키 등도 개발용 environment variable로 분리되어 있습니다.

 

✔ application-local.yml — 로컬 개발 환경 설정

application-local.yml

spring:
  config:
    activate:
      on-profile: local

  datasource:
    url: ${LOCAL_DB_URL:}
    username: ${LOCAL_DB_USERNAME:}
    password: ${LOCAL_DB_PASSWORD:}
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        format_sql: true
    open-in-view: false

# Base64 encoded dummy key (real secrets should be overridden in dev/prod)
jwt:
  secret: dGVtcG9yYXJ5LXNlY3JldC1rZXktZm9yLWxvY2FsLWRldg==

redis:
  host: localhost
  port: 6379

로컬에서는 편의를 위해:

  • format_sql = true → SQL 로그 보기 쉽게
  • dummy JWT key → 실 서버 키 노출 방지
  • 로컬 Redis/DB 사용

 

✔ application-prod.yml — 운영 서버 설정

application-prod.yml

spring:
  config:
    activate:
      on-profile: prod

  datasource:
    url: ${PROD_DB_URL}
    username: ${PROD_DB_USERNAME}
    password: ${PROD_DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        format_sql: false
    open-in-view: false

jwt:
  secret: ${PROD_JWT_SECRET}

redis:
  host: ${REDIS_HOST}
  port: ${REDIS_PORT}

운영(prod)에서는 다음 기준으로 설정합니다:

  • 운영 DB 정보는 절대 코드에 포함하지 않고 모두 환경 변수로 분리
  • SQL 로그 출력 비활성화(format_sql=false)
  • JWT 키도 운영용 환경 변수 기반
  • Redis, 외부 API 키 등 모두 environment variable 로 관리

 

✔ 프로필 분리 흐름 요약

Spring Boot는 다음 순서로 설정을 읽습니다:

application.yml → 활성 프로필 확인 → 
application-{profile}.yml → 해당 설정 override

예를 들어 prod 환경에서는 다음처럼 실행:

java -jar app.jar --spring.profiles.active=prod

→ application.yml에서 기본 구조 로드 → application-prod.yml로 설정 override

 

✔ 왜 이렇게 분리하는 것이 좋은가?

1) 보안 강화

  • 운영 DB ID/PW, JWT Secret 키가 코드에 절대 포함되지 않음
  • 환경 변수로만 관리하므로 안전함

2) 환경별 설정 충돌 방지

  • local에서 테스트하는데 prod 설정이 적용되는 사고 방지
  • 개발서버(dev) 테스트 중 운영 DB에 영향을 주는 위험 제거

3) 배포 자동화 용이

  • CI/CD 파이프라인에서 프로필만 바꿔 배포 가능
  • 한 프로젝트로 로컬/개발/운영 3가지 환경 모두 대응 가능

4) 유지보수 용이

  • 각 환경의 설정이 명확하게 분리되어 변경 시 실수 줄어듦
  • 팀원 간 협업에도 유리

 

✔ 마무리

application.yml 프로필 분리는 작은 프로젝트에서도 반드시 필요한 구조이며,
운영 환경이 생기는 순간부터 안정성·보안·유지보수 측면에서 큰 차이를 만들어 줍니다.

다음 글에서는 멀티모듈 + JPA 기본 구조를 정리합니다!

 

https://jaemoi8.tistory.com/48

 

Spring Boot(Kotlin) 기본 셋팅 — 11편. 멀티모듈 + JPA 기본 구조 정리

이번 글에서는 Spring Boot 멀티 모듈 프로젝트에서 JPA를 어떤 구조로 배치해야 하는지와초기 셋팅에서 알아두면 좋은 핵심 개념을 정리합니다.특히 본 시리즈는 “기본 서버 셋팅 템플릿”을 만

jaemoi8.tistory.com