블로그로 돌아가기
Python

fastapi 배포 방법: 실무 배포 가이드와 모범 사례

fastapi 배포 방법을 단계별로 정리한 실무 가이드입니다. Docker 이미지 생성, Uvicorn/Gunicorn 설정, 리버스 프록시 구성, CI/CD 적용과 운영 시 주의점을 포함해 바로 적용 가능합니다.

FastAPIDockerUvicorn배포 자동화CI/CD
FastAPI 배포 과정을 설명하는 다이어그램이 포함된 기술 블로그 썸네일

fastapi 배포 방법이 필요한 상황

fastapi 배포 방법을 알고 있으면 개발한 API를 안정적으로 운영 서버에 배포하고, 자동화된 파이프라인과 모니터링을 통해 운영 리스크를 줄일 수 있습니다. 이 글에서는 Docker 기반 이미지 빌드, Uvicorn/Gunicorn 실행, Nginx 리버스 프록시, CI/CD 파이프라인 예제와 운영·보안 주의점을 실무 중심으로 다룹니다. 최종 목표는 로컬에서 만든 FastAPI 앱을 프로덕션 환경에 신뢰성 있게 배포하는 것입니다.

fastapi 배포 방법 핵심 개념

  • 프로세스 관리: Uvicorn(ASGI) 단독 실행 또는 Gunicorn + Uvicorn 워커 조합
  • 컨테이너화: Dockerfile을 통한 이미지 표준화
  • 리버스 프록시: Nginx로 TLS 종료 및 정적 자원 서빙
  • 오케스트레이션/배포 자동화: Docker Compose, Kubernetes, 또는 CI/CD (GitHub Actions/GitLab CI)
  • 모니터링/로깅: Prometheus, Grafana, Sentry 등

fastapi 배포 방법 실무 예제

아래 예제는 Dockerfile + Uvicorn으로 컨테이너를 만들고 Nginx로 리버스 프록시하는 간단한 흐름입니다.

# Dockerfile FROM python:3.11-slim WORKDIR /app COPY pyproject.toml poetry.lock /app/ RUN pip install --upgrade pip && pip install poetry && poetry config virtualenvs.create false && poetry install --no-dev COPY . /app ENV PYTHONUNBUFFERED=1 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]

간단한 docker-compose.yml 예시:

version: '3.8' services: web: build: . ports: - "8000:8000" restart: always nginx: image: nginx:stable ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - web

nginx.conf 예시 (리버스 프록시):

server { listen 80; server_name example.com; location / { proxy_pass http://web:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

언제 쓰면 좋고 언제 피해야 할까

언제 쓰면 좋은가

  • 빠르게 API를 만들고 경량화된 비동기 처리가 필요할 때
  • Python 기반 서비스에서 높은 개발 생산성을 원할 때
  • 컨테이너 기반 배포(DevOps)를 적용하려는 경우

언제 피해야 하는가

  • 이미 대규모 동기 워크로드와 복잡한 미들웨어가 많아 호환 이슈가 우려될 때
  • 팀에 Python 운영 경험이 전무하고 다른 언어(예: Go, Java)에 더 익숙할 때
  • 레거시 인프라에서 ASGI 전환 비용이 클 때

배포 옵션 비교표

구분항목1항목2항목3
내용단일 UvicornGunicorn + Uvicorn 워커Kubernetes + Horizontal scaling
내용간단, 낮은 오버헤드프로세스 관리, 재시작 용이자동 스케일링, 복잡도 증가
내용설정 간편더 안정적 운영 가능인프라 비용 및 운영 인력 필요

실무 체크리스트

  • 코드 준비: 환경변수 사용, 비밀값 분리(Secrets)
  • 컨테이너화: Dockerfile 최적화, 불필요 파일 제외
  • 웹서버: Uvicorn 또는 Gunicorn + Uvicorn 워커 설정 검증
  • 리버스 프록시: Nginx로 TLS 종료(HTTPS) 구성
  • 로깅/모니터링: Structured logging, 에러 추적 도구 연동
  • 배포 자동화: CI/CD로 이미지 빌드→테스트→배포 파이프라인 구성
  • 롤백 계획: 배포 실패 시 즉시 이전 버전으로 롤백 가능성 확보

성능·보안·운영 주의점

성능

  • Uvicorn은 단일 스레드 이벤트 루프 기반이므로 CPU 바운드 작업은 별도 워커/태스크로 분리
  • 동시성(Concurrency) 테스트: locust, k6로 부하 테스트 수행

보안

  • TLS 필수: Let's Encrypt 등으로 HTTPS 적용
  • 입력 검증 및 Rate limiting 적용(예: FastAPI dependency로 구현)
  • 비밀정보는 환경변수/시크릿 매니저(GCP Secret Manager, AWS Secrets Manager)로 보관

운영

  • 로그 유실 방지: stdout/stderr 로깅을 중앙화(Fluentd, Loki)
  • 헬스체크 및 레디니스 체크 구현: /healthz, /ready 엔드포인트
  • 리소스 제한: 컨테이너에 CPU/메모리 리소스 쿼터 설정

배포 자동화 예시 (GitHub Actions)

간단한 워크플로우 스니펫:

name: docker-build-push on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Qemu uses: docker/setup-qemu-action@v2 - name: Build and push uses: docker/build-push-action@v4 with: push: true tags: user/repo:latest

자주 묻는 질문

Q1: Uvicorn과 Gunicorn 중 어느 쪽을 선택해야 하나요? A1: 개발/소규모 서비스는 Uvicorn 단독도 괜찮습니다. 프로덕션에서 프로세스 관리를 원하면 Gunicorn에 Uvicorn 워커를 조합하세요.

Q2: FastAPI에서 동기 코드가 많은데 어떻게 처리해야 하나요? A2: CPU 바운드 작업은 작업 큐(Celery, RQ)로 오프로딩하거나 별도 프로세스로 분리하세요. 비동기/동기 혼합 시 run_in_executor를 활용하세요.

Q3: HTTPS는 어디서 처리하는 게 좋나요? A3: 일반적으로 Nginx 또는 로드밸런서에서 TLS 종료를 하고 내부 통신은 TLS를 추가로 적용할지 판단하세요. 클라우드 환경에서는 Managed LB 권장합니다.

Q4: 빠르게 배포하고 싶을 때 권장 스택은? A4: Docker + Docker Compose + Let's Encrypt + GitHub Actions 조합으로 빠른 반복 배포가 가능합니다.

정리

  • fastapi 배포 방법은 컨테이너화, 적절한 서버(Uvicorn/Gunicorn), 리버스 프록시, CI/CD로 구성
  • Dockerfile 최적화와 환경변수/시크릿 관리가 중요
  • 성능은 비동기 구조 이해와 부하 테스트로 확인
  • 보안은 TLS 적용, 입력 검증, 시크릿 관리로 강화
  • 운영은 로깅·모니터링·헬스체크로 안정성 확보
fastapi 배포 방법: Docker, Uvicorn, Nginx 실무 가이드 | RYUSLOG DEV