FastAPI를 EC2에 HTTPS와 API Gateway를 이용해 배포한 방법
Source: Dev.to
번역하려는 전체 텍스트를 제공해 주시면, 요청하신 대로 한국어로 번역해 드리겠습니다. (코드 블록, URL 및 마크다운 형식은 그대로 유지됩니다.)
개요
FastAPI App
↓
Dockerize & deploy on EC2
↓
Connect API Gateway
↓
HTTPS URL ready to go
1단계. Elastic IP
Elastic IP는 우리 조직에서 제공했기 때문에 인스턴스에 바로 연결했습니다.
Note: Elastic IP가 없으면 EC2 퍼블릭 IP가 인스턴스를 재시작할 때마다 변경됩니다 — 즉 매번 API Gateway 통합을 업데이트해야 합니다.
단계 2. EC2에 SSH 연결
내 로컬 터미널에서 .pem 파일이 있는 위치로 이동한 뒤 연결했습니다.
cd ~/Downloads
chmod 400 your-key.pem
ssh -i your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP
chmod 400단계를 건너뛰지 마세요..pem파일 권한이 너무 열려 있으면 SSH가 연결을 완전히 거부합니다:
WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for 'your-key.pem' are too open.
Step 3. EC2에 Docker 설치
# 패키지 업데이트
sudo apt-get update
# Docker 설치
sudo apt-get install -y docker.io
# sudo 없이 Docker 실행
sudo usermod -aG docker ubuntu
newgrp docker
# 확인
docker --version
# Docker version 29.1.3
단계 4. 저장소 복제
cd ~
git clone https://github.com/your-username/your-repo.git
cd your-repo # go to your project
ls
Step 5. Dockerfile
FastAPI 앱을 uvicorn으로 실행하기 위한 매우 간단한 설정입니다.
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
6단계. docker-compose.yml
services:
app:
build: .
container_name: fastapi-app
ports:
- "8000:8000"
restart: always
Step 7. docker-compose 설치 — 첫 번째 장애물
docker compose version
# docker: unknown command: docker compose
❌ 문제
Docker는 설치되었지만 Compose 플러그인이 설치되지 않았습니다.
명백한 해결책을 시도해 보았습니다:
sudo apt-get install -y docker-compose-plugin
# E: Unable to locate package docker-compose-plugin
✅ 해결책
바이너리를 직접 다운로드합니다:
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
docker-compose --version
# Docker Compose version v5.1.3
단계 8. FastAPI 서버 실행
cd ~/backend
docker-compose up -d --build
실행 중인지 확인:
docker ps
# fastapi-app is up
curl http://localhost:8000/docs
# Got a response from FastAPI
서버가 EC2 인스턴스에서 실행 중입니다. 이제 HTTPS URL을 가져옵시다.
9단계. API Gateway 만들기
AWS 콘솔 → API Gateway → API 생성 → HTTP API
API name: backend
Region: ap-south-1 (Mumbai)
Step 10. Set Up Integration
이 단계에서는 API Gateway가 EC2 인스턴스와 통신하는 방법을 설정합니다.
Integration type: HTTP_PROXY
HTTP URI: http://YOUR_EC2_PUBLIC_IP:8000
11단계. 라우트 구성
ANY /{proxy+} → integration
/{proxy+}— 모든 경로를 포착하는 그리디 경로 변수ANY— 모든 HTTP 메서드(GET, POST, PUT, DELETE 등)를 허용
Step 12. $default 단계에 배포
단계 → $default → 배포
배포가 완료되면 AWS가 자동으로 HTTPS URL을 생성합니다. API Gateway는 기본적으로 SSL을 제공하므로 인증서를 수동으로 설정할 필요가 없습니다. 솔직히 말해서 가장 좋은 부분이었습니다.
Step 13. 테스트 — 두 번째 장애물
문서에 접근해 보았습니다:
https://xxxxxxxxxxxx.execute-api.ap-south-1.amazonaws.com/docs
❌ 문제
어떤 경로를 요청하든 — /docs, /api/users, 무엇이든 — 항상 루트 / 응답이 반환되었습니다. 모든 경로가 사라지고 루트로 다시 라우팅되고 있었습니다.
통합 구성(integration config)을 좀 더 자세히 살펴보면:
http://YOUR_EC2_PUBLIC_IP:8000 ← 경로가 전달되지 않음!
확인된 문제점
- Missing
{proxy}가 통합 URI 끝에 없어서, 경로와 무관하게 모든 요청이 EC2의 루트로 전달되었습니다. - No parameter mapping 이 설정되지 않아, 경로 정보가 Gateway 단계에서 완전히 사라졌습니다.
✅ 해결 방법
통합 URI 업데이트
http://YOUR_EC2_PUBLIC_IP:8000/{proxy}
파라미터 매핑 추가
-
API Gateway → Integration → Edit → Create parameter mapping
-
설정:
Mapping type: HTTP request path Destination: $request.path.proxy Source: {proxy} -
변경 사항을 저장하고 재배포합니다.
업데이트 후, 모든 라우트(/docs, /api/users 등)가 FastAPI 컨테이너로 올바르게 프록시되며, HTTPS 엔드포인트가 기대대로 동작합니다.
TL;DR
- EC2 프로비저닝 → Elastic IP 연결.
- SSH 후 Docker를 설치하고, 레포를 클론한 뒤
Dockerfile및docker-compose.yml을 추가. - Docker Compose 설치 (바이너리 직접 다운로드).
- 실행
docker-compose up -d --build. - API Gateway에서 HTTP API 생성,
http://:8000/{proxy}를 가리키는 HTTP_PROXY 통합 사용. - {proxy} 매개변수 매핑 추가 후
$default로 배포. - 즐기기: SSL을 직접 다루지 않아도 되는 완전 관리형 HTTPS 엔드포인트.
Location: Path
Name: proxy
Value: $request.path.proxy
그런 다음
$default단계를 재배포하세요 – 재배포하기 전까지는 변경 사항이 적용되지 않습니다.
(저도 이 점을 깨닫는 데 잠시 걸렸어요.)
Step 14. Final Test
https://xxxxxxxxxxxx.execute-api.ap-south-1.amazonaws.com/docs
FastAPI Swagger UI가 정상적으로 로드되었습니다.
아키텍처
Client
↓ HTTPS
API Gateway
https://xxxxxxxxxxxx.execute-api.ap-south-1.amazonaws.com/{path}
↓ HTTP
EC2 (YOUR_EC2_PUBLIC_IP:8000/{path})
↓
Docker Container
↓
FastAPI (uvicorn:8000)
문제 해결 요약
| 문제 | 원인 | 해결 방법 |
|---|---|---|
docker compose를 찾을 수 없음 | Compose 플러그인이 설치되지 않음 | 바이너리를 수동으로 다운로드 |
| 모든 경로가 루트 “/” 응답을 반환 | URI에 {proxy}가 누락되고 매개변수 매핑이 없음 | URI를 업데이트하고 매핑을 추가한 뒤 재배포 |
| SSH 연결 거부 | .pem 파일 권한이 너무 넓음 | 키 파일에 chmod 400 실행 |
통합 URI에 있는 {proxy} 토큰은 사소한 디테일이지만, 처음이라 예상보다 오래 걸렸습니다. 이 글이 다른 사람에게 도움이 되길 바랍니다. 혹시 이해가 안 되는 부분이 있으면 아래에 댓글을 남겨 주세요! 🙌