본문 바로가기
스프링 (Spring)

[Spring boot] 설정 정보(application.yml / properties) 분리시키기 - spring profiles

by codeyaki 2023. 6. 12.
반응형

사용 이유

현재 진행 중인 프로젝트에서 오라클 클라우드 프리티어를 이용해서 배포 테스트를 진행하게 되었다

현재 application.yml을 서브 모듈 ( https://teching.tistory.com/144 )을 사용해서 관리하고 있는 상황이었다.

 

spring boot 설정 정보 외부에서 관리하기 2 - submodule

https://teching.tistory.com/143 [spring boot 설정 정보 외부에서 관리하기 Spring boot 설정 정보 관리하기 서버를 github를 사용해서 형상관리를 할 생각인데 레파지토리를 public으로 열어두려고 한다... 공개

teching.tistory.com

오라클 클라우드의 DB는 특이하게 지갑을 이용해서 접속해야 하는데 그 경로를 지정해주어야 한다. 예를 들어 DB에 접속하기 위해서라면 아래와 같이 yml을 작성해야 한다.

spring:
  datasource:
    url: jdbc:oracle:thin:@sixteens_low?TNS_ADMIN=./src/main/resources/Wallet_sixteens
    username: exam
    password: example!
    driverClassName: oracle.jdbc.OracleDriver

위와 같이 현재 위치해 있는 지갑의 경로를 지정해주어야 한다.

이를 빌드하여 Docker로 말아야 할 때도 이 경로가 위치한 곳에 지갑을 위치해 두어야 해서 빌드할 때마다 yml을 수정해주어야 해서 매우 불편함을 느꼈고 이를 해결하고자 Spring boot에 있는 profile 기능을 사용해서 해결해보고자 했다.

 

Profiles 적용하기

Spring Profiles는 애플리케이션 구성의 일부를 분리하고 특정 환경에서만 사용할 수 있도록 하는 방법을 제공합니다. 

 

공식 문서에서 가져온 문구인데 지금 내게 딱 필요한 기능이 아닐까 싶었다!  👍🏻

버전은 spring boot 2.4 이상을 기준으로 이전 버전에서 사용되던 profiles 방식은 deprecated 되었다. 이 점 유의해야 한다!

Spring profile은 말 그대로 환경마다 설정을 다르게 적용하고 싶을 때 사용하면 적절한 대안이 될 것 같다.

기본 사용 방법

a. 프로필 설정

1. 파일명 규칙

application-{profile}.yml
  •  (properties)로 파일을 만들 때 profile부분에 원하는 프로필명을 넣어주면 스프링이 시작할 때 스캔을 하면서 application-*. yml을 모두 찾아 config에 저장하게 된다.

2. yml파일 내에서 선언하기

spring:
  config:
    activate:
      on-profile: "프로필명"
  • on-profile을 지정하면 해당 프로필명으로 지정이 되게 된다.
  • ---를 사용해서 한 파일 내에 구역을 나눠 여러 프로필을 지정할 수 있다.
  • 만약 on-profile을 지정하지 않는다면 default로 지정이 된다.
server:
  port: 8080
---
spring:
  config:
    activate:
      on-profile: a
      
server:
  port: 8888

---

spring:
  config:
    activate:
      on-profile: b
      
server:
  port: 9999
  • 아무 프로필을 활성화하지 않는다면 포트가 8080
  • a 프로필 활성화 시 8888, b 프로필 활성화 시 9999 포트로 지정되게 할 수 있다.

b. 프로필 활성화 방법

프로필을 활성화시키는 방법에는 여러 가지가 있는데 이중 세 가지를 소개해보자면

 

1. yml에서 활성화시키기

spring:
  profiles:
    active:
      - 활성화할 profile 명
    group:
      그룹으로 묶을 이름:
        - 활성화 시킬 프로필
      그룹으로 묶을 이름2:
        - 활성화 시킬 프로필
    include:
      - 모든 그룹에 포함시킬 프로필1
      - 모든 그룹에 포함시킬 프로필2
  • active에는 기본적으로 활성시킬 프로필 명을 적어주면 된다.
  • group은 프로필들을 모아 새로운 프로필로 만들어주는 기능을 한다.
  • include는 모든 프로필에 기본적으로 포함시킬 프로필명들을 적어주면 된다. (default에 작성한 것들을 포함할 때 사용한다.)

2. 코드에서 어노테이션으로 적용하기

@Component
@Profile("프로필명")
public class DevDatasourceConfig{

    @Bean
    ...
}
  • 이와 같이 활성화시킬 profile명을 @Porfile의 값에 넣어주면 된다.

3. 실행 시 옵션으로 프로필 선택하기

-Dspring.profiles.active 옵션을 사용하면 실행 시 프로필을 선택할 수 있습니다!

 

사용 예시

사용 예시를 통해서 적용 방법을 좀 더 알아보도록 하자
예시 상황은 local에서 개발할 때와 prod로 배포할 때 DB접속을 다르게 하고 싶은 상황, 또한 applicaiton.yml을 다른 디렉터리에서 관리하고 싶어 다른 디렉터리에 yml을 두고 관리하고 있는 상황이라고 가정하겠습니다.

DB로는 오라클 클라우드에서 자율운행데이터베이스를 사용하여 지갑을 연결해야 하는 상황

 

0. 폴더 구조

/resources
  /config
    /Wallet_example
      ...지갑파일들
    application-db.yml
  application.yml

 

1. application-db.yml

--- # defalut 공통 설정
spring:
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.Oracle12cDialect
        format_sql: true
        use_sql_comment: true
        show_sql: true

--- # local
spring:
  config:
    activate:
      on-profile: "db-local"
  datasource:
    url: jdbc:oracle:thin:@example_low?TNS_ADMIN=./src/main/resources/Wallet_example
    username: exam
    password: example!
    driverClassName: oracle.jdbc.OracleDriver

--- # oracle 클라우드
spring:
  config:
    activate:
      on-profile: "db-prod"
  datasource:
    url: jdbc:oracle:thin:@example_low?TNS_ADMIN=/var/Wallet_example
    username: exam
    password: example!
    driverClassName: oracle.jdbc.OracleDriver
  • 기본적으로 profile은 application-{profile}.yml (properties) 형태로 작성해 두어야 한다. (스캔할 때 config에 *.yml로 import 하기 때문입니다.)
  • --- : 설정 정보를 분리시킬 수 있다. (properties에서는 #--- 로 구분해야 한다.)
  • 각 환경별로 설정 정보를 다르게 적용하여 prod환경에서는 /var/Wallet_eample에 위치한 지갑을 사용하도록 설정
    • 또한 당연하겠지만 /var/Wallet_example 위치에 지갑을 위치하도록 해야 합니다!
      (도커 환경은 dockerfile에 해당 위치로 복사)

2. application.yml

spring:
  config:
    import:
      - classpath:config-file/application-db.yml

  application:
    name: example
  profiles:
    include:
      - db
    active:
      - local
    group:
      local:
        - db-local
      prod:
        - db-prod
      prod:
  • import 문은 현재 application-db.yml이 application.yml과 다른 디렉터리에 위치하고 있기 때문에 import를 통해서 설정을 추가
    • 같은 디렉터리에 위치한 .yml (.properties)는 자동으로 스프링 부트가 찾아주기 때문에 import로 넣지 않아도 괜찮다.
  • include는 기본적으로 포함시킬 profile을 선택하는 것. 예시에서는 db만 추가하면 됐으니 db를 추가해 주었다.
    • on-profile을 설정하지 않는다면 default로 동작하게 됩니다. 따라서 위와 같이 공통 설정이 있는 경우 추가해주어야 합니다.
  • active를 통해 local 프로필을 활성화시켜주었다.
  • group은 여러 설정들을 합쳐 하나의 profile로 묶는 기능
    • 여기에서는 local에는 db-local을 포함시키고 prod에는 db-prod을 포함시키게 됩니다. 
    • 한 개의 프로필을 사용할 때는 없어도 괜찮지만 관련 설정들을 추가할수록 관리하기가 어렵기 때문에 group으로 묶어서 한 번에 관리하는 것이 좋아 보입니다.

이렇게 구성한 서버를 동작시켜 보면

The following 3 profiles are active: "db", "local", "db-local"

 

문구를 확인해 보면 현재 db, local, db-local프로필들이 활성화되는 것을 확인할 수 있다.

 

만약 jar를 실행할 때 profile을 결정하고 싶다면 jar를 실행할 때 아래와 같이 -Dspring.profiles.active={설정할 profile이름}을 사용하면 실행환경에서 profile을 변경할 수 있다!

java -jar -Dspring.profiles.active=prod /app.jar

 

반응형