프로젝트를 진행하다 보면 로컬, 개발, 검증, 운영 환경에 따라 DB, 서버 포트, Redis 호스트 주소 등 다양한 설정을 환경에 따라 다르게 적용해야 할 때가 많다. 이러한 처리를 일일이 수동으로 조정하는 것은 매우 번거롭지만, Spring Boot의 Profile 기능을 이용하면, 번거롭게 매번 설정을 수정할 필요 없이 간편하게 환경에 맞는 설정을 적용할 수 있다.
Spring은 하드 코딩을 지양하고, 구현하고자 하는 시스템의 환경에 맞춰 환경 변수를 효율적으로 조정할 수 있는 다양한 방법을 제공한다. 이를 위해 Properties를 설정하고, 필요한 Properties를 로드하여 시스템에 맞는 환경에서 애플리케이션을 기동할 수 있다. 오늘은 개발/검증/운영 환경에 따라 profile을 적절하게 설정하여, 효율적으로 프로퍼티를 가져오는 방법에 대해 알아보자.
application.properties란?
application.properties
란, 스프링 부트가 애플리케이션을 구동할 때 자동으로 로딩하는 파일로, key-value 형식으로 값을 정의한다. 이 파일에 다양한 설정 값들을 저장해놓고, 애플리케이션에서 참조하여 사용할 수 있다. (application.yaml
파일의 형식도 지원한다)
예를 들어 다음과 같이 작성할 수 있다.
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
기본적으로 다음 경로를 찾아 파일을 로드하며, 필요하다면 경로를 직접 지정해줄 수도 있다.
classpath:/
classpath:/config/
file:./
file:./config/
Spring Profile
Spring Boot에서는 런타임 환경을 구분할 수 있는 Profile을 제공한다. 스프링 프로필은 애플리케이션의 다양한 환경(개발,테스트,운영)에 맞춰 설정을 분리하고 관리할 수 있게 해주는 기능이다. 이를 통해 같은 코드 베이스에서 환경 별로 다른 설정을 편리하게 적용할 수 있다. 스프링 프로필을 사용하면 각 환경에 맞는 설정을 쉽게 전환할 수 있다. 예를 들어, 개발 환경에서는 로컬 데이터베이스를 사용하고, 운영 환경에서는 클라우드 데이터베이스를 사용하는 등의 설정을 프로필로 관리할 수 있다. 이는 코드의 재사용성을 높이고 환경 간 전환을 용이하게 만든다.
주요 기능
- 환경 구분 : 각 프로필은 특정 환경을 나타내며, 이를 통해 개발자는 환경에 적합한 설정을 정의할 수 있다.
- 설정 파일 관리 :
application-{profile}.properties
또는application-{profile}.yaml
파일을 사용하여 각 프로필별 설정을 관리한다. (파일 명명은 정해진 형식이다) - 프로필 활성화 : 애플리케이션 실행 시 특정 프로필을 활성화하여 해당 설정을 로드할 수 있다.
실제로도 현재 진행중인 프로젝트에서 다음과 같이 환경에 따라 프로퍼티를 구분하여 작성하고 있다. 공통된 설정은 application.properties
에 작성하고, 각 환경의 설정은 application-{profile}.properties
에 작성하고 있다. (경로 : src/main/resources
)
.
├── application.properties
├── applicaiton-local.properties
├── applicaiton-qa.properties
├── application-dev.properties
└── application-prd.properties
위와 같이 환경 별 프로퍼티를 구성하고 application.properties
에서 spring.active.profiles
값을 설정하면 해당 환경의 설정이 적용된다. 예를 들어 다음은, dev
profile을 활성화하여 적용하는 것이다.
spring.profiles.active=dev
Profile 적용하여 배포하기
IDE를 활용하기
IDE들(대표적으로 IntelliJ)은 똑똑하기 때문에, application.properties
에 spring.profiles.active
를 설정하는 것만으로도 프로필이 적용된다. IDE를 통해 실행한다면, profile 설정이 간단하지만, kubernetes 클러스터에 배포(Dockerfile)하듯이, war 혹은 jar로 말아서 제공하는 경우에는 추가적인 설정(JVM 옵션 지정)이 필요하다.
JAR 구동 방법
jar로 코드를 만 경우에는 다음과 같이 명령줄에 인수를 추가하여 실행한다.
java -Dspring.profiles.active={profile} -jar filename.jar
또한 아래의 WAR 구동 방법도 적용 가능하다.
WAR 구동방법
war로 gradle build한 경우에는, 어떻게 해야하는지 여러 방법들을 살펴보자. (Tomcat 기준)
catalina.sh
설정 (JVM 시스템 속성 사용)
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prod"
setenv.sh
생성 : tomcat 구동 시 실행 환경 설정 파일로, 다음과 같이 파일을 생성 및 작성한다 (JVM 시스템 속성 사용)
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=dev"
- environment 변수 사용
ENV SPRING_PROFILES_ACTIVE=dev
catalina.sh 는 Tomcat 서버를 시작하는 스크립트로, Java 프로세스가 시작될 때 필요한 환경 변수나 JVM 옵션을 설정할 수 있다. Tomcat 을 사용할 때는, 프로필을 명시적으로 설정해주어야 한다.
현재 진행중인 프로젝트는 Spring Boot 애플리케이션을 war로 빌드하여 K8S 클러스터에서 실행시키고 있다. 이런 경우 application.properties
의 spring.active.profiles
설정 뿐만 아니라 추가적인 설정이 필요하다. 현재는 Dockerfile에 JAVA_OPTS
환경 변수를 설정하는 부분을 추가하여, 환경 별로 Docker Image를 빌드하고 있다. 즉, 다음과 같은 형식으로 명령을 수행할 수 있도록 하는 것이다.
ENV JAVA_OPTS="-Dspring.profiles.active=dev"
CMD ["app/sw/was/tomcat/bin/catalina.sh", "run"]
설정이 잘 되었으면, 애플리케이션을 실행했을 때 다음과 같이 로그를 확인할 수 있다.
The following 1 profile is active: "dev"
Reference