환경에 따라 properties 파일 분리 및 빌드하기
로컬, 테스트, 개발, 운영 환경마다 설정 값이 다를 때가 많다.
대표적으로 각 환경마다 사용하는 데이터베이스가 다를 수 있다. 로컬에서 실행할 때 개발 서버에 배포할 때 등 다양한 상황마다 한 설정 파일에서 값들을 바꾸는 작업은 매우 귀찮다. 이는 둘째치고 실수를 유발하기 좋은 지점이다.
스프링부트를 통해 프로젝트를 실행하면 기본적으로 제공해주는 기능이 있다.
어떤 명령 없이 프로젝트를 실행할 경우 default 프로파일 application.properties 를 읽는다.
테스트를 수행할 때는 test 패키지 내부 resources/application.properties 를 읽는다.
남은건 개발 혹은 운영 서버에 필요한 배포 파일이다. 우선 조금의 리스크는 있지만 가장 간단한 방법이다.
우선 위처럼 src/main/resources 내부에 application-{환경}.properties 로 설정 파일을 만들자.
그리고 파일 내부에는 spring.profies.active 변수를 설정해주자.
spring.profiles.active=dev
그리고 빌드를 수행한다. 윈도우 기준
./gradlew build
빌드가 정상적으로 수행되면 build/libs 내부에 jar 파일이 생길 것이다.
터미널에서 다음과 같은 명령을 주어 jar 파일을 실행시켜보자
java -jar ./build/libs/{프로젝트 명}-0.0.1-SNAPSHOT.jar
프로젝트를 실행하면서 default 프로파일이 읽히는 것을 알 수 있다.
이제 그럼 다음과 같이 명령을 주어 jar 파일을 실행시켜보자
java -jar ./build/libs/{프로젝트 명}-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
이를 통해서 프로젝트를 실행할 때 마다 매번 설정 파일을 열어 변수 값을 변경할 일을 줄일 수 있다.
위 방법은 편리하긴하나 조금 문제가 생길수도 있다.
왜냐하면 빌드를 수행할 때 application.properties 를 기준으로 하기 때문이다. 그렇기 때문에 실제 개발 서버에서 다른 설정 파일을 적용하면 에러가 발생할 수도 있을 것 같다.(내 생각이다. 그런데 CI/CD를 하면서 이럴 때가 많았기 때문에... 일어날 것이라고 생각한다.)
build.gradle 내부에 task를 추가하자.
task configureBootJar {
dependsOn test
doLast {
bootJar {
if (project.hasProperty('devProfile')) {
configurations.runtimeClasspath.getFiles().each { file ->
from(zipTree(file)) {
includeEmptyDirs = false
include "application-dev.properties"
}
}
} else {
configurations.runtimeClasspath.getFiles().each { file ->
from(zipTree(file)) {
includeEmptyDirs = false
include "application.properties"
}
}
}
}
}
}
bootJar {
enabled = false
dependsOn configureBootJar
}
이제 터미널에 아래와 같이 명령을 하자. -P는 Gradle 에서 속성을 정의하는 옵션이다.
./gradlew build -PdevProfile
이렇게 하면 application-dev.properties 를 기준으로 빌드한다.
마지막으로 우분투 OS 기준으로는 spring.profiles.active 대신 spring.config.name 변수를 사용하면 되는 것 같다.
java -jar {프로젝트 명}-0.0.1-SNAPSHOT.jar --spring.config.name=application-dev
명령을 내려보면 아래처럼 dev properties 파일이 적용된다.