스프링 부트 애플리케이션에서 다중 환경 구성을 관리하는 것은 개발, 테스트, 프로덕션 배포에 있어 핵심 요소입니다. 프로파일(Profile) 메커니즘은 이 문제를 해결하는 핵심 도구로, 활성화된 프로파일에 따라 애플리케이션이 동적으로 설정 파일을 로드하여 하드코딩으로 인한 유지보수 문제를 방지합니다.
프로파일 기본 사용법
스프링 부트는 기본적으로 명명 규칙에 따라 설정 파일을 로드합니다. 예를 들어 application-dev.yml, application-prod.yml과 같은 방식입니다. 주 설정 파일인 application.yml에서는 spring.profiles.active를 통해 현재 활성화할 환경을 지정할 수 있습니다.
spring:
profiles:
active: dev
위 설정은 application-dev.yml의 내용을 우선적으로 로드합니다. 지정되지 않은 경우, 기본적으로 application.yml의 공통 설정이 사용됩니다.
다양한 프로파일 활성화 방식
프로파일은 여러 경로를 통해 활성화할 수 있습니다. 일반적인 방법은 다음과 같습니다.
application.yml에서 직접spring.profiles.active설정- JVM 매개변수 사용:
-Dspring.profiles.active=prod - 명령줄 시작 매개변수 사용:
--spring.profiles.active=test - 운영체제 환경변수 설정:
SPRING_PROFILES_ACTIVE=dev
조건부 설정 주입
@Profile 어노테이션을 결합하면 Bean의 조건부 등록이 가능합니다. 예를 들어:
@Configuration
@Profile("dev")
public class DevDataSourceConfig {
// 개발 환경 데이터소스 설정
}
dev 프로파일이 활성화된 경우에만 이 설정 클래스가 로드되어, 환경별 로직을 효과적으로 분리할 수 있습니다.
프로파일 설정 우선순위 예시
| 활성화 방식 | 우선순위 | 설명 |
|---|---|---|
| 명령줄 매개변수 | 최고 | 시작 시 --spring.profiles.active 전달 |
| JVM 시스템 속성 | 높음 | -Dspring.profiles.active=xxx |
| 설정 파일 | 낮음 | application.yml에서 정의 |
설정 파일을 통한 프로파일 활성화 다섯 가지 방법
YAML 다중 문서 블록을 사용한 환경 분리
YAML 설정에서 다중 문서 블록 구분자 ---를 사용하면 여러 환경 간 설정을 효과적으로 분리할 수 있습니다. 각 문서 블록은 논리적으로 독립적이어서 개발, 테스트, 프로덕션 등 여러 환경 설정을 관리하기 용이합니다.
server:
host: localhost
port: 8080
---
server:
host: api.prod.example.com
port: 443
environment: production
위 코드는 두 개의 독립적인 설정 문서를 정의합니다. 첫 번째는 로컬 개발용, 두 번째는 프로덕션 환경용입니다.
application-{profile}.properties를 사용한 외부화 설정
스프링 부트에서 application-{profile}.properties를 통해 환경별 설정을 분리할 수 있습니다. 예를 들어 개발, 테스트, 프로덕션 환경은 각각 application-dev.properties, application-test.properties, application-prod.properties를 사용할 수 있습니다.
// application.properties
spring.profiles.active=dev
다중 환경 설정 구조 예시:
application.properties: 공통 설정application-dev.properties: 개발 환경 데이터베이스 연결application-prod.properties: 프로덕션 환경 보안 매개변수
외부 설정의 우선순위는 내부 설정보다 높으며, 환경변수나 명령줄 매개변수로 기본 설정을 덮어쓸 수 있습니다.
기본 프로파일과 폴백 메커니즘 설계
설정 관리에서 기본 프로파일은 시스템 초기화의 최종 보루 역할을 합니다. 활성 프로파일이 명시적으로 지정되지 않으면 프레임워크가 자동으로 기본 설정 집합을 활성화하여 애플리케이션이 정상적으로 시작되도록 보장합니다.
폴백 메커니즘의 트리거 조건:
spring.profiles.active환경변수가 설정되지 않은 경우- 지정된 프로파일이 존재하지 않거나 로드에 실패한 경우
- 설정 소스 중단(예: 원격 Config Server 연결 불가)
로딩 우선순위 비교표:
| 순서 | 설정 유형 | 우선순위 |
|---|---|---|
| 1 | 활성 프로파일 | 최고 |
| 2 | 폴백 프로파일 | 중간 |
| 3 | 기본 프로파일 | 최저(최후 수단) |
설정 파일 로딩 순서와 우선순위 실전 검증
스프링 부트 애플리케이션 시작 과정에서 설정 파일의 로딩 순서는 최종 설정 결과에 직접적인 영향을 미칩니다. 스프링 부트는 다음과 같은 우선순위(높음에서 낮음)를 따릅니다:
- 명령줄 매개변수
java:comp/env의 JNDI 속성- Java 시스템 속성(
System.getProperties()) - 운영체제 환경변수
- JAR 외부의
application.yml - JAR 내부의
application.yml
명령줄과 JVM 매개변수로 프로파일 활성화 제어
--spring.profiles.active 시작 매개변수 사용
스프링 부트 애플리케이션에서 명령줄 매개변수를 통해 실행 환경을 유연하게 전환할 수 있습니다. 가장 일반적인 방법은 --spring.profiles.active를 사용하여 현재 활성화할 설정 파일을 지정하는 것입니다.
java -jar myapp.jar --spring.profiles.active=prod
이 명령은 애플리케이션 시작 시 application-prod.yml 또는 application-prod.properties의 설정을 로드합니다. 다중 환경 지원 전략으로 개발 환경(dev)에서는 디버그 로그와 핫 리로드, 테스트 환경(test)에서는 테스트 데이터베이스 연결, 프로덕션 환경(prod)에서는 민감한 엔드포인트 비활성화와 캐시 활성화 등을 적용할 수 있습니다.
JVM 시스템 속성 -Dspring.profiles.active의 우선순위
스프링 부트에서 -Dspring.profiles.active는 JVM 시스템 속성을 통해 활성 프로파일을 지정하는 중요한 방법입니다. 그 우선순위는 설정 파일 내 spring.profiles.active 설정보다 높지만, 명령줄 매개변수보다는 낮습니다.
| 설정 방식 | 우선순위 |
|---|---|
명령줄 매개변수 (--spring.profiles.active=dev) | 최고 |
JVM 시스템 속성 (-Dspring.profiles.active=dev) | 중간 |
application.yml의 설정 | 낮음 |
java -Dspring.profiles.active=prod -jar myapp.jar
운영체제 환경변수 및 기타 고급 활성화 방식
OS 환경변수 SPRING_PROFILES_ACTIVE 설정 및 읽기
스프링 부트에서 SPRING_PROFILES_ACTIVE 환경변수는 현재 활성화할 설정 파일을 동적으로 지정하는 데 사용됩니다.
export SPRING_PROFILES_ACTIVE=prod
java -jar myapp.jar
환경변수의 우선순위는 설정 파일 내 정의보다 높습니다. 다음 코드로 현재 활성 프로파일을 확인할 수 있습니다:
@Autowired
Environment env;
String[] activeProfiles = env.getActiveProfiles();
이 메커니즘은 쉼표로 구분된 여러 프로파일(예: SPRING_PROFILES_ACTIVE=dev,security)을 지원하여 설정 조합 재사용이 가능합니다.
ConfigurableEnvironment를 사용한 프로그래밍 방식 프로파일 활성화
스프링 애플리케이션 컨텍스트 초기화 단계에서 ConfigurableEnvironment 인터페이스를 주입하여 프로파일을 동적으로 제어할 수 있습니다. setActiveProfiles() 또는 addActiveProfile() 메서드를 호출하여 컨테이너 시작 전에 활성 프로파일 집합을 미리 설정할 수 있습니다.
@Configuration
public class ProfileConfig {
@Autowired
public void setProfile(ConfigurableEnvironment env) {
env.addActiveProfile("production");
}
}
@ActiveProfiles 어노테이션의 단위 테스트 적용
스프링 부트 프로젝트에서 @ActiveProfiles 어노테이션은 테스트 실행 시 활성화할 설정 파일을 지정하여 다양한 환경에서의 동작을 시뮬레이션하는 데 사용됩니다.
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class UserServiceTest {
// 테스트 코드
}
12요소 앱 원칙에 따른 외부 설정 모범 사례
12요소 앱(12-Factor App) 규칙을 따를 때, 스프링 부트의 외부 설정 관리는 코드와 설정을 엄격히 분리하고 환경변수를 핵심 설정 소스로 사용해야 합니다. 데이터베이스 비밀번호, API 키 등의 민감한 설정은 하드코딩을 피하고 환경변수로 주입하는 것이 좋습니다:
spring:
datasource:
url: ${DATABASE_URL}
username: ${DB_USER}
password: ${DB_PASSWORD}
우선순위 규칙 이해로 설정 혼란 극복
복잡한 시스템에서 설정은 일반적으로 환경변수, 설정 파일, 명령줄 매개변수, 원격 설정 센터 등 여러 소스에서 비롯됩니다. 동일한 매개변수가 여러 곳에서 정의될 때, 우선순위 규칙이 최종 적용 값을 결정합니다. 일반적인 설정 소스 우선순위(높음에서 낮음)는 다음과 같습니다:
- 명령줄 매개변수
- 환경변수
- 로컬 설정 파일 (예:
config.yaml) - 원격 설정 센터 (예: Nacos, Consul)
- 기본 내장 값
일부 프레임워크는 .env 파일을 자동으로 로드하여 의도치 않게 환경변수를 덮어쓸 수 있습니다. 로딩 순서를 명시적으로 제어하고, 시작 로그에 실제 적용된 설정 항목을 출력하여 감사와 디버깅을 용이하게 하는 것이 좋습니다.