-
[Spring Boot / FastAPI] 프로젝트 환경 분리프로젝트/뉴스타 2024. 6. 30. 22:34
프로젝트 환경 분리 왜 궁금했을까❓
프로젝트를 할 때, Dev와 Prod 환경 설정들을 분리하지 않고 사용하다 보니 지속적으로 Config를 수정해야 한다는 문제점이 있었다. 이러한 부분에서 팀의 생산성을 향상시키고자 Dev와 Prod 환경을 분리하려고 한다. 또한, 분리를 통해 운영 서버의 데이터를 조작할 수 없게 하여 안전성을 향상시키고자 한다.
1. 기존의 환경 변수 관리법
기존에는 각 어플리케이션의 환경 변수를 하나의 YAML 파일에 넣고 GitLab에 PUSH하여 팀원끼리 공유하는 식으로 진행이 되었다.
- 위와 같은 방식으로 운영하다보니 환경 변수가 prod와 dev가 섞이게 되어 운영 서버에 데이터가 들어가거나 개발 서버의 환경 변수로 인해 작동이 안하는 장애가 발생했다.
- 각 팀원들이 pull을 할 때마다 각 환경 변수들이 개발 서버에 맞게 되어 있는 지, 안되어 있다면 변경하는 작업이 지속적으로 이뤄져야 해서 비 효율적이였다.
- GitLab에 비밀키와 같은 민감한 정보들이 GitLab에 PUSH되어 보안에 심각한 문제를 일으키고 있었다.
위와 같은 문제점들을 해결하고자 개선된 환경 변수 관리 방법을 적용하고 팀의 생산성과 보안성을 향상시키고자 한다.
2. 개선된 환경 변수 관리법
- Private한 (Notion) 공간에 env 파일을 두고 각 팀원들과 공유하여 서비스 전체적의 환경 변수를 관리
- 각 어플리케이션에서는 prod와 dev 파일로 yaml을 분리하여 각 환경에 맞는 설정을 주입할 수 있도록 설정
- dev에서 개발할 때, 어플리케이션에 dev.yaml을 활용하겠다고 설정하면 dev 환경에 맞는 설정들이 주입
- prod에서 개발할 때, 어플리케이션에 prod.yaml을 활용하겠다고 설정하면 prod 환경에 맞는 설정들이 주입
이로써 어플리케이션을 실행할 때 어떠한 환경 파일을 사용할지 입력만 한다면 자동으로 주입되어 보다 편하고 장애없이 관리할 수 있다.
3. 프로젝트 적용
3.1. Spring Boot
- yaml 설정 파일을 개발 / 배포 / 공용으로 나눠서 관리를 했다.
application.yml
spring: profiles: default: dev datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/newstar?serverTimezone=Asia/Seoul username: ${MYSQL_USER_DEV_ID} password: ${MYSQL_USER_DEV_PASSWORD} data: redis: host: localhost port: 6379 jpa: properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect # show_sql: true # sysout 단계에서 쿼리문 show format_sql: true default_batch_fetch_size: 1000 # select 배치 조회 크기 server: servlet: context-path: '/api' port: 8080 logging: level: org.hibernate.SQL: debug org.hibernate.type: trace # log 단계에서 쿼리문 show management: endpoints: web: exposure: include: health
application-dev.yml
spring: config: activate: on-profile: dev jpa: hibernate: ddl-auto: none
application-prod.yml
spring: config: activate: on-profile: prod datasource: url: jdbc:mysql://mysql:3306/newstar?serverTimezone=Asia/Seoul username: ${MYSQL_USER_PROD_ID} password: ${MYSQL_USER_PROD_PASSWORD} jpa: hibernate: ddl-auto: none data: redis: host: redis
3.2. FastAPI
- 하나의 yml 파일에 dev, prod를 나눠서 각 환경 설정을 관리했다.
application.yml
dev: DB: user: 'newstar' password: 'newstar' host: 'localhost' port: 3306 database: 'newstar' ES: host: 'localhost:9200' TEST: member_pw: 'feb91399-aaf3-40ef-856d-35e6ddf8befb' prod: DB: host: 'mysql' port: 3306 database: 'newstar' ES: host: 'elastic:9200'
config.py
import os import yaml with open(os.path.dirname(os.path.abspath(__file__)) + '/application.yml', 'r') as yaml_conf: conf = yaml.safe_load(yaml_conf)[os.environ.get('APP_ENV', 'dev')] class Config: DB = conf['DB'] if os.getenv("APP_ENV") == 'prod': DB['user'] = os.getenv("MYSQL_USER_PROD_ID") DB['password'] = os.getenv("MYSQL_USER_PROD_PASSWORD") ES = conf['ES']
3.3. Docker-Compose
- 각 어플리케이션 컨테이너 실행 시 환경 변수가 주입될 수 있도록 설정했다.
version: '3' services: spring: container_name: spring-blue image: newstar_back ports: - 8080:8080 restart: always env_file: - /env/.env environment: TZ: Asia/Seoul react: container_name: react-blue image: newstar_front ports: - 3000:3000 fastapi: container_name: fastapi-blue image: fastapi_back ports: - 8000:8000 restart: always env_file: - /env/.env environment: TZ: Asia/Seoul networks: default: name: app-net external: true
'프로젝트 > 뉴스타' 카테고리의 다른 글
[Infra] 무중단 배포 전략 (Rolling / Blue-Green / Canary) (0) 2024.07.21 [React] Axios API 모듈화 (0) 2024.07.02 [FastAPI] ElasticSearch (0) 2024.06.27 [Spring boot] Java 테스트 코드 (0) 2024.06.17 [Spring Boot] Redis를 활용한 성능 향상 (0) 2024.06.16