greatsangho의 이야기

FinPilot - AWS Debian에서 FastAPI 서버 Docker Compose 본문

프로그래밍/SK AI 캠프

FinPilot - AWS Debian에서 FastAPI 서버 Docker Compose

greatsangho 2025. 2. 25. 03:29

Docker

 

GitHub - greatsangho/SKN05-FINAL-3TEAM: FinPilot Project

FinPilot Project. Contribute to greatsangho/SKN05-FINAL-3TEAM development by creating an account on GitHub.

github.com

 

모든 서버는 AWS에 호스팅합니다. 올바른 자격 증명을 설정하려면 @greatsangho에게 문의하세요.

개발 완료된 백엔드 서버를 도커로 배포합니다

아래는 Debian 기반 시스템에서 Kubernetes 설치부터 finpilotback.duckdns.org를 사용한 FastAPI 서버 배포까지의 전체 과정을 순서대로 정리한 가이드입니다.


/home/sangho/ML/SKN05-FINAL-3TEAM/.venv/bin/gunicorn main:app --workers 3 --worker-class uvicorn.workers.UvicornWorker --bind 127.0.0.1:8000 --access-logfile="-"
watch free -h

도커 설치

sudo apt update
sudo apt install -y apt-transport-https software-properties-common gnupg2
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] <https://download.docker.com/linux/ubuntu> $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl status docker
sudo usermod -aG docker $USER
docker run -d -p 8000:8000 --name finpilot furince/finpilot-api-server:2

모든 컨테이너 중지 및 삭제

docker stop $(docker ps -aq)
docker rm $(docker ps -aq)

모든 이미지 삭제

docker rmi $(docker images -q)

이미지 생성

docker build -t finpilot .

도커 실행

docker run -d -p 8000:8000 --name finpilot finpilot

컨테이너 재시작

docker-compose down --volumes --remove-orphans
docker-compose up --build -d
docker-compose logs fastapi nginx certbot

Certbot 명령 실행

docker-compose run certbot certonly --webroot --webroot-path=/var/www/certbot --email greatsangho@gmail.com --agree-tos --no-eff-email -d finpilotback.duckdns.org -d www.finpilotback.duckdns.org

Nginx 재시작

docker-compose restart nginx
sudo chmod +x init-letsencrypt.sh 

sudo apt remove containerd runc docker.io -y
sudo apt autoremove -y

sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \\
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] <https://download.docker.com/linux/ubuntu> \\
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \\
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
  sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo apt update && sudo apt upgrade -y
sudo apt install nginx docker.io

SWAG 컨테이너 내부에서 FastAPI 접속 테스트

docker-compose up --build -d
docker-compose logs -f swag 
docker exec swag curl -v <http://fastapi:8000/health>

nginx.conf

# https 통신만 실행
server {
    listen 80;
    server_name finpilotback.duckdns.org;
    
    location / {
        proxy_pass http://fastapi: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;
    }
}

server {
    listen 443 ssl;
    server_name finpilotback.duckdns.org;

    ssl_certificate /config/etc/letsencrypt/live/finpilotback.duckdns.org/fullchain.pem;
    ssl_certificate_key /config/etc/letsencrypt/live/finpilotback.duckdns.org/privkey.pem;

    location / {
        proxy_pass http://fastapi: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;
    }
}

docker-compose.yml

version: '3.8'

services:
  fastapi:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: fastapi
    platform: linux/amd64
    expose:
      - "8000"
    networks:
      - app-network
    env_file:
      - .env
    environment:
      - TZ=Asia/Seoul
      - SECRET_KEY=${SECRET_KEY}
      - DATABASE_URL=${DATABASE_URL}
      - NAMESPACE_UUID=${NAMESPACE_UUID}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - TAVILY_API_KEY=${TAVILY_API_KEY}
      - USER_AGENT=${USER_AGENT}
      - DART_API_KEY=${DART_API_KEY}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 60s
      timeout: 10s
      retries: 3

  swag:
    image: lscr.io/linuxserver/swag:latest
    container_name: swag
    platform: linux/amd64
    depends_on:
      fastapi:
        condition: service_healthy
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/site-confs:/config/nginx/site-confs  # 설정 파일 매핑
      - ./certificates:/etc/letsencrypt
    env_file:
      - .env
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - URL=finpilotback.duckdns.org
      - SUBDOMAINS=
      - VALIDATION=http # duckdns
      - DUCKDNSTOKEN=${DUCKDNSTOKEN}
      - EMAIL=greatsangho@gmail.com
      - STAGING=false  # 테스트 시 true로 변경
    networks:
      - app-network
    restart: unless-stopped

networks:
  app-network:
    driver: bridge

volumes:
  certificates:
    driver: local
docker-compose down && docker-compose up -d

 

해결과제

  • MySQL 서버를 구동할 수 있음
  • FastAPI 환경을 구축하기
  • 릴리즈된 환경을 개별적으로 도커를 이용해서 구현
  • 로컬 안에서 프론트 백엔트 구동
  • 요청을 어떻게 주고 받으면서 작동하는지를 확인하기
  • 원하는 이미지, Node.js, FastAPI 등 docker pull
  • 도커로 실행
  • docker volume mount
  • docker compose
  • 네트워크 설정
  • 인터렉션 된 상태에서는 검증하기가 어려움
  • 분리된 환경에서 테스트 하는 방법 공부하기

이미지를 가져오기 → 독립된 환경에서 각각

  • git flow
  • 개발 과정에 대해 release, develop, feature, hotfix, main
  • 마이너하게 기능 추가하고 싶을 때
  • feature branch로 (develop) brance 분기해서 추가적으로 기능 후 merge request 요청
  • 리뷰하는 사람이 특정 모듈의 메인 담당자
  • relase 후 빠르게 구성하기
  • 각자 Docker를 설치하여 도커에 코드를 올리기
  • relase 버전 브렌치 구현
  • 개발 환경 세팅하고 개발해본 경험

https://github.com/knaopel/docker-frontend-backend-db/blob/master/docker-compose.yml

https://puleugo.tistory.com/107

  • 구동하는 시간에 대해 예상이 되도록 명시
  • 요청에 따라 구현이 바뀜
  • 프론트에서 페이지 락 되는 문제 등등
  • 백엔드는 웨이팅
  • 트래픽 물고 있음 - 요청 개수 …
  • 트래픽이 몰리면 서버 다운됨
  • 경험 상 1000 개 요청이 넘어가면 문제 발생
  • 비동기적 처리방식
  • 웹 프록시 - AWS 웹 프록시 기능
  • 시간에 얽혀있는 것을 확인해야 함
  • 시행착오 및 시간 절약에 필수적
  • 면접에서 물어볼 것임
  • 시간적인 부분에 대한 고려하기
  • 리눅스 작업예약 스케줄러?
  • 키값에 대해서 어떻게 처리할 것인지 여부 - 사용안 함 또는 로컬에 저장하도록 최대한 생각

https://eff-certbot.readthedocs.io/en/latest/using.html#setting-up-automated-renewal

반응형