NGINX는 웹 서버와 리버스 프록시로 널리 사용되는 고성능 소프트웨어입니다. 이번 포스팅에서는 NGINX의 개념을 이해하고, Docker를 사용하여 NGINX와 FastAPI를 통합해 서버를 띄우는 실습을 진행하겠습니다.
1. NGINX란?
1.1. NGINX의 정의
NGINX(발음: 엔진엑스)는 2004년 개발된 오픈소스 소프트웨어로, 웹 서버, 리버스 프록시, 그리고 로드 밸런서 역할을 수행합니다.
특히 비동기 이벤트 기반 아키텍처를 사용하여 대규모 동시 요청 처리에 강점을 보입니다.
1.2. NGINX의 주요 역할
- 웹 서버: 정적 콘텐츠(HTML, CSS, JS) 제공.
- 리버스 프록시: 클라이언트 요청을 백엔드 서버로 전달.
- 로드 밸런서: 트래픽을 여러 서버로 분산.
- 캐시 서버: 콘텐츠를 캐싱해 성능 최적화.
- HTTPS 지원: SSL 인증서 설정으로 보안 강화.
2. 왜 NGINX와 Docker를 사용하는가?
2.1. NGINX의 장점
- 고성능: 수천 개의 동시 연결 처리 가능.
- 유연성: 리버스 프록시, 로드 밸런싱 등 다양한 역할.
- 확장성: 여러 환경에 쉽게 적용 가능.
2.2. Docker의 장점
Docker는 컨테이너화를 통해 애플리케이션을 독립적이고 이식 가능한 환경에서 실행할 수 있게 합니다.
Docker와 NGINX를 함께 사용하면:
- 서버 설정과 배포가 간소화됩니다.
- FastAPI와 같은 백엔드 프레임워크와 쉽게 통합할 수 있습니다.
3. 실습: Docker에서 NGINX와 FastAPI를 이용해 서버 띄우기
3.1. 프로젝트 디렉터리 구조
아래와 같은 디렉터리 구조로 프로젝트를 구성합니다:
nginx-fastapi-docker/
│
├── app/
│ ├── main.py # FastAPI 애플리케이션
│ ├── Dockerfile # FastAPI용 Dockerfile
│
├── nginx/
│ ├── nginx.conf # NGINX 설정 파일
│
├── docker-compose.yml # Docker Compose 설정
3.2. FastAPI 애플리케이션 코드
app/main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, World! Welcome to FastAPI with NGINX and Docker!"}
@app.get("/api")
def read_api():
return {"message": "This is a sample API endpoint."}
3.3. FastAPI용 Dockerfile
app/Dockerfile:
# FastAPI Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Run FastAPI server
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]는 Docker 컨테이너가 실행될 때 실행되는 명령어를 지정하는 구문입니다. 이 명령어는 Uvicorn 서버를 실행하여 FastAPI 애플리케이션을 시작합니다.
- uvicorn
- Python의 비동기 웹 서버로, ASGI(Asynchronous Server Gateway Interface) 표준을 지원합니다.
- FastAPI와 같은 ASGI 프레임워크를 실행하는 데 자주 사용됩니다.
- main:app
- main: FastAPI 애플리케이션이 정의된 Python 파일 이름입니다. 여기서는 main.py 파일을 의미합니다.
- app: main.py 파일 내에서 정의된 FastAPI 애플리케이션 객체의 변수 이름입니다. 예를 들어:
from fastapi import FastAPI
app = FastAPI()
--host 0.0.0.0
- --host: Uvicorn 서버가 어떤 네트워크 인터페이스에서 요청을 수신할지 지정합니다.
- 0.0.0.0은 컨테이너의 모든 네트워크 인터페이스에서 요청을 수신하도록 설정합니다.Docker 컨테이너는 기본적으로 외부 네트워크에서 격리되어 있으므로, 외부에서 접근 가능하게 만들기 위해 0.0.0.0을 사용해야 합니다.
app/requirements.txt:
fastapi
uvicorn[standard]
3.4. NGINX 설정 파일
nginx/nginx.conf:
server {
listen 80;
# Define server_name (Optional)
server_name localhost;
# Proxy requests to FastAPI
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;
}
# Cache-Control for static files (Optional)
location /static/ {
root /var/www;
expires 1d;
}
}
listen 80:
- 의미: NGINX가 요청을 수신할 포트를 정의합니다.
- 설정: 80번 포트는 HTTP의 기본 포트입니다.
- 클라이언트가 브라우저를 통해 http://your-domain.com으로 요청을 보낼 때, 이 요청은 기본적으로 80번 포트를 통해 들어옵니다.
- 만약 HTTPS를 사용하려면 listen 443 ssl;처럼 443번 포트를 지정해야 합니다.
server_name localhost;
- 의미: 이 서버 블록이 처리할 도메인 이름(또는 호스트 이름)을 정의합니다.
- 설정:
- localhost는 로컬 테스트용으로 사용되며, 외부에서 접근하려면 도메인 이름 또는 IP 주소를 여기에 작성해야 합니다.
location / { ... }
- 의미: 요청 URL의 경로(/)에 대해 처리할 동작을 정의합니다.
- 설정:
이 블록 안에서는 클라이언트의 요청을 FastAPI 애플리케이션으로 전달하는 리버스 프록시 역할을 수행합니다.
proxy_pass http://fastapi:8000;
- 의미: 클라이언트가 / 경로로 요청을 보낼 때 해당 요청을 **FastAPI 서버(컨테이너)**로 전달합니다.
- 설정:
- http://fastapi:8000은 FastAPI 애플리케이션이 실행 중인 컨테이너의 주소와 포트입니다.
이 이름은 docker-compose.yml에서 정의한 서비스 이름(fastapi)과 매칭됩니다. - FastAPI가 컨테이너 내에서 실행되며 8000 포트에서 대기 중입니다.
- http://fastapi:8000은 FastAPI 애플리케이션이 실행 중인 컨테이너의 주소와 포트입니다.
proxy_set_header
- 의미: 리버스 프록시를 통해 전달되는 요청에 특정 HTTP 헤더를 추가하거나 수정합니다.
- 설정:
- proxy_set_header Host $host;
- 클라이언트의 Host 헤더를 FastAPI로 전달합니다.
(예: 클라이언트가 http://example.com으로 요청하면 이 정보를 FastAPI가 확인 가능)
- 클라이언트의 Host 헤더를 FastAPI로 전달합니다.
- proxy_set_header X-Real-IP $remote_addr;
- 클라이언트의 실제 IP 주소를 FastAPI로 전달합니다.
이 정보는 FastAPI에서 클라이언트의 원본 IP를 추적하는 데 유용합니다.
- 클라이언트의 실제 IP 주소를 FastAPI로 전달합니다.
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 클라이언트의 IP 주소 체인을 FastAPI로 전달합니다.
예를 들어, 클라이언트가 여러 프록시를 거쳤다면 그 경로 정보가 X-Forwarded-For 헤더에 포함됩니다.
- 클라이언트의 IP 주소 체인을 FastAPI로 전달합니다.
- proxy_set_header Host $host;
3.5. Docker Compose 파일
docker-compose.yml:
version: '3.8'
services:
fastapi:
build:
context: ./app
container_name: fastapi-container
ports:
- "8000:8000"
nginx:
image: nginx:latest
container_name: nginx-container
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- fastapi
3.6. 서버 실행
- Docker 빌드 및 실행
docker-compose up --build
2. NGINX와 FastAPI 확인
- http://localhost/ : FastAPI의 기본 경로 출력.
- http://localhost/api : FastAPI의 API 경로 출력.
4. 결론
이번 포스팅에서는 NGINX의 개념과 장점을 살펴보고, Docker와 FastAPI를 활용해 서버를 구성하는 방법을 실습했습니다. NGINX의 리버스 프록시 역할과 Docker의 컨테이너화 장점을 활용하면, 웹 애플리케이션 배포와 관리가 훨씬 간편해집니다.
Reference
https://nginx.org/en/docs/beginners_guide.html
https://fastapi.tiangolo.com/tutorial/
'Docker' 카테고리의 다른 글
Docker를 이용한 ChromaDB와 데이터 생성 컨테이너 연동하기 (2) | 2024.11.15 |
---|---|
[Docker] Zookeeper와 Kafka 설치 및 연동 가이드: Docker Compose로 간편하게 설정하기 (0) | 2024.11.10 |
[Docker] Docker와 PostgreSQL을 이용한 데이터 생성 시스템 구축하기 (2) | 2024.10.06 |
[Docker] DockerFile 명령어 정리: ADD, COPY, CMD, ENTRYPOINT, ARG, ENV 등 (6) | 2024.09.25 |
[Docker] Ubuntu 22.04 환경에서 도커 설치하기 (0) | 2024.09.23 |