본문 바로가기
Framework/Spring Boot

[Spring Boot] application.yml 완벽 가이드: Profile을 활용한 무결점 환경 분리 전략

반응형

스프링 부트(Spring Boot)로 개발을 진행하다 보면 필연적으로 데이터베이스 접속 IP, 비밀번호, 외부 결제 API 연동 키(Key) 등 수많은 '설정(Configuration) 데이터'를 다루게 됩니다. 초보 개발자들은 흔히 자바(Java) 코드 안에 String dbUrl = "jdbc:mysql://localhost:3306..." 처럼 값을 하드코딩(Hard-coding)하는 실수를 저지릅니다. 이렇게 코드를 짜면, 내 노트북(로컬)에서는 잘 돌던 프로그램이, IP가 완전히 다른 실제 라이브 운영(Production) 서버에 배포되는 순간 데이터베이스를 찾지 못하고 펑 터져버립니다. 배포할 때마다 소스코드를 열어서 주석 처리하고 IP를 고쳐서 빌드하실 건가요? 이런 원시적인 작업을 우아하게 해결하기 위해 스프링 부트가 제공하는 마법의 파일이 바로 application.yml과 Profile(환경 분리) 시스템입니다.

이번 시리즈에서는 "소스코드는 단 한 줄도 건드리지 않고, 로컬/개발/운영 서버의 설정을 카멜레온처럼 스위칭하는 실무 최고급 노하우"에 대하여 다뤄보겠습니다.

📝 1. properties vs yml (야믈): 대세는 YAML이다

스프링 부트 프로젝트를 처음 생성하면 src/main/resources 폴더 밑에 application.properties라는 파일이 덩그러니 놓여있습니다. 하지만 실무에 가보면 이 확장자를 .yml(YAML, 야믈)로 당장 바꾸라는 선배의 지시를 받게 됩니다. 왜 그럴까요?

.properties 방식의 단점 (중복의 지옥)

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=root
spring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.datasource라는 접두어가 끝도 없이 중복해서 반복됩니다. 설정이 100줄 넘어가면 가독성이 최악으로 떨어집니다.

.yml 방식의 장점 (계층적 구조의 우아함)

spring:
  datasource:
    url: jdbc:mysql://localhost/test
    username: root
    password: 1234
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

YAML 파일은 들여쓰기(Indentation, 스페이스 2칸)를 통해 계층(Depth)을 표현합니다. 접두어 중복이 사라져 코드가 훨씬 깔끔해지며, 리스트나 배열 형태의 데이터를 표현하기도 압도적으로 유리합니다. 따라서 파일 확장자를 application.yml로 변경하는 것이 실무 첫걸음입니다.


🔀 2. 프로필(Profile) 환경 분리의 핵심 아키텍처

현대의 애플리케이션은 "빌드는 한 번만 하고(Build Once), 어디서든 실행(Run Anywhere)"되어야 한다는 12-Factor App 원칙을 따릅니다. 이를 위해 젠킨스(Jenkins)로 빌드해 둔 똑같은 .jar 파일을 가지고, 내 PC에서 켤 때는 local, 개발팀 테스트 서버에서 켤 때는 dev, 고객이 쓰는 진짜 상용 서버에서 켤 때는 prod(Production) 모드로 동작하게 만들어야 합니다.

스프링 부트는 파일 이름 규칙(Naming Convention)을 통해 이를 기가 막히게 해결합니다.

  • application.yml: 공통 설정 (어느 환경에서나 100% 동일한 값, 예: 애플리케이션 이름)
  • application-local.yml: 내 PC 전용 설정 (H2 메모리 DB 등)
  • application-dev.yml: 테스트 서버 전용 설정 (개발 DB 연결 정보)
  • application-prod.yml: 라이브 상용 서버 전용 설정 (운영 DB, 외부 캐시, 엄격한 보안 세팅)


💻 3. 완벽한 실무 yml 파일 분리 예제

1. 공통 파일 (application.yml)

spring:
  application:
    name: my-awesome-app
  profiles:
    # 아무 옵션을 안 주고 실행하면 기본적으로 'local' 프로필을 활성화해라!
    active: local 
    
server:
  port: 8080 # 포트 번호는 어디서든 8080 고정

2. 로컬 개발 파일 (application-local.yml)

spring:
  datasource:
    url: jdbc:h2:mem:testdb  # 로컬은 가벼운 H2 메모리 DB 사용!
  jpa:
    hibernate:
      ddl-auto: create-drop  # 로컬은 서버 켜질때마다 테이블 싹 밀고 다시 생성! (개발용)
    show-sql: true           # 쿼리를 눈으로 봐야 하니 콘솔에 출력!

3. 상용 운영 파일 (application-prod.yml)

spring:
  datasource:
    url: jdbc:mysql://192.168.1.100:3306/real_db # 진짜 비싼 AWS RDS 주소 연결!
    username: real_admin
    password: super_secret_password_123!
  jpa:
    hibernate:
      ddl-auto: validate     # 상용에선 절대 테이블 건드리지 말고 검증만 해라! (create 주면 회사 망함)
    show-sql: false          # 로그 너무 많아지니까 SQL 출력 금지!

🚀 4. 리눅스 서버에서 프로필(Profile) 활성화하며 실행하기

이제 이 .jar 파일을 운영 서버(Linux)에 올렸습니다. 이때 아무 옵션 없이 java -jar app.jar를 치면 application.yml에 설정해둔 대로 local 프로필이 돌아가며 H2 메모리 DB를 찾게 됩니다.

상용 서버에서는 자바를 실행할 때 환경변수(Command Line Argument)"너는 지금 PROD 환경이야!"라고 귀에다 소리쳐 주어야 합니다.

# 실행 시 프로필을 강제로 'prod'로 덮어씌웁니다.
# 스프링은 application.yml을 먼저 읽고, application-prod.yml의 설정으로 덮어쓰기(Override)를 수행합니다.
java -jar -Dspring.profiles.active=prod my-awesome-app.jar

이 한 줄의 명령어로 여러분의 프로그램은 순식간에 강력한 실서버 세팅 장착을 완료하게 됩니다.


🎯 5. 마무리 및 다음 단계

지금까지 코드 수정과 재빌드라는 원시적인 노가다 없이, 파일명 규칙과 YAML의 깔끔한 계층 구조를 활용하여 수만 가지의 환경 세팅을 단 1초 만에 카멜레온처럼 스위칭하는 '스프링 부트 프로필(Profile) 아키텍처'에 대해 다루어 보았습니다. 이는 현대 클라우드 네이티브(Cloud Native) 앱이 갖춰야 할 최우선 소양입니다.

서버가 운영 환경에서 팽팽 잘 돌고 있습니다. 그런데 갑자기 고객센터에서 "결제가 안 된다"는 클레임이 들어왔습니다. 원인을 파악하려면 서버가 남긴 '로그(Log)'를 뒤져봐야 합니다. 그런데 콘솔 화면에만 하얀 글씨로 찍히던 System.out.println()은 서버가 꺼지거나 로그가 차면 영영 날아가 버립니다! 지난주에 발생한 에러를 추적하려면 로그를 반드시 '디스크 파일'로 날짜별로 예쁘게 남겨야 합니다. 이어지는 05단계 포스팅에서는 "장애가 터졌을 때 유일한 목격자이자 블랙박스!" Spring Boot Logback 로깅 시스템 완벽 제어 및 파일 로테이션(Rotation) 실무 노하우에 대해 아주 뼈 때리게 파헤쳐 보겠습니다!

반응형