Communitygithub.com

배포 패턴

웹 애플리케이션을 위한 배포 워크플로우, CI/CD 파이프라인 패턴, 도커 컨테이너화, 헬스 체크, 롤백 전략 및 프로덕션 준비 체크리스트. CI/CD 설정, 앱 컨테이너화 또는 출시 전 프로덕션 준비 상태를 확인할 때 사용합니다.

배포 패턴란 무엇인가요?

이 스킬은 소프트웨어 개발자와 AI 에이전트(예: 클로드 코드, 커서, 코덱스)가 프로덕션에 안정적이고 안전하게 배포할 수 있도록 지원합니다. 롤링, 블루-그린, 카나리 배포 전략의 장단점과 구체적인 전환 과정을 설명하고, Node.js, Go, Python/Django를 위한 최적화된 멀티 스테이지 도커파일을 제공합니다. GitHub Actions 기반의 전체 CI/CD 파이프라인 예시(테스트, 빌드, 배포 단계)와 함께 헬스 체크 엔드포인트 구현법 및 쿠버네티스 프로브 설정 방법을 다룹니다. 또한 12팩터 앱 환경 설정, Zod를 이용한 설정 유효성 검사, 즉시 롤백 명령어, 배포 전 확인해야 할 프로덕션 준비 체크리스트(애플리케이션, 인프라, 모니터링, 보안, 운영)를 포함하여 DevOps 모범 사례를 종합적으로 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/deployment-patterns

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

배포 패턴은(는) 무엇을 하나요?

프로덕션 배포 워크플로우 및 CI/CD 모범 사례.

활성화 시점

  • CI/CD 파이프라인 설정
  • 애플리케이션 도커화
  • 배포 전략 수립 (블루-그린, 카나리, 롤링)
  • 헬스 체크 및 준비성 프로브 구현
  • 프로덕션 릴리스 준비
  • 환경별 설정 구성

배포 전략

롤링 배포 (기본값)

인스턴스를 점진적으로 교체합니다 — 롤아웃 중에는 구버전과 신버전이 동시에 실행됩니다.

인스턴스 1: v1 → v2  (첫 번째 업데이트)
인스턴스 2: v1        (여전히 v1 실행)
인스턴스 3: v1        (여전히 v1 실행)

인스턴스 1: v2
인스턴스 2: v1 → v2  (두 번째 업데이트)
인스턴스 3: v1

인스턴스 1: v2
인스턴스 2: v2
인스턴스 3: v1 → v2  (마지막 업데이트)

장점: 제로 다운타임, 점진적 롤아웃 단점: 두 버전이 동시에 실행됨 — 하위 호환성 필요 사용 시기: 표준 배포, 하위 호환 변경

블루-그린 배포

두 개의 동일한 환경을 실행합니다. 트래픽을 원자적으로 전환합니다.

Blue  (v1) ← 트래픽
Green (v2)   대기 중, 신버전 실행

# 확인 후:
Blue  (v1)   대기 (예비로 전환)
Green (v2) ← 트래픽

장점: 즉시 롤백 (블루로 전환), 깔끔한 절체 단점: 배포 중 2배의 인프라 필요 사용 시기: 중요 서비스, 문제 허용 불가

카나리 배포

먼저 전체 트래픽의 일부만 신버전으로 라우팅합니다.

v1: 95% 트래픽
v2:  5% 트래픽  (카나리)

# 메트릭 양호 시:
v1: 50% 트래픽
v2: 50% 트래픽

# 최종:
v2: 100% 트래픽

장점: 전체 롤아웃 전에 실제 트래픽으로 문제 발견 단점: 트래픽 분할 인프라, 모니터링 필요 사용 시기: 대규모 트래픽 서비스, 위험한 변경, 기능 플래그

도커

멀티 스테이지 Dockerfile (Node.js)

# 1단계: 의존성 설치
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production=false

# 2단계: 빌드
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
RUN npm prune --production

# 3단계: 프로덕션 이미지
FROM node:22-alpine AS runner
WORKDIR /app

RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
USER appuser

COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/package.json ./

ENV NODE_ENV=production
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

CMD ["node", "dist/server.js"]

멀티 스테이지 Dockerfile (Go)

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server

FROM alpine:3.19 AS runner
RUN apk --no-cache add ca-certificates
RUN adduser -D -u 1001 appuser
USER appuser

COPY --from=builder /server /server

EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:8080/health || exit 1
CMD ["/server"]

멀티 스테이지 Dockerfile (Python/Django)

FROM python:3.12-slim AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY requirements.txt .
RUN uv pip install --system --no-cache -r requirements.txt

FROM python:3.12-slim AS runner
WORKDIR /app

RUN useradd -r -u 1001 appuser
USER appuser

COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
COPY . .

ENV PYTHONUNBUFFERED=1
EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=3s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health/')" || exit 1
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]

도커 모범 사례

# 좋은 관행
- 특정 버전 태그 사용 (node:22-alpine, node:latest 지양)
- 이미지 크기 최소화를 위한 멀티 스테이지 빌드
- 루트가 아닌 사용자로 실행
- 의존성 파일 먼저 복사 (레이어 캐싱 활용)
- node_modules, .git, 테스트 제외를 위한 .dockerignore 사용
- HEALTHCHECK 명령어 추가
- docker-compose 또는 k8s에서 리소스 제한 설정

# 나쁜 관행
- 루트로 실행
- :latest 태그 사용
- 전체 저장소를 하나의 COPY 레이어로 복사
- 프로덕션 이미지에 개발 의존성 설치
- 이미지에 시크릿 저장 (환경 변수 또는 시크릿 매니저 사용)

CI/CD 파이프라인

GitHub Actions (표준 파이프라인)

