07 / 09
CI/CD & 배포
Jenkins 기반 프론트엔드 CI/CD, monorepo npm workspace 빌드, S3 sync 배포, CloudFront Invalidation
CI/CD 전환 배경
통합 포탈 서비스는 기존 백엔드(auth) 서비스용 Jenkins 파이프라인을 기반으로 프론트엔드 배포 파이프라인을 새로 구성하였습니다. auth는 백엔드에서, 통합 포탈 서비스는 프론트엔드에서 사용하는 구조이기 때문에 기존 파이프라인의 Docker/ECR/ECS 관련 스텝을 제거하고, S3 + CloudFront 기반 정적 배포로 전환하였습니다.
기존 파이프라인 (백엔드)
Docker build / run
컨테이너 포트 3000 설정
PROD ECR 이미지 Push
ECS 서비스 업데이트
전환된 파이프라인 (프론트엔드)
npm workspace 기반 React 빌드
S3 sync --delete 배포
CloudFront Invalidation
환경별 (dev/prod) 분기
기존 파이프라인에서 제거/변경된 포인트
기존 Jenkins 파이프라인은 백엔드 서비스(auth) 배포를 위해 Docker 빌드 → ECR Push → ECS 업데이트 흐름으로 구성되어 있었습니다. 포탈 서비스는 프론트엔드 SPA이므로 이 흐름이 불필요하며, 배포 핵심이 S3 sync + CloudFront Invalidation으로 변경됩니다.
| 기존 스텝 | 변경 사항 | 사유 |
|---|---|---|
| Docker build / run | 제거 | 프론트엔드는 정적 빌드 산출물만 필요 |
| 컨테이너 포트 3000 설정 | 제거 | 컨테이너 실행 불필요 |
| ECR 이미지 Push | 제거 | Docker 이미지 불필요 |
| ECS 서비스 업데이트 | 제거 | 백엔드 전용 스텝 |
| 빌드 산출물 처리 | S3 sync로 변경 | 정적 파일을 S3에 직접 배포 |
| 배포 후 반영 | CloudFront Invalidation 추가 | CDN 캐시 갱신 필요 |
프론트엔드 CI/CD 파이프라인 구조
monorepo 구조 + npm workspace를 사용하며, @connect-portal/react 패키지의 빌드 산출물(packages/react/dist)을 S3에 배포합니다.
배포 흐름
ENV (dev/prod) 선택
Jenkins 파라미터로 배포 대상 환경을 선택합니다. 환경에 따라 S3 버킷과 CloudFront Distribution ID가 분기됩니다.
선택한 환경에 맞게 React 빌드
npm workspace 기반으로 @connect-portal/react 패키지만 빌드합니다. 환경별 .env 파일이 적용되어 API 엔드포인트 등이 분기됩니다.
S3 sync --delete 배포
빌드 산출물(packages/react/dist)을 대상 S3 버킷에 동기화합니다. --delete 옵션으로 이전 버전의 불필요한 파일을 자동 정리합니다.
CloudFront Invalidation
배포 완료 후 CloudFront 캐시를 무효화하여 사용자에게 즉시 최신 버전이 제공되도록 합니다.
Jenkinsfile 핵심 구조
전제: monorepo 구조 + npm workspace 사용. 빌드 대상은 @connect-portal/react 패키지이며, 산출물은 packages/react/dist 디렉토리입니다.
pipeline {
agent any
parameters {
choice(name: 'ENV', choices: ['dev', 'prod'],
description: '배포 환경 선택')
}
environment {
S3_BUCKET_DEV = 'connect-portal-dev'
S3_BUCKET_PROD = 'connect-portal-prod'
CF_DIST_DEV = 'EXXXXXXXXXXXDEV'
CF_DIST_PROD = 'EXXXXXXXXXXXPROD'
}
stages {
stage('Install') {
steps { sh 'npm ci' }
}
stage('Build') {
steps {
sh "npm run build -w @connect-portal/react"
}
}
stage('Deploy to S3') {
steps {
script {
def bucket = params.ENV == 'prod'
? env.S3_BUCKET_PROD : env.S3_BUCKET_DEV
sh """
aws s3 sync packages/react/dist \
s3://${bucket} --delete
"""
}
}
}
stage('CloudFront Invalidation') {
steps {
script {
def distId = params.ENV == 'prod'
? env.CF_DIST_PROD : env.CF_DIST_DEV
sh """
aws cloudfront create-invalidation \
--distribution-id ${distId} \
--paths "/*"
"""
}
}
}
}
}dev 브랜치 전용 배포 파이프라인
dev 환경은 별도의 파이프라인으로 분리하여, dev 브랜치에 push 시 자동으로 빌드 및 배포가 수행되도록 구성하였습니다. prod 배포는 수동 트리거(Jenkins 파라미터 선택)로만 실행됩니다.
dev 환경
• dev 브랜치 push 시 자동 트리거
• dev S3 버킷 + dev CloudFront 배포
• 빠른 피드백 루프
prod 환경
• 수동 트리거 (Jenkins 파라미터)
• prod S3 버킷 + prod CloudFront 배포
• 배포 전 확인 절차
배포 후 Smoke Test (보류)
배포 후 자동 smoke test 단계를 추가하여 주요 페이지 접근 가능 여부, API 연동 상태 등을 검증하는 방안을 검토 중입니다. 현재는 수동 확인으로 대체하고 있으며, 향후 자동화 예정입니다.
Summary
통합 포탈 서비스의 CI/CD는 기존 백엔드 파이프라인에서 Docker/ECR/ECS 관련 스텝을 제거하고, monorepo + npm workspace 기반 React 빌드 → S3 sync → CloudFront Invalidation으로 전환하였습니다. 환경별 분기(dev/prod)를 통해 안전한 배포 흐름을 확보하였으며, dev 브랜치는 자동 배포, prod는 수동 트리거로 운영합니다.