fastapi 배포 방법: 실무 배포 가이드와 모범 사례
fastapi 배포 방법을 단계별로 정리한 실무 가이드입니다. Docker 이미지 생성, Uvicorn/Gunicorn 설정, 리버스 프록시 구성, CI/CD 적용과 운영 시 주의점을 포함해 바로 적용 가능합니다.
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 |
|---|---|---|---|
| 내용 | 단일 Uvicorn | Gunicorn + 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 적용, 입력 검증, 시크릿 관리로 강화
- 운영은 로깅·모니터링·헬스체크로 안정성 확보