💡 다양한 환경을 고려합시다.
애플리케이션 개발 시 아래와 같은 다양한 환경을 고려할 수 있습니다.
- local : 로컬 환경이고 MySQL DB를 사용한다.
- dev : 서버 환경이며 클라우드 서비스의 DB를 사용하거나 팀원들이 공용으로 사용할 수 있는 DB를 사용한다. 배포 전 QA를 수행한다.
- test : 테스트 환경이며 로컬 H2 DB를 사용한다.
- prod : 실제 배포 환경
그러므로 다양한 환경에 맞는 profile을 구성해줘야합니다.
spring boot에서는 profile를 그룹화해 새로운 profile을 정의할 수 있습니다.
다음은 공통된 설정을 common profile에 정의하고, 각각의 환경에 맞는 설정을한 예시 입니다.
spring: profiles: active: "local" group: "local": "local, common" "dev": "dev, common" "prod": "prod, common" "test": "test, common"
- application-common.yml
spring: config: activate: on-profile: "common" application: name: instakyuram thymeleaf: suffix: .html servlet: multipart: maxFileSize: 5MB maxRequestSize: 30MB security: patterns: ignoring: ["/css/**", "/js/**", "/webjars/**", "/images/**"] permit-all: ALL : ["/api/members/signup", "/api/members/signin", "/members/signin"] GET : ["/api/members/**", "/members/**", "/api/posts/**"] POST : [] PATCH : [] PUT : [] DELETE : [] OPTIONS: [] TRACE: [] HEAD: [] jwt: issuer: kyuram client-secret: secret accessToken: header: atoken expiry-seconds: 60 refreshToken: header: rtoken expiry-seconds: 120 logging: level: org.hibernate.type.descriptor.sql: trace
- application-local.yml
spring: config: activate: on-profile: "local" datasource: driver-class-name: com.mysql.jdbc.Driver username: localadmin password: localadmin url: jdbc:mysql://localhost:3306/kyuram jpa: hibernate: ddl-auto: validate show-sql: true properties: hibernate: format_sql: true flyway: enabled: true baseline-on-migrate: true locations: classpath:db/migration, classpath:db/seed cors: allowed: api: /api/** url: ["http://localhost:3000", "http://127.0.0.1:3000"] method: GET, POST, PATCH, DELETE
- application-dev.yml
spring: config: activate: on-profile: "dev" datasource: driver-class-name: com.mysql.jdbc.Driver username: devadmin password: devadmin #로컬이 아닌 클라우드 또는 개발환경의 DB를 사용한다. url: jdbc:mysql://aws-rds:3306/dev/kyuram jpa: hibernate: ddl-auto: validate show-sql: true properties: hibernate: format_sql: true flyway: enabled: true baseline-on-migrate: true locations: classpath:db/migration, classpath:db/seed cors: allowed: api: /api/** #실제 개발환경의 URL을 입력한다. url: ["http://dev.instakyuram.com:3000"] method: GET, POST, PATCH, DELETE
- application-prod.yml
spring: config: activate: on-profile: "prod" datasource: driver-class-name: com.mysql.jdbc.Driver username: prodadmin password: prodamin #실제 배포환경용 DB를 사용한다. url: jdbc:mysql://aws-rds:3306/prod/kyuram jpa: hibernate: ddl-auto: validate show-sql: true properties: hibernate: format_sql: true flyway: enabled: true baseline-on-migrate: true locations: classpath:db/migration, classpath:db/seed # 실제 배포 환경에서는 토큰 유효기간을 2시간, 14일로 지정한다. jwt: accessToken: expiry-seconds: 7200 refreshToken: expiry-seconds: 1209600 cors: allowed: api: /api/** #실제 배포환경의 리액트 URL을 입력한다. url: ["http://instakyuram:3000"] method: GET, POST, PATCH, DELETE
- application-test.yml
spring: config: activate: on-profile: "test" flyway: enabled: false baseline-on-migrate: false locations: classpath:db/migration, classpath:db/seed datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:testdb h2: console: enabled: true settings: web-allow-others: true path: /h2-console jpa: show-sql: true hibernate: ddl-auto: create-drop generate-ddl: true defer-datasource-initialization: true
👨👩👧👦 더욱 세분화된 profile
다음과 같이 로컬 profile을 더 세분화 할 수 있습니다.
- local-h2 : 로컬 환경이며 H2 DB(In-memory DB, Flyway X)를 사용한다.
- local-mysql: 로컬 환경이며 MySQL DB(RDB, Flyway O)를 사용한다.
- test: test 환경이며 H2 DB(In-memory DB, Flyway X)를 사용한다.
spring: profiles: active: "local-mysql" group: "local-h2": "local, h2db, common" "local-mysql" : "local, mysqldb, common" "test": "test, h2db, common"
그렇다면 profile은 local, h2db, mysqldb, test, common으로 나눌 수 있습니다.
common은 동일하므로 생략합니다.
- application-local.yml
spring: config: activate: on-profile: "local" #로컬 환경에서만 필요한 설정들을 포함할 수 있습니다.
- application-test.yml
spring: config: activate: on-profile: "test" # 테스트 환경에서만 필요한 설정들을 포함할 수 있습니다.
- application-h2db.yml
spring: config: activate: h2db datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:testdb h2: console: enabled: true settings: web-allow-others: true path: /h2-console jpa: show-sql: true hibernate: ddl-auto: create-drop generate-ddl: true defer-datasource-initialization: true flyway: enabled: false baseline-on-migrate: false locations: classpath:db/migration, classpath:db/seed
- application-mysqldb.yml
spring: config: activate: mysqldb datasource: driver-class-name: com.mysql.jdbc.Driver username: root password: password url: jdbc:mysql://localhost:3306/kyuram jpa: hibernate: ddl-auto: validate show-sql: true properties: hibernate: format_sql: true flyway: enabled: true baseline-on-migrate: true locations: classpath:db/migration, classpath:db/seed
🆚 Profile 세분화 VS 병합
💁🏻 세분화
- 장점 : Profile을 각각의 목적마다 쪼개면 재사용성이 향상되고 중복이 줄어 정합성이 향상됩니다.
- ex) local.yml, mysql.yml, h2.yml 세개로 쪼개어 그루핑해 local_mysql, local_h2을 사용할 경우, cors설정을 바꾸기로했다면 local.yml을 바꾸기만 하면 됩니다.



- 단점 : 하나의 파일에 해당 환경의 모든 설정을 볼 수 없어 찾기가 어려워집니다.
💁🏻♀️ 병합
- 장점 : 원하는 환경의 Profile을 한번에 볼 수 있습니다.

- 단점 : 정합성이 떨어질 수 있습니다.
- ex) 로컬 환경에서 cors 설정을 바꾸기로 했을 때, local_h2.yml, local_mysql.yml 모두 바꿔줘야 합니다.


🧐 제 생각은..
프로파일을 너무 잘게 쪼갠다면 해당 프로파일이 어느 그룹에서 사용되는지 파악하기가 어려울 것 같습니다.
너무 잘게 쪼개기 보다는 모든 환경에 해당하는 설정을 Common에 몰아두어 어느정도의 중복을 제거하고
적당한 중복을 허용하여 각 환경에 맞는 설정을 한번에 볼 수 있도록하는 것이 좋아 보입니다.