[FE] 기술 요구사항 3 ‐ development production 빌드 및 배포 환경 분리 - woowacourse-teams/2026-gachi-gacha GitHub Wiki

[FE] 기술 요구사항 3 ‐ development / production 빌드 및 배포 환경 분리

[가치가챠] 프론트엔드 개발 및 운영 환경 분리 가이드

본 문서는 가치가챠 프로젝트의 프론트엔드 애플리케이션의 development(개발) / production(운영) 빌드 및 배포 환경을 어떻게 분리했는지 설명하는 문서입니다.

1. 아키텍처 개요 및 환경 분리 목적

"새 기능을 테스트하려고 임시 UI를 추가했는데, 실제 사용자들에게 테스트중인 기능이 노출되는 문제"

이를 방지하기 위해 배포 환경을 분리했습니다.

  • 프론트엔드와 백엔드 모두 개발용(DEV)과 운영용(PROD) 서버를 별도로 구축하여 총 4대의 EC2 체제(FE-DEV, FE-PROD, BE-DEV, BE-PROD)로 운영합니다. 이를 통해 개발 서버에서 발생한 장애가 운영 서버에 영향을 주지 않습니다. 신규 기능과 임시 UI는 DEV 환경에서 팀 내부 검증을 거치며, 내부 테스트를 통과한 코드만 PROD 환경(main 브랜치)으로 머지됩니다.

2. DEV / PROD 환경 상세 비교

개발 환경과 운영 환경은 기준 브랜치부터 API 통신 대상까지 다음 기준에 따라 동작합니다.

구분 Development (개발 환경) Production (운영 환경)
기준 브랜치 frontend-dev main
접속 도메인 dev.gachigacha.kro.kr gachigacha.kro.kr
배포 빌드 명령 APP_ENV=development pnpm build APP_ENV=production pnpm build
Webpack 모드 production production
API 통신 대상 BE DEV 서버 BE PROD 서버
Self-hosted Runner 라벨 frontend-dev frontend-prod
GitHub Environment frontend-development frontend-production
접근 대상 개발자 일반 사용자

(도메인은 비용 절감을 위해 내도메인.한국의 무료 도메인인 .kro.kr을 활용하여 각 환경의 고정 IP(Elastic IP)에 매핑)

현재 frontend-dev와 main 브랜치에는 Branch Protection이 설정되어 있지 않고, 두 GitHub Environment에도 Required Reviewer가 없습니다. PR에서 Frontend Quality 워크플로는 실행되지만 실패한 검사를 기술적으로 머지 차단하는 단계까지는 적용되지 않았습니다. 보호 규칙과 운영 배포 승인 여부는 팀 논의 후 별도로 설정합니다.

3. Webpack 실행 환경과 배포 빌드

Webpack의 mode와 애플리케이션의 배포 환경(APP_ENV)은 서로 다른 개념으로 관리합니다.

3.1. 로컬 개발 서버

  • 명령: pnpm dev
  • Webpack 모드: development
  • 목적: 개발 중 빠른 확인과 문제 추적
  • 특징: HMR, API 프록시, eval-cheap-module-source-map을 사용합니다.

3.2. DEV / PROD 배포 빌드

  • 명령: 두 환경 모두 pnpm build
  • Webpack 모드: 두 환경 모두 production
  • 환경 식별: DEV는 APP_ENV=development, PROD는 APP_ENV=production을 주입합니다.
  • 분리 대상: API 서버, 카카오 지도 키, PostHog 설정, 배포 경로와 Runner를 GitHub Environment 변수로 구분합니다. Sentry 설정 분리는 PR #175에서 추가한 뒤 팀 논의와 운영 검증을 거칠 예정입니다.
  • 공통 최적화: 코드 압축, splitChunks, runtime chunk 분리와 [contenthash] 파일명을 두 배포 환경에 동일하게 적용합니다.
  • Source Map: 현재 frontend-dev의 production 빌드는 일반 source-map을 생성합니다. PR #175에서는 기본적으로 source map을 만들지 않고, Sentry가 활성화되며 업로드 값이 모두 있을 때만 hidden-source-map을 생성해 업로드 후 삭제하도록 변경했습니다. 이 정책은 PR 논의와 머지 후 최종 적용됩니다.

DEV 배포도 실제 배포 조건에서 동작을 검증하는 환경이므로 production 모드로 빌드합니다. APP_ENV=development는 Webpack을 development 모드로 바꾸는 값이 아니라, 애플리케이션과 외부 서비스가 개발 환경임을 구분하는 값입니다.

4. 환경별 CI/CD 파이프라인 구성

4.1. PR 품질 검사

  • frontend-dev 또는 main 대상 PR에서 프론트엔드 코드가 변경되면 Frontend Quality 워크플로가 실행됩니다.
  • 의존성 고정 설치, ESLint, Prettier, TypeScript 검사, Jest 단위·통합 테스트, Storybook 빌드, 애플리케이션 production 빌드를 순서대로 검증합니다.
  • 현재는 Required Status Check가 아니므로, 검사를 실제 머지 조건으로 강제하려면 Branch Protection 설정이 추가로 필요합니다.

4.2. 환경별 자동 배포

  • frontend-dev에 push되면 frontend-development Environment 값과 frontend-dev Runner를 사용하여 DEV 서버에 배포합니다.
  • main push를 기준으로 frontend-production Environment 값과 frontend-prod Runner를 사용하는 PROD 배포 워크플로를 frontend-dev에 구성했습니다.
  • 현재 main 브랜치에는 프론트엔드 PROD 배포 워크플로 파일이 아직 반영되지 않았습니다. 다음 프론트엔드 운영 릴리스에서 main에 워크플로를 포함하고 실제 자동 배포 성공 여부를 검증해야 합니다.

Self-hosted Runner

  • GitHub에서 서버 방화벽을 뚫고 코드를 밀어 넣는 방식인 SSH/SCP은 AWS 접근 키 노출 위험이 존재. EC2 서버 내부에 설치된 Runner가 깃허브로 나가서 결과물을 pull해오는 Self-hosted Runner 방식을 채택. DEV 서버와 PROD 서버에는 각각 분리된 런너 라벨(frontend-dev, frontend-prod)이 부여되어 환경 간 배포가 교차되지 않음.

5. 무중단 배포 및 Nginx 네트워크 환경 설정

5.1. Symbolic Link를 활용한 무중단 배포

  • 새 코드를 배포할 때 덮어쓰기 방식을 사용하면 사용자는 일시적으로 깨진 화면을 보게 되는 문제. 이를 해결하기 위해 빌드 결과물을 releases/커밋해시라는 새 폴더에 다운로드한 뒤, Nginx가 보는 current 바로가기 링크를 한번에 교체(ln -sfn). 이를 통해 짧은 시간 내에 배포가 가능하며, 장애 시 즉각적인 롤백이 가능하다.

5.2. Nginx 리버스 프록시와 HTTPS

  • 리버스 프록시 : 프론트엔드에서 백엔드로 직접 API를 호출하면 Mixed Content, CORS와 같은 브라우저 정책에 막힘. 프론트엔드는 상대 경로(/api/v1/...)로 요청을 보내고, Nginx가 이를 백엔드의 프라이빗 IP로 보내주어(proxy_pass) 네트워크 에러를 해결.
  • HTTPS 적용: 카카오 API 연동 및 브라우저 보안 정책을 충족하기 위해 단일 Nginx 웹 서버에 **Certbot (Let's Encrypt)**을 활용하여 무료로 SSL/TLS 인증서를 발급받고 적용.