공뷰/Spring

[Spring] 스프링부트 개발 환경에 따른 application.yml 환경 분리(local, dev, prod)

nourzoo 2025. 7. 27. 15:52

 

application.yml 환경 종류

  • application-local.yml
    • 내 맥북 인텔리제이에서 개발하고 검사해보는 용도
  • application-dev.yml
    • 서버에 올려서 개발 하면서 테스트 해보는 용도
  • application-prod.yml
    • 찐 운영할 때 사용

application-local.yml - 로컬 환경설정 파일

spring:
  jpa:
    hibernate:
      ddl-auto: create
상황: A 개발자가 새로운 회원 관리 기능을 개발 중
	• 설정: local 환경에서 ddl-auto가 create-drop으로 되어 있음
	• 개발 과정:
		1. 앱 실행 → DB 테이블이 새로 생성됨
		2. 회원 데이터 몇 건 등록 → 회원 가입 기능, 테스트 데이터 입력
		3. 기능 개발 도중 버그 발견 → IDE에서 디버깅 위해 앱 종료
		4. 앱 재실행 → create-drop 설정 때문에 앱 종료 시 DB 테이블이 삭제됨 → 모든 회원 데이터 사라짐
		5. 다시 회원 가입 기능 테스트 → 매번 데이터 처음부터 다시 입력해야 함
	• 결과:
		• 개발자가 매번 기능 테스트를 위해 데이터를 새로 입력해야 하므로 작업 효율이 떨어짐
		• 디버깅 중 데이터 상태를 비교하거나 확인하는 것이 불가능함

 

 

어차피 로컬에서 개발하면 서버 종료했을 때 api 보낼 수도 없고 아무것도 못 하는데 굳이 create로 데이터를 남기는 이유

1. 서버를 처음 실행할 때 db 상태

    user 테이블: [ {id: 1, name: "admin"} ]

2. api 호출로 회원가입 api 호출 -> name="hanbin" 추가했을 때 db 상태

    user 테이블: [ {id: 1, name: "admin"}, {id: 2, name: "hanbin"} ]

3. 이 상태는 서버를 꺼도 mysql db가 남아있다.

4. 서버를 종료했을 때 테이블을 drop하지 않으므로 서버 종료하고 db 직접 조회해도 데이터가 남아있다.

 

따라서 좋은 점은 다음과 같다.

1. 서버 종료 후 DB 툴로 들어가서 “이 API가 실제로 어떤 데이터를 만들었는지” 직접 확인할 수 있다.

2. 서버가 죽거나 에러가 발생했을 때, 마지막 상태의 DB를 확인해 문제를 찾을 수 있다.

    create-drop일 경우 서버가 꺼지면서 데이터가 사라져, 어떤 데이터가 잘못 들어갔는지 알 수 없지만,

    create일 경우 DB에 그대로 남아 있어 Workbench나 DBeaver로 주문 데이터 확인 가능하다.

 

application-dev.yml - 개발 환경설정 파일

spring:
  jpa:
    hibernate:
      ddl-auto: update
  sql:
    init:
      mode: always
      defer-datasource-initialization: true

  • 개발 시 DB 스키마 자동 반영 (update)

application-prod.yml - 운영 환경설정 파일

spring:
  jpa:
    hibernate:
      ddl-auto: validate
  sql:
    init:
      mode: always

  • 운영 환경은 테이블 생성/수정 없이 검증만 수행
  • data.sql 자동 실행은 허용

application.yml - 공통 설정 파일

spring:
  profiles:
    active: local
  config:
    import:
      - classpath:/yaml/application-local.yml
      - classpath:/yaml/application-dev.yml
      - classpath:/yaml/application-prod.yml

active: local이면 application-local.yml이 적용됨

GitHub Actions나 테스트 환경에서는 dev 등으로 설정 가능

 

여기서 궁금한 것들

1. spring jpa hibernate ddl-auto
2. sql init mode
3. defer-datasource- initialization

defer-datasource-initialization=true의 역할

spring:
  sql:
    init:
      defer-datasource-initialization: true
  • JPA(Hibernate)가 테이블 생성 → 그 다음에 SQL(schema.sql, data.sql) 실행
    • SQL 실행을 지연시켜서 JPA가 테이블을 만든 후에 SQL 파일을 실행하게 함
  • 충돌 방지해줌
  • 즉, 이 설정 없으면 JPA가 테이블 만들기 전에 data.sql 실행할 가능성도 있음.

spring sql init mode

어플리케이션 실행 시 schema.sql, data.sql을 실행할지 말지 결정함.

프로덕션에서는 실행 허용

spring:
  sql:
    init:
      mode: always

테스트에서는 실행 방지

spring:
  sql:
    init:
      mode: never
  • 아예 SQL 파일 무시해버림
    • 테스트에선 @Sql 등으로 명시적으로 주입한다. 만약 해당 설정을 never로 하기 싫다면 data.sql → test-date.sql 등으로 네이밍 수정하고 @TestPropertySource 또는 @ActiveProfiles를 사용해 테스트 전용 SQL 스크립트를 지정한다.
    • 운영용 data.sql이 테스트에 섞이지 않게 분리하자.

 

야구보구의 프로필 정리

  • application-local.yml
    • ddl-auto: create
  • application-dev.yml
    • ddl-auto: create
      • 개발 초기이기 때문에 데이터 변경이 잦을 것으로 예상했다.
      • 따라서 컬럼 삭제나 타입 변경이 제대로 반영되지 않는 `update` 대신,  
      • 실행 시마다 스키마를 삭제하고 새로 생성하는 `create`가 더 안전하다고 판단했다.
  • application-prod.yml
    • ddl-auto: validate