반응형
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 파이프라인은 다음과 같은 순서로 작동합니다:
- CI 파이프라인 성공 시 자동으로 시작
- Python 버전 감지 및 Docker 이미지 빌드
- ECR에 이미지 푸시
- EC2 서버에 SSH 접속
- 최신 이미지 풀 및 서비스 재시작
이 설정으로 개발자는 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 |