[Springboot] 배포 환경 별로 설정파일 분리하기(feat. gradle)

Bobby·2021년 9월 14일
5

즐거운 개발일지

목록 보기
7/22
post-thumbnail

프로젝트 환경 분리하기

  • 설정 파일을 local(로컬), dev(개발), prod(운영) 세가지 환경에 맞추어 분리 해보자.
  • Spring profile, Gradle(Maven) profile 대해 araboza.

프로젝트 생성

  • spring initializer : springboot 2.5.4
  • dependency
implementation 'org.springframework.boot:spring-boot-starter-web'

1. Spring Profile

  • Spring Profile은 런타임 시 지정한 profile 값에 따라서 각 설정 파일을 로드 하도록 할 수 있다.
  • 스프링 부트에서는 기본적으로 실행 시 resource 폴더에서 application.properties(yml)를 찾아 로드한다.
  • 다음으로 profile 값이 있다면 application-${profile}.properties(yml) 파일을 찾아 로드한다.
  • 설정 파일 내부의 설정 값들은 가장 마지막에 로드한 값으로 오버라이드 된다.
  • profile 값을 넘겨주지 않으면 기본 값은 default 이다.

application.yml

  • application.yml을 가장 먼저 로드 하므로 공통으로 사용할 설정 값을 지정 하거나 기본값(local)을 설정하고 profile 값이 있다면 다음 설정 파일에서 오버라이드 해서 사용 할 수도 있다.
  • 개인적으로 명확한 분리를 위해서 공통 값만 사용하는 것이 좋은 것 같다.
  • profile 기본 값을 local로 설정 하기 위해 profile 값을 local로 지정 한다.
spring:
  profiles:
    active: local

common: common
test: common

application-local.yml

test: local

application-dev.yml

test: dev

application-prod.yml

test: prod

LogApplication.java

  • 애플리케이션 실행 시 common, test값을 출력해 보자
@SpringBootApplication
public class LogApplication {

    @Value("${common}")
    private String common;

    @Value("${test}")
    private String test;

    public static void main(String[] args) {
        SpringApplication.run(LogApplication.class, args);
    }

    @PostConstruct
    private void start() {
        System.out.println("common = " + common);
        System.out.println("test = " + test);
    }
}

빌드 및 실행

./gradlew bootJar
  • 빌드 후 모든 설정파일이 컴파일 된 것을 확인 할 수 있다.
  • jar 실행 시 지정한 profile 값에 따라서 각 파일이 로드 된다.

  • 기본 값으로 실행
    • application.yml, application-local.yml 파일이 로드
    • 후에 로드된 application-local.yml 파일의 test 값이 우선순위를 가지게 되어 local 출력
java -jar build/libs/log-0.0.1-SNAPSHOT.jar

  • profile 값 지정하여 실행
java -jar -Dspring.profiles.active=local build/libs/log-0.0.1-SNAPSHOT.jar


2. Gradle profile

  • 지금까지는 각 환경에서 모두 필요하지 않지만 모든 설정파일을 컴파일 한 후 실행 시점에서 원하는 값을 로딩 했다.
  • Gradle profile 설정을 하면 각 profile 값에 해당하는 설정 파일만 컴파일 할 수 있다.
  • build.gradle 설정을 추가한다.
  • 기본적으로 컴파일 시 resource 디렉토리에서 리소스 들을 찾지만 찾을 리소스 디렉토리를 추가 한다.
...

// profile의 기본값 local로 설정
ext.profile = (!project.hasProperty('profile') || !profile) ? 'local' : profile

// 리소스 디렉토리 추가
sourceSets {
    main {
        resources {
            srcDirs "src/main/resources-env/${profile}"
        }
    }
}
  • 각 파일을 다음과 같이 옮겨보자.

빌드 및 실행

기본값으로 빌드

./gradlew clean bootjar
  • 로컬 설정 파일만 컴파일 된 것을 확인 할 수 있다.

기본값으로 실행

java -jar build/libs/log-0.0.1-SNAPSHOT.jar

profile 값 지정하여 빌드

./gradlew clean bootjar -Pprofile=dev 
  • dev 파일만 컴파일 된다.

profile 값 지정하여 실행

java -jar -Dspring.profiles.active=dev build/libs/log-0.0.1-SNAPSHOT.jar

profile include

  • profile을 중복해서 사용할 수 있다.
  • 지금까지 profile 별로 컴파일 하여 실행하였다.
  • 만약 dev로 컴파일 하고 jar 실행 할 때 dev값을 넣어 주지 않는다면 기본값이 local이므로 application-dev.yml 파일은 로드 되지 않을 것이다.
  • profile값을 적기 귀찮다면 profile include를 써보자. (배포 환경에서는 배포스크립트를 작성하여 해결 가능..)
  • 구조 변경

application-common.yml

common: common
test: common

application.yml

  • 각각 다음과 같이 변경
  • 공통으로 들어갈 설정값은 application-common에 넣는다.
spring:
  profiles:
    include: common
    active: dev(or local or prod)

test: dev(or local or prod)

빌드 및 실행

./gradlew clean bootjar -Pprofile=dev
  • 다음과 같이 컴파일 되었다.

  • 실행

java -jar build/libs/log-0.0.1-SNAPSHOT.jar

  • 실행 결과 profile값이 common, dev 둘다 적용되었다.
  • 주의할 점이 있다면 application.yml이 실행되고 include된 application-common.yml의 우선순위가 높기 때문에 test값이 common 이 출력되었다.
  • common에는 중복값이 없도록 하는 것이 좋겠다..

Gradle을 잘 다루면 Gradle 설정으로 디테일 하게 원하는 대로 빌드가 가능할 것 같다.

profile
물흐르듯 개발하다 대박나기

1개의 댓글

comment-user-thumbnail
2023년 7월 7일

안녕하세요.
application.yml을 가장 먼저 로드 하는 것이 아니라 bootstrap.yml을 가장 먼저 로드 하고 그 다음
application.yml을 로드하는 것이 아닌가요?

답글 달기