Docker

[Docker] NGINX란? Docker와 FastAPI를 활용한 서버 구축 실습

JustJunsu 2024. 11. 17. 17:32
728x90

NGINX는 웹 서버와 리버스 프록시로 널리 사용되는 고성능 소프트웨어입니다. 이번 포스팅에서는 NGINX의 개념을 이해하고, Docker를 사용하여 NGINX와 FastAPI를 통합해 서버를 띄우는 실습을 진행하겠습니다.

 

1. NGINX란?

1.1. NGINX의 정의

NGINX(발음: 엔진엑스)는 2004년 개발된 오픈소스 소프트웨어로, 웹 서버, 리버스 프록시, 그리고 로드 밸런서 역할을 수행합니다.
특히 비동기 이벤트 기반 아키텍처를 사용하여 대규모 동시 요청 처리에 강점을 보입니다.

1.2. NGINX의 주요 역할

  1. 웹 서버: 정적 콘텐츠(HTML, CSS, JS) 제공.
  2. 리버스 프록시: 클라이언트 요청을 백엔드 서버로 전달.
  3. 로드 밸런서: 트래픽을 여러 서버로 분산.
  4. 캐시 서버: 콘텐츠를 캐싱해 성능 최적화.
  5. 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 포트에서 대기 중입니다.

proxy_set_header

  • 의미: 리버스 프록시를 통해 전달되는 요청에 특정 HTTP 헤더를 추가하거나 수정합니다.
  • 설정:
    1. proxy_set_header Host $host;
      • 클라이언트의 Host 헤더를 FastAPI로 전달합니다.
        (예: 클라이언트가 http://example.com으로 요청하면 이 정보를 FastAPI가 확인 가능)
    2. proxy_set_header X-Real-IP $remote_addr;
      • 클라이언트의 실제 IP 주소를 FastAPI로 전달합니다.
        이 정보는 FastAPI에서 클라이언트의 원본 IP를 추적하는 데 유용합니다.
    3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      • 클라이언트의 IP 주소 체인을 FastAPI로 전달합니다.
        예를 들어, 클라이언트가 여러 프록시를 거쳤다면 그 경로 정보가 X-Forwarded-For 헤더에 포함됩니다.

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. 서버 실행

  1. 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

 

Beginner’s Guide

Beginner’s Guide This guide gives a basic introduction to nginx and describes some simple tasks that can be done with it. It is supposed that nginx is already installed on the reader’s machine. If it is not, see the Installing nginx page. This guide de

nginx.org

https://fastapi.tiangolo.com/tutorial/

 

Tutorial - User Guide - FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com

 

 

728x90