Spring Boot를 배포할 때 spring.profiles.active를 설정하는 방법이 여러 가지라 헷갈릴 때가 많습니다. 특히 -Dspring.profiles.active=prod처럼 -D로 주는 방식은 “좀 더 로우한 곳에 설정하는 것 같다”는 느낌이 드는데, 이 감각은 꽤 정확합니다. 다만 로우 레벨이라고 해서 무조건 우선순위가 가장 높지는 않기 때문에, 동작 원리와 우선순위를 같이 정리해두면 배포 실수가 크게 줄어듭니다.
빠른 체크포인트
- -D…는 Spring 기능이 아니라 JVM 자체 옵션으로, 실행 전에 JVM 레벨에 값을 설정합니다.
- –spring.profiles.active=…는 Spring Boot가 해석하는 애플리케이션 인자입니다.
- 로우 레벨(JVM) 설정이라고 해도 Spring Boot 우선순위에서는 –가 -D를 덮어쓸 수 있습니다.
- 프로파일 설정은 보통 커맨드라인 인자, JVM 옵션, 환경변수, 설정 파일 순으로 사용합니다.
1. JVM 시스템 프로퍼티(System Property)란?
JVM 시스템 프로퍼티는 Java 프로그램이 실행될 때 JVM이 들고 있는 “전역 설정 값”입니다. -D키=값 형태로 전달하면, JVM이 그 값을 보관하고 애플리케이션은 실행 중에 System.getProperty(“키”)로 꺼내 쓸 수 있습니다. 이 방식은 Spring 전용이 아니라 Java 자체 표준 기능이라서, Spring이 아닌 순수 Java 프로그램에서도 동일하게 동작합니다.
예를 들어 아래처럼 실행하면 JVM에 spring.profiles.active=prod가 저장됩니다.
java -Dspring.profiles.active=prod -jar app.jar
Spring Boot는 부팅 과정에서 시스템 프로퍼티를 읽어 prod 프로파일을 활성화합니다.
2. 왜 “로우한 곳에 설정하는 느낌”이 드는가?
-D는 애플리케이션보다 아래인 JVM 레벨에서 처리되기 때문에, 다음 두 가지 이유로 로우 레벨처럼 느껴집니다.
첫째, -D는 JVM이 시작될 때 바로 적용됩니다. 즉, Spring Boot가 실행되기 전부터 JVM 내부에 값이 이미 결정되어 있습니다. 둘째, -D는 Spring Boot 문법이 아니라 Java 실행 옵션입니다. 이 말은 “애플리케이션 옵션이 아니라 런타임 옵션”에 가깝다는 뜻입니다.
정리하면 -D는 “Spring에 지시한다”가 아니라 “JVM이 실행될 때부터 갖고 있는 환경을 만든다”에 더 가깝습니다.
3. -D와 –의 차이(핵심)
Spring Boot에서 프로파일을 주는 방식은 대표적으로 두 가지가 자주 쓰입니다.
3-1) JVM 시스템 프로퍼티로 주기(-D)
java -Dspring.profiles.active=prod -jar app.jar
이 방식은 JVM 전역 설정으로 들어갑니다. Spring Boot는 실행 시점에 이를 읽어서 프로파일을 결정합니다.
3-2) Spring Boot 커맨드라인 인자로 주기(–)
java -jar app.jar --spring.profiles.active=prod
이 방식은 JVM이 아니라 Spring Boot가 실행 후에 파싱하는 애플리케이션 인자입니다. 즉, “Spring Boot가 직접 해석하는 값”입니다.
실무적으로는 둘 다 많이 쓰이지만, –는 Spring Boot에만 의미가 있고, -D는 Java 전반에 통하는 옵션이라는 차이가 있습니다.
4. 우선순위 결론: 로우 레벨이 항상 이기는 건 아니다
직관적으로는 “JVM 레벨이 더 로우하니까 더 강할 것 같다”는 생각이 들 수 있는데, Spring Boot는 보통 실행 시점의 직접 입력을 더 우선시합니다. 그래서 같은 키를 여러 방식으로 주면 커맨드라인 인자(–)가 시스템 프로퍼티(-D)를 덮어쓸 수 있습니다.
예를 들어 아래처럼 주면 최종 프로파일은 prod로 결정됩니다.
java -Dspring.profiles.active=dev -jar app.jar --spring.profiles.active=prod
즉, -D가 더 로우하다는 느낌은 맞지만, Spring Boot의 설정 우선순위에서는 –가 더 강하게 동작할 수 있습니다.
5. 배포에서 추천되는 사용 방식
환경에 따라 실수 확률이 낮은 패턴을 선택하는 게 좋습니다.
- 로컬/단순 실행: –spring.profiles.active=prod 방식이 직관적입니다.
- Docker/쿠버네티스: SPRING_PROFILES_ACTIVE=prod 같은 환경변수가 관리하기 편합니다.
- JVM 레벨 통일이 필요할 때: -Dspring.profiles.active=prod도 안정적인 선택입니다.
중요한 건 한 프로젝트 안에서 “프로파일 주입 방식”을 섞어 쓰면 디버깅이 어려워질 수 있으니, 팀 기준으로 하나를 정해두는 편이 운영에 유리합니다.
정리
JVM 시스템 프로퍼티는 애플리케이션이 아니라 JVM 런타임 레벨에 값을 저장하는 방식이라 “로우한 곳에 설정하는 느낌”이 나는 게 정상입니다. 다만 Spring Boot는 커맨드라인 인자 같은 실행 시점 입력을 더 우선시할 수 있으므로, -D와 –가 동시에 존재할 때는 우선순위에 의해 값이 덮어써질 수 있습니다. 배포에서 중요한 건 어떤 방식이든 한 가지 방식으로 통일하고, 실제 적용된 값을 로그로 확인하는 습관을 만드는 것입니다.