name: CI/CD

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm test -- --coverage
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: coverage
          path: coverage/

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: production
    steps:
      - name: Deploy to production
        run: |
          # 플랫폼별 배포 명령어
          # Railway: railway up
          # Vercel: vercel --prod
          # K8s: kubectl set image deployment/app app=ghcr.io/${{ github.repository }}:${{ github.sha }}
          echo "Deploying ${{ github.sha }}"

파이프라인 단계

PR 열림:
  lint → typecheck → 단위 테스트 → 통합 테스트 → 프리뷰 배포

main에 병합됨:
  lint → typecheck → 단위 테스트 → 통합 테스트 → 이미지 빌드 → 스테이징 배포 → 스모크 테스트 → 프로덕션 배포

헬스 체크

헬스 체크 엔드포인트

// 간단한 헬스 체크
app.get("/health", (req, res) => {
  res.status(200).json({ status: "ok" });
});

// 상세 헬스 체크 (내부 모니터링용)
app.get("/health/detailed", async (req, res) => {
  const checks = {
    database: await checkDatabase(),
    redis: await checkRedis(),
    externalApi: await checkExternalApi(),
  };

  const allHealthy = Object.values(checks).every(c => c.status === "ok");

  res.status(allHealthy ? 200 : 503).json({
    status: allHealthy ? "ok" : "degraded",
    timestamp: new Date().toISOString(),
    version: process.env.APP_VERSION || "unknown",
    uptime: process.uptime(),
    checks,
  });
});

async function checkDatabase(): Promise<HealthCheck> {
  try {
    await db.query("SELECT 1");
    return { status: "ok", latency_ms: 2 };
  } catch (err) {
    return { status: "error", message: "Database unreachable" };
  }
}

쿠버네티스 프로브

livenessProbe:
  httpGet:
    path: /health
    port: 3000
  initialDelaySeconds: 10
  periodSeconds: 30
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /health
    port: 3000
  initialDelaySeconds: 5
  periodSeconds: 10
  failureThreshold: 2

startupProbe:
  httpGet:
    path: /health
    port: 3000
  initialDelaySeconds: 0
  periodSeconds: 5
  failureThreshold: 30    # 30 * 5s = 150s 최대 시작 시간

환경 설정

12팩터 앱 패턴

# 모든 설정은 환경 변수로 — 절대 코드에 포함하지 않음
DATABASE_URL=postgres://user:pass@host:5432/db
REDIS_URL=redis://host:6379/0
API_KEY=${API_KEY}           # 시크릿 매니저에 의해 주입
LOG_LEVEL=info
PORT=3000

# 환경별 동작
NODE_ENV=production          # 또는 staging, development
APP_ENV=production           # 명시적 앱 환경

설정 유효성 검사

import { z } from "zod";

const envSchema = z.object({
  NODE_ENV: z.enum(["development", "staging", "production"]),
  PORT: z.coerce.number().default(3000),
  DATABASE_URL: z.string().url(),
  REDIS_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
  LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
});

// 시작 시 검증 — 설정이 잘못되면 빠르게 실패
const env = envSchema.parse(process.env);

롤백 전략

즉시 롤백

# 도커/쿠버네티스: 이전 이미지로 전환
kubectl rollout undo deployment/app

# Vercel: 이전 배포로 승격
vercel rollback

# Railway: 이전 커밋으로 재배포
railway up --commit <이전 SHA>

# 데이터베이스: 마이그레이션 롤백 (되돌릴 수 있는 경우)
npx prisma migrate resolve --rolled-back <마이그레이션 이름>

롤백 체크리스트

  • 이전 이미지/아티팩트를 사용할 수 있고 태그가 지정되었는가
  • 데이터베이스 마이그레이션이 하위 호환되는가 (파괴적 변경 없음)
  • 기능 플래그로 배포 없이 새 기능을 비활성화할 수 있는가
  • 오류율 급증에 대한 모니터링 알림이 설정되었는가
  • 프로덕션 릴리스 전에 스테이징에서 롤백을 테스트했는가

프로덕션 준비 체크리스트

프로덕션 배포 전:

애플리케이션

  • 모든 테스트 통과 (단위, 통합, E2E)
  • 코드나 설정 파일에 하드코딩된 시크릿 없음
  • 오류 처리가 모든 엣지 케이스를 다룸
  • 로깅이 구조화되어 있고 (JSON) PII를 포함하지 않음
  • 헬스 체크 엔드포인트가 의미 있는 상태를 반환함

인프라

  • 도커 이미지가 재현 가능하게 빌드됨 (고정된 버전)
  • 환경 변수가 문서화되고 시작 시 검증됨
  • 리소스 제한 설정됨 (CPU, 메모리)
  • 수평 확장 구성됨 (최소/최대 인스턴스)
  • 모든 엔드포인트에 SSL/TLS 활성화

모니터링

  • 애플리케이션 메트릭 내보내기 (요청 속도, 지연 시간, 오류)
  • 오류율이 임계값을 초과하면 알림 설정
  • 로그 집계 설정 (구조화된 로그, 검색 가능)
  • 헬스 엔드포인트에 대한 가동 시간 모니터링

보안

  • 의존성에서 CVE 스캔
  • CORS를 허용된 오리진으로만 구성
  • 공용 엔드포인트에 속도 제한 활성화
  • 인증 및 권한 부여 확인
  • 보안 헤더 설정 (CSP, HSTS, X-Frame-Options)

운영

  • 롤백 계획 문서화 및 테스트 완료
  • 프로덕션 규모 데이터 대상으로 데이터베이스 마이그레이션 테스트
  • 일반적인 장애 시나리오에 대한 런북
  • 온콜 로테이션 및 에스컬레이션 경로 정의

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

관련 스킬