코샵
끄적끄적 코딩 공방
코샵

인기 글

  • 분류 전체보기 (475) N
    • MongoDB (4)
    • 일기장 (4)
    • Unity (138)
      • Tip (41)
      • Project (1)
      • Design Pattern (8)
      • Firebase (6)
      • Asset (2)
    • 파이썬 (127)
      • Basic (40)
      • OpenCV (8)
      • Pandas (15)
      • PyQT (3)
      • SBC(Single Board Computer) (1)
      • 크롤링 (14)
      • Fast API (29)
      • Package (6)
    • Linux (4)
    • C# (97)
      • Algorithm (11)
      • Window (7)
    • TypeScript (44) N
      • CSS (6) N
    • Git (11)
    • SQL (5)
    • Flutter (10)
      • Tip (1)
    • System (1)
    • BaekJoon (6)
    • Portfolio (2)
    • MacOS (1)
    • 유틸리티 (1)
    • 서비스 (6)
    • 자동화 (3)
    • Hobby (10)
      • 물생활 (10)
      • 식집사 (0)
전체 방문자
오늘
어제

최근 댓글

최근 글

반응형
hELLO · Designed By 정상우.
코샵

끄적끄적 코딩 공방

파이썬/Fast API

FastAPI 프로젝트 배포 자동화 가이드 Part 2: CD 파이프라인과 서버 배포

2025. 2. 4. 12:13
반응형

Part 1에서 구성한 자동화된 빌드 환경을 바탕으로, 이제 실제 리눅스 서버에 배포하는 과정을 자동화해보겠습니다.

CD 워크플로우 구성

# .github/workflows/cd.yml
name: CD Pipeline

on:
  workflow_run:
    workflows: ["CI Pipeline"]
    types:
      - completed
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}

    steps:
    - uses: actions/checkout@v2

    - name: Get Python Version
      id: get_version
      run: |
        python_version=$(python scripts/get_python_version.py | jq -r .full)
        echo "version=${python_version}" >> $GITHUB_OUTPUT

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ secrets.AWS_REGION }}

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build and push image to ECR
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: fastapi-app
        IMAGE_TAG: ${{ github.sha }}
      run: |
        docker build \
          --build-arg PYTHON_VERSION=${{ steps.get_version.outputs.version }} \
          -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
          -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

    - name: Deploy to EC2
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USER }}
        key: ${{ secrets.EC2_SSH_KEY }}
        script: |
          cd /app/fastapi-deploy
          aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}
          docker-compose pull
          docker-compose down
          docker-compose up -d

서버 설정 스크립트

리눅스 서버 초기 설정을 위한 스크립트입니다.

#!/bin/bash
# scripts/server_setup.sh

# 시스템 업데이트
sudo apt-get update
sudo apt-get upgrade -y

# Docker 설치
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Docker Compose 설치
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# AWS CLI 설치
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# 애플리케이션 디렉토리 생성
sudo mkdir -p /app/fastapi-deploy
sudo chown -R $(whoami):$(whoami) /app

프로덕션 Docker Compose 설정

# docker-compose.prod.yml
version: '3.8'

services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    depends_on:
      - web
    networks:
      - app-network

  web:
    image: ${ECR_REGISTRY}/${ECR_REPOSITORY}:latest
    expose:
      - 8000
    env_file:
      - .env.prod
    depends_on:
      - db
      - redis
    networks:
      - app-network
    deploy:
      replicas: 3
      restart_policy:
        condition: any
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    networks:
      - app-network
    deploy:
      resources:
        limits:
          memory: 1G

  redis:
    image: redis:6
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app-network

networks:
  app-network:
    driver: overlay

volumes:
  postgres_data:
  redis_data:

Nginx 설정

# nginx.conf
user nginx;
worker_processes auto;

events {
    worker_connections 1024;
}

http {
    upstream fastapi {
        server web:8000;
    }

    server {
        listen 80;
        server_name your-domain.com;

        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 443 ssl;
        server_name your-domain.com;

        ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

        location / {
            proxy_pass http://fastapi;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
        }
    }
}

모니터링 설정

Prometheus와 Grafana를 사용한 모니터링 설정입니다.

# docker-compose.monitoring.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    networks:
      - monitoring

  grafana:
    image: grafana/grafana
    depends_on:
      - prometheus
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - monitoring

networks:
  monitoring:

volumes:
  grafana_data:

이렇게 설정된 CD 파이프라인은 다음과 같은 순서로 작동합니다:

  1. CI 파이프라인 성공 시 자동으로 시작
  2. Python 버전 감지 및 Docker 이미지 빌드
  3. ECR에 이미지 푸시
  4. EC2 서버에 SSH 접속
  5. 최신 이미지 풀 및 서비스 재시작

이 설정으로 개발자는 main 브랜치에 푸시만 하면 자동으로 프로덕션 환경에 배포가 이루어집니다.

저작자표시 비영리 변경금지 (새창열림)

'파이썬 > Fast API' 카테고리의 다른 글

FastAPI와 Nginx : 웹 서버 구성  (1) 2025.02.07
FastAPI 프로젝트 배포 자동화 가이드 Part 3: 무중단 배포와 모니터링  (0) 2025.02.05
프로젝트 배포 자동화 가이드 Part 1: 개발 환경 구성  (1) 2025.02.03
FastAPI-Cache로 구현하는 효율적인 API 캐싱  (0) 2025.02.02
Router Tags 활용  (0) 2025.02.01
    '파이썬/Fast API' 카테고리의 다른 글
    • FastAPI와 Nginx : 웹 서버 구성
    • FastAPI 프로젝트 배포 자동화 가이드 Part 3: 무중단 배포와 모니터링
    • 프로젝트 배포 자동화 가이드 Part 1: 개발 환경 구성
    • FastAPI-Cache로 구현하는 효율적인 API 캐싱
    코샵
    코샵
    나의 코딩 일기장

    티스토리툴바