티스토리 뷰
# 변경 이전
# MySQL DB 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=[비밀!]
spring.datasource.username=[비밀!]
spring.datasource.password=[비밀!]
# JPA 설정
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
# 로그 설정
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type=info
# HTML Form에서 PUT, DELETE 메소드도 hidden field에 담아 사용하도록 설정
spring.mvc.hiddenmethod.filter.enabled=true
# View Resolver 설정
spring.mvc.static-path-pattern=/resources/**
# HTTPS
#server.port=443
#security.require-ssl=true
#server.ssl.key-store=[key storage]
#server.ssl.key-store-password=[SSL Password]
#server.ssl.keyStoreType=[type]
#server.ssl.key-alias=[alias]
# Twilio
twilio.sid=[sid]
twilio.token=[token]
twilio.myTel=[myTel]
twilio.verifiedToTel=[verifiedTel]
server.tomcat.max-http-form-post-size=5MB
spring.servlet.multipart.maxFileSize=5MB
spring.servlet.multipart.maxRequestSize=5MB
# Mosquitto
mosquitto.clientId=[mqttClientID]
mosquitto.password=[mqttClientPW]
온갖 설정 정보들이 application.properties 파일 한 군데에 다 몰아서 설정되어있다.
보기 불편한거는 둘째치고, DB 연결 시 필요한 ID/PW나 외부 API 연동 시 필요한 토큰 값과 같은 민감한 개인정보까지 다 모여있다 보니 해당 파일을 깃허브에 업로드 할 수가 없다는 것이 제일 문제였다. 얘가 없으면 실행이 안되는데 말이지..
이 설정 파일을 잘 분리해서 개인정보가 담긴 민감한 파일을 분리하고, 더 나아가서 운영 환경 설정도 별도로 분리하는 것 까지 해보자!!
# 로컬에 적용하기
## 로컬 환경에 대한 설정 정보를 담은 파일 ##
# (local 환경) 타 properties 파일 불러오기
spring.profiles.include=https,twilio,mqtt
# real(운영 환경)에서 사용할 properties 파일
spring.profiles.group.real=real,real-db,https,twilio,mqtt
# MySQL DB(Local) 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/capstone?useUnicode=true&serverTimezone=Asia/Seoul&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=admin
# JPA 설정
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
# 로컬 환경에서의 로그 설정
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type=info
# HTML Form에서 PUT, DELETE 메소드도 hidden field에 담아 사용하도록 설정
spring.mvc.hiddenmethod.filter.enabled=true
# View Resolver 설정
spring.mvc.static-path-pattern=/resources/**
# 기타 설정
server.tomcat.max-http-form-post-size=5MB
spring.servlet.multipart.maxFileSize=5MB
spring.servlet.multipart.maxRequestSize=5MB
application.properties
## 운영 환경에 대한 설정 정보를 담은 파일 ##
# 로그 설정
logging.level.org.hibernate.SQL=info
logging.level.org.hibernate.type=info
# JPA 설정
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
# HTML Form에서 PUT, DELETE 메소드도 hidden field에 담아 사용하도록 설정
spring.mvc.hiddenmethod.filter.enabled=true
# View Resolver 설정
spring.mvc.static-path-pattern=/resources/**
# 기타 설정
server.tomcat.max-http-form-post-size=5MB
spring.servlet.multipart.maxFileSize=5MB
spring.servlet.multipart.maxRequestSize=5MB
application-real.properties
## 외부 API 설정 파일 ##
# Twilio
twilio.sid=[sid]
twilio.token=[token]
twilio.myTel=[myTel]
twilio.verifiedToTel=[verifiedTel]
# Mosquitto
mosquitto.clientId=[mqttClientID]
mosquitto.password=[mqttClientPW]
application-api.properties
이와 같은 방식으로 properties 파일들을 분리했다.
+++
application.properties 파일은 default 설정을 담고 있는 Application을 위한 기본 설정파일이고,
이후에 만들 application-real.properties와 같은 파일은 각각의 profile을 위한 설정 파일을 만드는 것이다.
(active된) profile 설정 파일이 우선순위를 갖는다
+++
spring.profiles.include=https,api
- spring.profiles.include property can be used to unconditionally add active profiles. (참고)
이 코드가 application.properties 파일이 읽어질 때 다른 properties 파일 까지 추가해서 실행할 수 있게 만들어준다.
application-[이름].properties 와 같이 하이픈 뒤에 이름을 적어주면 된다.
정상적으로 세팅 되었다면 로컬에서 애플리케이션 실행 시 다음과 같은 문구를 볼 수 있다
(기본 application.properties 을 포함해서 https, api 두개의 파일을 추가로 실행시키는 것이다)
* 변경 이전에는 No active profile set ~~ 과 같은 문구와 함께 "default" profile 하나만 실행됐었다.
(default profile = application.properties)
로컬 환경에서 잘 동작하는 것을 확인했다면 다음은 AWS EC2 운영 환경에서도 동작하도록 만들어보자!
# EC2 환경에 적용하기
개인정보가 담긴 파일은 깃허브에 올리면 안된다.
private 리포지토리면 모르겠는데 public 이라면 사냥꾼들이 개인정보를 호시탐탐 노리고 있으니 항상 조심해야 한다.
그렇기에 개인정보가 담긴 설정파일인 api, https.properties 및 EC2 환경에서 DB 연결에 사용되는 real-db.properties는 EC2에서 VIM을 활용해 직접 만들어 주는 것으로 한다.
*** => api, https, real-db.properties 파일은 .gitignore에 등록해둬야한다 ***
* api, https, real-db.properties는 어디에 만들어야 할까?
- 프로젝트 내부 src/main/resources 디렉토리에 다시 넣어놓는 것이 아니다 (빌드에 포함되는 애들이 아니다)
- 프로젝트 외부에 잘 알아볼 수 있는 곳에다가 잘 모아서 저장하도록 하자.
- 설정파일이 프로젝트 외부에 있으면 스프링이 이를 인식할 수 있게 하기 위해 별도의 옵션을 추가해야 한다.
-Dspring.config.location=classpath:/application.properties,/home/ec2-user/app/application-real-db.properties,/home/ec2-user/app/application-api.properties
그리고 하나의 옵션을 더 추가해 줘야한다.
gradlew build 명령을 통해 빌드된 jar 파일을 그냥 java -jar 명령어를 통해 실행시키면 아래와 같이 된다.
아까 로컬에서 했던 것과 동일하게 https와 api properties만 불러와진 것을 확인할 수 있다. (include가 적용됐다)
앞서 로컬 설정과 운영 설정을 구분하기 위해 real 이라는 그룹을 만들었었다.
# real(운영 환경)에서 사용할 properties 파일
spring.profiles.group.real=real,real-db,https,api
이는 real이라는 그룹을 실행시키면 real, real-db, https, api 4개의 설정파일이 default 설정파일에 추가되어 실행된다.
아래와 같은 옵션으로 그룹을 활성화 시킬 수 있다.
-Dspring.profiles.active=real
근데 application.properties 파일과 application-real.properties 파일이 충돌하는 것이 아닐까?
이는 앞서 말했듯이 active된 profile을 위한 properties가 기본 properties 보다 우선순위가 더 높기 때문에 덮어씌워져서 문제가 없다
결론적으로 이제 profile을 나눠둠으로 인해 jar을 실행시킬때 붙여야 할 코드는 아래와 같다.
java -jar \
-Dspring.config.location=classpath:/application.properties,/home/ec2-user/app/application-real-db.properties,/home/ec2-user/app/application-https.properties,/home/ec2-user/app/application-api.properties \
-Dspring.profiles.active=real [jar 파일명]
꽤 번거로워졌음은 틀림이 없어보인다.
하지만 이는 나중에 CI/CD를 이용한 배포 자동화를 하게 된다면 스크립트가 알아서 코드를 실행시키기 때문에 별 문제가 되지 않는다!
++ 나중에 구글링 하면서 또 찾아보니 가장 자주 쓰이는 profile 네이밍이 있다고 한다
local: 로컬 환경
dev: 테스트 환경
prod: 운영 환경
세 종류로 나누는 것이 국룰이라고 한다.
++ 또한 로컬 환경에서도 IDE를 통해 특정 profile을 active 시켜 실행시킬 수 있다.
## 예시
spring.profiles.group.real2=real2,real-db,https,api
IDE가 내부적으로 -Dspring.profiles.active=real2 옵션을 붙여서 jar를 실행시킨 것을 잘 확인할 수 있다.
이렇게 되면 설정 파일 분리가 얼추 모두 끝나게 된다.
진짜 익숙하지 않은 작업이라 그런지 너무 빡세다
백엔드 개발자가 이래서 어렵다 어렵다 하는 거구나 싶다. AWS나 배포, 깃 사용은 익숙치 않아 그런지 여전히 너무 어려운 것 같다.
'웹 > Spring' 카테고리의 다른 글
Swagger (Springfox)를 이용해 스프링 프로젝트의 API 문서 만들어보기 (0) | 2022.09.08 |
---|---|
스프링 부트 | 상대 경로 현재 디렉토리(./)는 어디를 뜻하는 것일까? (1) | 2022.09.06 |
스프링 부트 | Port 8080 was already in use 해결 (0) | 2022.08.22 |
스프링 볶음밥 - 8, 9장 (0) | 2022.07.12 |
스프링 볶음밥 - 7장 (0) | 2022.07.11 |