✍️ 필사 모드: 프런트엔드 CI/CD·배포 전략 2025 — GitHub Actions·Turborepo·Vercel·Cloudflare·Preview·Canary·Feature Flag·SLSA·SBOM 완전 가이드
한국어프롤로그 — "프라이데이 배포하지 마세요"
10년 전 엔지니어링 문화에서 금요일 배포는 금기였다. 뭔가 터지면 주말 없이 밤샘해야 했기 때문이다. 2025년에는 이 격언이 많이 낡았다. 세상의 많은 팀은 금요일에도 하루 수십 번 배포한다. 무엇이 바뀌었는가?
바뀐 건 세 가지다:
- 배포 파이프라인이 자동화됐다 — 사람의 실수 개입 여지가 줄었다
- Preview Deployment가 기본이 됐다 — 프로덕션 전에 실제 환경과 동일한 URL로 검증
- Progressive Delivery — Canary, Feature Flag로 "일부 사용자에게만" 먼저 배포
2025년의 주요 전환점:
- Monorepo Build Cache의 대중화 — Turborepo·Nx·Bazel의 Remote Cache가 무료/저렴하게 제공. 첫 빌드 10분이 두 번째 빌드 10초로
- Edge-first 배포 — Vercel·Cloudflare·Netlify의 Edge Function + Static 하이브리드
- AI 에이전트의 PR 배포 — Copilot·Cursor·Claude Code가 브랜치 생성→PR→배포까지
- 공급망 보안 의무화 — EU CRA, 미국 EO 14028, SLSA Level 3, SBOM 제출 요구 확산
이번 글에서는 13개 챕터로 CI/CD·배포 전략을 정리한다.
1장 · CI/CD 기본 용어 재정리
네 가지 개념
- CI (Continuous Integration) — 코드 변경을 자주 merge + 자동 빌드·테스트
- CD (Continuous Delivery) — merge 후 언제든 배포 가능한 상태 유지
- CD (Continuous Deployment) — merge → 자동 프로덕션 배포
- Progressive Delivery — Canary·Feature Flag로 점진적 전달
배포 지표 — DORA 4가지
Google의 DevOps Research and Assessment가 만든 표준:
| 지표 | Elite | High | Medium | Low |
|---|---|---|---|---|
| Deployment Frequency | 하루 여러 번 | 주 1회+ | 월 1회 | 6개월 |
| Lead Time for Changes | 1시간 미만 | 1일 미만 | 1주~1개월 | 1~6개월 |
| Change Failure Rate | 0~15% | 16~30% | 16~30% | 46~60% |
| Mean Time to Restore | 1시간 미만 | 1일 미만 | 1일~1주 | 1주~1개월 |
2023년 DORA 보고서는 Stability(MTTR·Change Failure Rate) + Throughput(Frequency·Lead Time) 균형이 핵심이라고 정리. "빠른 배포"만이 아니라 "안전한 빠른 배포"가 엘리트.
2장 · GitHub Actions — 2025 de facto 표준
왜 Actions가 이겼나
- GitHub 내장 — 별도 계정·설정 없음
- Marketplace — 20,000+ 공개 Action
- 매트릭스 빌드 — Node 18·20·22 × OS 3종 병렬
- Reusable Workflow — DRY
- Artifact·Cache 내장
기본 CI 워크플로우
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm test
- run: pnpm build
Concurrency — 동일 브랜치 이전 실행 취소
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
PR에 push를 여러 번 할 때 이전 실행을 자동 취소 → 비용 절감.
OIDC로 클라우드 자격 증명 관리
긴 수명의 AWS_ACCESS_KEY_ID를 GitHub Secrets에 저장하는 시대는 끝났다. OIDC Federation으로 토큰이 매번 새로 발급되고, GitHub Actions → AWS·GCP·Azure로 안전하게 인증.
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/github-actions-role
aws-region: ap-northeast-2
대안들
- CircleCI — Parallelism 세밀, Docker Executor
- Buildkite — Self-hosted agent, 엔터프라이즈
- GitLab CI — GitLab 쓰면 자연스럽다
- Jenkins — 여전히 레거시 엔터프라이즈 표준
2025 스타트업·중소규모: GitHub Actions가 기본. 빌드 시간이 수십 분이거나 비용이 문제되면 self-hosted runner 병행.
3장 · Monorepo — Turborepo·Nx·Bazel
왜 모노레포인가
- 프런트엔드(web·mobile·admin) + 디자인 시스템 + 공용 라이브러리를 한 저장소에
- Lockstep 버전 관리, 원자적 PR
- 공통 ESLint·TS·Test 설정 공유
Turborepo — Vercel 인수, Rust로 재작성 중
npx create-turbo@latest my-monorepo
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"test": {
"dependsOn": ["build"],
"outputs": []
},
"dev": { "cache": false, "persistent": true }
}
}
Remote Cache — 협업 캐시
npx turbo login
npx turbo link
내 PC에서 빌드한 결과를 팀원과 CI가 공유. "이미 빌드한 거 또 안 함" → CI 시간 80% 감소 사례 다수.
Nx — 엔터프라이즈 모노레포
npx create-nx-workspace@latest
Turborepo 대비:
- Nx Graph — 의존 관계 시각화
- Generators — 새 앱·라이브러리 템플릿
- Affected — 변경된 프로젝트만 빌드 (
nx affected -t test) - Nx Cloud Remote Cache
Angular 생태계에서 출발했지만 React·Vue·Svelte·Node 지원.
Bazel — Google 스케일
수천 개 패키지·다언어(C++·Go·Java·TS) 섞인 초대형 모노레포에서만 의미. 셋업 비용이 크다. Uber·Airbnb·Spotify 사례.
2025 선택
- 단순·빠른: Turborepo
- 다양한 기능·시각화: Nx
- 초대형·다언어: Bazel
- 아주 단순: npm workspaces + 그냥 스크립트
4장 · 배포 플랫폼 — Vercel·Netlify·Cloudflare Pages·AWS Amplify
Vercel
- Next.js 친화 (Vercel이 Next 개발사)
- Preview Deployment 원조 — 모든 PR·브랜치에 고유 URL
- Edge Function + Serverless Function 하이브리드
- Speed Insights·Analytics 통합
- 비용: 호비 무료, 상용은 높은 편
Netlify
- Jamstack 원조
- Build Plugin 생태계
- Edge Function (Deno 런타임)
- Forms·Identity 기본 제공
- Vercel과 유사한 UX, 가격 약간 저렴
Cloudflare Pages + Workers
- CDN 자체가 강점 — 330+ 도시 Edge
- Workers — V8 isolate 기반 경량 Edge
- KV·D1·R2·Durable Objects — Full stack 백엔드
- 비용이 매우 저렴 — Free tier 관대
- Next.js SSR 완벽 지원은 여전히 발전 중(OpenNext)
AWS Amplify
- AWS 리소스(Lambda·Cognito·AppSync) 통합
- 대기업·이미 AWS 사용 조직에 자연스러움
- UX는 Vercel/Netlify보다 투박
선택 기준
- Next.js·React 중심 + Simplicity: Vercel
- 다양한 프레임워크·Build Plugin: Netlify
- 비용·Edge 성능·Full stack 서버리스: Cloudflare
- 이미 AWS 기반: Amplify
5장 · Preview Deployment — 리뷰 문화의 혁명
왜 혁명적인가
- 코드 리뷰 + 실제 동작하는 URL 리뷰가 결합
- 디자이너·PM·QA가 PR 단계에서 직접 검증
- "머지하고 보자"가 아니라 "머지 전에 보고 결정"
동작 방식
- PR 생성 또는 push
- CI가 빌드 → 고유 URL(
branch-name--project.vercel.app)에 배포 - PR에 자동 코멘트로 URL 게시
- 코멘트·툴바로 피드백
Vercel 기본 동작
별 설정 없이 GitHub 연결 → 모든 PR Preview 자동.
Self-host 구현
- AWS S3 + CloudFront + Route53 서브도메인
- Cloudflare Pages + Wrangler
- Kubernetes + Argo Rollouts + Namespace
Preview URL과 환경변수
- Preview에도 DB 접근이 필요 → Preview DB(Neon·PlanetScale branch)
- 실 서비스 DB 접근 금지 (데이터 오염 방지)
- 피처 플래그는 보통 Preview는 모든 플래그 On
2024~2025 확장 — Stagewise·Toolbar
- 페이지 위에 띄우는 "리뷰 오버레이" 툴
- 디자이너가 요소 클릭 → 코멘트 남기기
- Vercel Toolbar, v0, Stagewise가 대표 사례
6장 · Progressive Delivery — Canary·Blue-Green·Feature Flag
Blue-Green Deployment
- 현재 프로덕션(Blue)과 별도로 새 버전(Green)을 완전히 배포
- LB 스위치 한 번으로 전환
- 문제 시 즉시 롤백 가능
Canary Deployment
- 새 버전을 일부 트래픽(1%·5%·25%)에만 점진 공개
- 에러율·지연·전환율을 모니터링하며 단계적 확대
- 실패 시 해당 단계에서 롤백
Feature Flag
- 배포와 기능 공개를 분리한다
- 코드는 배포되었지만, 플래그로 on/off 제어
- 세그먼트별 공개 가능 (특정 회사·국가·플랜)
- A/B Test·Experiment도 동일 인프라
Feature Flag 서비스 2025
- LaunchDarkly — 엔터프라이즈 표준
- Flagsmith — 오픈소스 가능
- Unleash — 오픈소스 + SaaS
- PostHog Feature Flags — Analytics·Replay와 통합
- Vercel Edge Config + Feature Flags — 2024년 출시, 초저지연
구현 예
import { getAllFlags } from "@vercel/flags/next";
const flags = await getAllFlags();
if (flags["checkout-v2"]) {
return <CheckoutV2 />;
}
Canary + Feature Flag 조합
- 코드 100% 배포 (Canary 100%)
- 기능은 Flag로 1% → 10% → 50% → 100% 점진 공개
- 문제 시 재배포 없이 플래그만 off
2025년의 권장 패턴: "Deploy ≠ Release". 배포는 상시, 릴리스는 제품 의사결정.
7장 · Rollback 전략 — "언제든 되돌릴 수 있는가?"
자동 Rollback 조건
- Canary 단계에서 에러율 > P50 * 2
- Core Web Vitals 회귀 (LCP p75 > 2.5s)
- Synthetic Test 실패
수동 Rollback
- Vercel: PR Revert + Redeploy (또는 이전 배포 Promote)
- Netlify·Cloudflare도 동일
- 쿠버네티스:
kubectl rollout undo
Database Migration의 함정
코드는 쉽게 롤백돼도 DB 스키마 변경은 비가역. 2025 권장 패턴:
- Expand — 새 컬럼·테이블 추가 (기존 코드와 호환)
- Migrate — 새 코드 배포, 점진적 이동
- Contract — 구 컬럼·테이블 제거 (새 코드가 안정화된 후)
이 Expand-Contract 패턴 덕분에 언제든 직전 배포로 안전 롤백.
Feature Flag의 Rollback 역할
- 배포 롤백보다 Flag off가 훨씬 빠름 (초 단위)
- 하지만 Flag에만 의존하지 말고 실제 Revert도 옵션으로 유지
8장 · CDN·ISR·Cache Invalidation
Frontend 배포의 Cache 3계층
- Browser Cache — 브라우저 내 (
Cache-Control) - CDN Cache — Edge 노드 (Vercel·Cloudflare·CloudFront)
- Origin Cache — 서버 레벨 (Redis·Memcached)
Next.js ISR (Incremental Static Regeneration)
- 빌드 시 정적 생성
- 요청 시 "오래됨" 체크 →
revalidate주기 지나면 재생성 - 재생성 중에도 기존 페이지 서빙 (Stale-While-Revalidate)
// App Router
export const revalidate = 3600; // 1시간마다 재생성
// Page Router
export async function getStaticProps() {
return { props, revalidate: 3600 };
}
On-demand Revalidation
// 관리자가 상품 수정 시
import { revalidateTag, revalidatePath } from "next/cache";
revalidateTag("products");
revalidatePath("/products/[id]", "page");
Cache Invalidation의 어려움
"There are only two hard things in Computer Science: cache invalidation and naming things." — Phil Karlton
실전:
- Hash 기반 파일명 (Next·Vite·Turbopack) → 신버전은 새 URL
- Tag 기반 무효화 (Next.js 14+) → 연관 데이터 그룹 단위
- Purge API (Cloudflare·Fastly) → 특정 URL 즉시 삭제
- Stale-While-Revalidate 기본값 → 사용자 경험 우선
9장 · Edge·Regional·Serverless 배포
Edge — 전 세계 CDN 노드 실행
- V8 Isolate 기반 (Vercel Edge, Cloudflare Workers)
- Cold Start 거의 없음 (ms 단위)
- 제약: Node.js API 일부 제한, 번들 크기 제한
- 적합: 인증·지역 라우팅·A/B·개인화 경량 로직
Regional Function — 특정 Region 서버리스
- AWS Lambda, Vercel Serverless Functions
- Node.js 완전 호환
- Cold Start 100ms~수 초
- 적합: DB 의존 복잡 로직, 파일·이미지 처리
Static + Edge Revalidation
- 빌드 시 정적 HTML 생성 → CDN 배포
- 동적 부분만 Edge Function 또는 RSC streaming
- 2025 Next.js **PPR (Partial Prerendering)**이 이 모델
"Runtime 선언"
export const runtime = "edge"; // 또는 "nodejs"
페이지·API마다 실행 환경 선택. Edge가 빠르지만 npm 라이브러리 호환성 낮음.
10장 · Artifact·Build Cache·Remote Cache
빌드 결과물을 공유한다는 것
CI가 매번 npm install·tsc·webpack을 돌리면 시간·비용 폭발. 이미 같은 input으로 빌드된 결과는 재사용.
GitHub Actions Cache
- uses: actions/cache@v4
with:
path: |
~/.pnpm-store
.next/cache
key: ${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
Turborepo Remote Cache
- 로컬·CI·팀원 간 공유
- Vercel 기본 제공 또는 자체 호스팅(S3·R2)
TURBO_TOKEN=... TURBO_TEAM=... turbo run build
Nx Cloud
- 유사 개념
- Distributed Task Execution(DTE)으로 병렬 실행 자동 분산
Docker Layer Cache
- Dockerfile 명령어별 레이어 캐시
FROM node:22-alpine→COPY package.json→RUN install순서가 중요- 자주 바뀌는 파일을 뒤에 둬서 캐시 히트 최대화
11장 · Supply Chain 보안 — SLSA·SBOM·Sigstore
왜 의무화됐나
- 2020 SolarWinds 사건 (국가급 공급망 공격)
- 2021 US Executive Order 14028 — 정부 납품 SW는 SBOM 제출
- 2024 EU Cyber Resilience Act — 2027년 완전 적용
SBOM (Software Bill of Materials)
내가 사용하는 모든 직접·transitive 의존성 목록. 제품의 성분표.
포맷:
- SPDX (Linux Foundation)
- CycloneDX (OWASP)
생성:
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
# 또는
syft packages npm:. -o spdx-json
SLSA (Supply chain Levels for Software Artifacts)
Google 주도. Level 1~4로 공급망 보안 수준 표준화.
- Level 1: 빌드 기록 존재
- Level 2: 서명된 provenance
- Level 3: 격리된 빌드 환경, 변조 방지
- Level 4: 재현 가능한 빌드, 두 사람 리뷰
Sigstore·cosign
- 소프트웨어 아티팩트(컨테이너 이미지·npm 패키지·바이너리)에 서명
- 공개키 인프라(PKI)가 아닌 키 없는 서명 (Keyless, OIDC 기반)
cosign sign --keyless ghcr.io/me/app:1.0
cosign verify --certificate-identity-regexp ...
npm Provenance
- 2023년 출시
- npm publish 시 GitHub Actions OIDC로 서명
npm install시 검증 가능
npm publish --provenance
한국 맥락
- ISMS-P 인증 범위에 공급망 보안 추가 논의
- 정부·금융·공공 조달에서 SBOM 요구 확산
12장 · AI 에이전트가 릴리스 PR을 만드는 2025
2024년 말~2025년의 변화
- Dependabot이 매일 수천 개 PR 생성·자동 머지
- Renovate Bot이 설정된 규칙대로 의존성 업그레이드 + 테스트 + 머지
- Claude Code·Cursor·Devin이 이슈 → 브랜치 → PR → Review → Merge 전체 자동화
자동 릴리스 PR 패턴
- 이슈 라벨링 (
type:feature,impact:low) - AI가 이슈를 읽고 변경 계획 제안
- 사람 승인 → 에이전트가 브랜치·PR 생성
- CI 통과 + 사람 리뷰 (Code·Preview URL)
- 머지 → 자동 배포 → Canary 단계별 모니터링
리스크
- 자동 머지의 범위: 의존성 patch는 OK, 프로덕션 로직은 사람이
- 롤백 권한: AI가 만든 배포라도 롤백은 사람이
- 감사 로그: "이 배포 누가 만들었나" 추적 가능해야
2025의 권장
- Dependabot·Renovate은 이미 안전. 즉시 도입.
- 에이전트 기반 기능 구현은 점진 도입, 위험도 낮은 곳부터.
- 문서·테스트·번역이 AI 에이전트에 가장 적합.
13장 · 체크리스트·안티패턴·다음 글 예고
CI/CD 체크리스트 (15개)
- GitHub Actions(또는 CircleCI) 기본 CI: lint·test·build
- Concurrency cancel-in-progress로 중복 실행 취소
- OIDC 인증으로 클라우드 자격 증명 관리
- Turborepo/Nx Remote Cache로 빌드 시간 단축
- Preview Deployment 모든 PR에 자동
- Preview DB 분리 (Neon·PlanetScale branch)
- Feature Flag 기본 탑재 (LaunchDarkly·PostHog·Vercel)
- Canary/Blue-Green로 Progressive Delivery
- 자동 Rollback 조건 정의 (에러율·Vitals 회귀)
- Expand-Contract DB 마이그레이션 패턴
- ISR + 태그 기반 Revalidation
- Edge vs Regional 적재 적소 선택
- SBOM 생성 CI에 통합
- npm/docker provenance 서명
- DORA 4 지표 팀 대시보드
CI/CD 안티패턴 TOP 10
- 모든 환경 변수를 GitHub Secrets에 평문 저장
- Secrets를 PR 로그에 출력 (
echo ${{ secrets.X }}) - Canary 없이 Big-Bang 배포
- Feature Flag를 영구적으로 유지 → dead code 폭발
- Preview에서 프로덕션 DB 접근
- 빌드 시간 30분+ 방치
- DB 마이그레이션과 코드 배포 동시 (롤백 불가)
- CI 실패를 "그냥 재실행" (Flaky 방치)
- 배포 후 모니터링 미확인
- 의존성 업데이트를 분기별로 수동 일괄 (위험 누적)
다음 글 예고 — Season 6 Ep 13 FINALE: "2025년 프런트엔드 엔지니어로 살아가기"
Season 6의 마지막 글. 기술을 넘어 프런트엔드 엔지니어로서의 일하기·성장하기·커뮤니티.
- 2025년 프런트엔드의 지도 (RSC·Signals·AI·Edge)
- 풀스택 vs 스페셜리스트 vs 디자인 엔지니어
- 커뮤니티와 오픈소스 참여
- 컨퍼런스·블로그·트위터(X)의 힘
- AI와 공존하며 성장하기
- 번아웃과 지속 가능한 학습
- 한국 프런트엔드 생태계의 과제와 기회
- 다음 10년을 어떻게 준비할까
"기술은 도구다. 도구는 사람을 위한 것이다. 프런트엔드는 결국 '사람이 쓸 것'을 만드는 일이다."
다음 글에서 만나자.
"CI/CD는 코드와 사용자 사이의 다리다. 다리가 튼튼하고 자동으로 점검되고 무너져도 수 분 내 수리되는 상태가 되면, 엔지니어는 **'배포가 아니라 제품'**에 집중할 수 있다. 이게 2025년의 성숙한 팀이다."
현재 단락 (1/295)
10년 전 엔지니어링 문화에서 **금요일 배포는 금기**였다. 뭔가 터지면 주말 없이 밤샘해야 했기 때문이다. 2025년에는 이 격언이 많이 낡았다. **세상의 많은 팀은 금요일에...