Skip to content

yml 관리

chungjeongsu edited this page Mar 4, 2026 · 1 revision

과거 yml 기본 구조

1. yml

image

yml 파일이란, '사람이 쉽게 읽을 수 있는' 데이터 직렬화 양식을 뜻합니다.

즉, 특정 파일에 데이터를 정의하는 역할임을 뜻합니다.

기본적으로 스프링 부트에서는 xml, yml 등 파일에 앱 설정 데이터(property)를 정의 할 수 있습니다.

저희 프로젝트에서도 yml을 이용하여 앱 설정 데이터를 정의합니다.

2. 프로파일

yml을 통해 설정 파일을 정의했다면, CICD 수행 시 해당 설정 파일을 활성화해 배포해야 합니다.

현재, 저희 서버는 2가지로 아래와 같습니다.

image
SPRING_PROFILES_ACTIVE=prod

MYSQL_URL=exaple
MYSQL_USERNAME=exaple
MYSQL_PASSWORD=exaple

KAKAO_CLIENT_ID=exaple
KAKAO_CLIENT_SECRET=exaple
KAKAO_REDIRECT_URI=exaple

CORS_ALLOWED_OGIRINS_FRONT=exaple

============================================
SPRING_PROFILES_ACTIVE=dev

MYSQL_URL=exaple
MYSQL_USERNAME=exaple
MYSQL_PASSWORD=exaple

KAKAO_CLIENT_ID=exaple
KAKAO_CLIENT_SECRET=exaple
KAKAO_REDIRECT_URI=exaple

CORS_ALLOWED_OGIRINS_FRONT=exaple

위처럼, properties 내부에 프로파일을 정의함으로 활성화할 설정 파일을 분기 처리 해줍니다.

3. 객체를 통한 yml 관리

yml에는 외부 API에서 필요한 Secret Key나, URL 등이 들어갑니다.

RestClient 라이브러리를 사용한 외부 API 통신과 같은 상황에서는 yml에 정의된 설정 값을 사용해야 합니다.

이러한 값들은 @Value 또는 @ConfigurationProperties와 같은 어노테이션으로 변수로써 매핑 시킬 수 있었습니다.

@Value는 단건 주입으로 문자열을 특정 타입으로 변환해 값을 주입합니다.

@ConfigurationProperties는 바인딩을 통해 객체에 다건 값을 주입해줍니다. 이때, @Validated가 수행될 수 있습니다.

때문에, NullPointerException과 같은 예외를 방지하고자, 대부분의 설정 값을 @ConfigurationProperties로 관리해줍니다.


문제 발생

server:
  servlet:
    session:
      cookie:
        same-site: none
        secure: true
        http-only: true

위는 yml의 공통 설정입니다.

same-site는 사이트의 동등 여부를 통한 쿠키 전송 설정입니다.

개발 서버(dev)에서는 https://localhost:3000 <-> https://dev.triple.io.kr 로, same-site:none 이 필요하였고,

배포 서버(prod)에서는 https://triple.io.kr <-> https://prod.triple.io.kr로, same-site:Lax가 필요하였습니다.

하지만, yml에서는 공통 설정으로 로컬 테스트, 개발 서버 테스트, 배포 서버 테스트 모두 properties를 바꿔 바인딩 후 수행/재배포 해야 하는 불편함이 생겼습니다.


프로파일 분리

해결책은 코드 단 if-else문을 통한 분리, 프로파일이 다른 파일로 분리 등이 있었습니다.

~~

때문에, 프로파일을 분리하고자 하였습니다.

yml 나누기

image

총 테스트를 수행하거나 참조해야하는 yml은 위와 같이 3가지 입니다.

CICD

yml을 3가지로 나눴으니, 이제, 해당 yml을 프로파일 별 활성화 해 배포를 해야합니다.

CD를 살펴보면 아래와 같습니다.

  - name: Write .env
    run: |
      if [ "${BRANCH_NAME}" = "develop" ]; then
        printf "%s" "${{ secrets.ENV_DEV }}" > .env
      else
        printf "%s" "${{ secrets.ENV_PROD }}" > .env
      fi

브랜치 별 적용할 ENV Secret Key를 선택한 후 .env 파일을 생성합니다.

      - name: Upload files
        env:
          DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
        run: |
          DEPLOY_PATH="${DEPLOY_PATH:-/home/ubuntu/deploy}"
          ENV_FILE="${GITHUB_WORKSPACE}/.env"
          COMPOSE_FILE="${GITHUB_WORKSPACE}/docker-compose.yml"

          if [ ! -f "${COMPOSE_FILE}" ]; then
            COMPOSE_FILE="${GITHUB_WORKSPACE}/docker/docker-compose.yml"
          fi

          if [ ! -f "${COMPOSE_FILE}" ]; then
            echo "docker-compose file not found in workspace"
            find "${GITHUB_WORKSPACE}" -maxdepth 3 -type f \( -name '*compose*.yml' -o -name '*compose*.yaml' \) || true
            exit 1
          fi

          ssh -i ~/.ssh/deploy_key.pem -o StrictHostKeyChecking=no ubuntu@"${TARGET_HOST}" "mkdir -p ${DEPLOY_PATH}"
          scp -i ~/.ssh/deploy_key.pem -o StrictHostKeyChecking=no "${ENV_FILE}" ubuntu@"${TARGET_HOST}":"${DEPLOY_PATH}"/.env
          scp -i ~/.ssh/deploy_key.pem -o StrictHostKeyChecking=no "${COMPOSE_FILE}" ubuntu@"${TARGET_HOST}":"${DEPLOY_PATH}"/docker-compose.yml
          ssh -i ~/.ssh/deploy_key.pem -o StrictHostKeyChecking=no ubuntu@"${TARGET_HOST}" "chmod 600 ${DEPLOY_PATH}/.env"

도커 컴포즈에 만들어진 .env 파일을 컨테이너 환경변수로 주입시킵니다.

그 후 java -jar app.jar로 실행되면, jvm이 해당 환경변수를 받습니다.

스프링은 이제 해당 환경 변수를 사용할 수 있게 됩니다.

스프링은 환경 변수 내부 SPRING_PROFILES_ACTIVE를 통해 특정 yml을 선택할 수 있습니다.

적용 완료

Clone this wiki locally