Reverse
뒤집다 (여기서 reverse 의 뜻은 "역전, 꺼꾸로"의 뜻이 아닌 "배후, 뒷쪽"의 뜻)
proxy
대리
네트워크에서 proxy 서버
클라이언트가 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 가리킨다.
=> 서버와 서버사이의 중계기 역할
Reverse Proxy의미
웹 서버 앞에 위치하여 클라이언트(예: 웹 브라우저) 요청을 해당 웹 서버에 분배해주는 서버
Forward Proxy (클라이언트 앞)
클라이언트 대신 프록시 서버가 목적 서버에 통신해주는 구성
아래 그림처럼, 같은 내부망에 존재하는 클라이언트의 요청을 받아 인터넷을 통해 외부 서버에서 데이터를 가져와 클라이언트에게 응답하는 구조

Reverse Proxy (본 서버 앞)
클라이언트가 웹서비스에 접근할때 웹서버에 요청하는 것이 아닌, 프록시로 요청하게 되고, 프록시가 배후(reverse)의 서버로부터 데이터를 가져오는 방식

Reverse Proxy를 사용하면
docker 서비스를 좀 더 쉽게 정의할 수 있는 docker-compose.yml 파일을 활용하여 아래 서비스들을 구성하는 예시이다.
(docker 서비스를 사용하면, 호스트 PC에 직접 nginx 등을 설치할 필요 없음)
version: "3.8"
services:
nginxproxy: # 도커 서비스명
depends_on: # 의존 서비스(아래 서비스들이 모두 구동된 후에 nginxproxy 서비스 구동)
- fastapi
- mongodb
image: nginx:alpine # 도커 이미지
container_name: proxyserver # 도커 컨테이너 이름
restart: always # 재시작 규칙
ports: # 포트 포워딩
- "1000:80" # 호스트 포트(접속 포트):도커 내부 포트
volumes: # 볼륨 마운트
- ./nginx/nginx.conf:/etc/nginx/nginx.conf # 호스트 볼륨 경로:도커 내부 볼륨 경로
- ./frontend:/usr/share/nginx/html
fastapi:
build: # 따로 Dockerfile을 사용하여 커스텀 빌드할 경우
context: ./fastapi # Dockerfile 상대 경로
dockerfile: Dockerfile # Dockerfile의 파일 이름
container_name: fastapi
restart: always
command: uvicorn app.main:app --workers 40 --host 0.0.0.0 --port 7000 --reload # uvicorn 사용할 경우 command
ports:
- "7000:7000"
volumes:
- ./fastapi/app:/code/app
mongodb:
image: mongo:7.0.5
container_name: mongodb
restart: always
ports:
- "27017:27017"
volumes:
- ./mongodb/db:/data/db # 데이터 베이스 폴더 (도커 서비스를 중지 시켜도 데이터를 유지하기 위한..)
env_file:
- ./mongodb/mongodb.env # mongoDB env 파일 (데이터베이스 설정 환경 변수 등 정의된..)
도커 서비스로 nginx, fastapi, mongodb 를 정의하고, nginx 설정을 사용자 정의하는 경우이다.
./nginx/nginx.conf 파일의 내용 예시이다.
user nginx; # Nginx 프로세스 실행 사용자 지정
worker_processes auto; # Nginx가 사용할 워커 프로세스 수를 자동으로 설정 (CPU 코어 수에 맞게 조정)
error_log /var/log/nginx/error.log warn; # 에러 로그 파일 경로 및 로그 레벨 설정 (warn 이상의 에러만 기록)
pid /var/run/nginx.pid; # Nginx 프로세스 ID 파일 경로 설정
# 네트워크 이벤트 설정 블록
events {
worker_connections 128; # 각 워커 프로세스에서 동시에 처리할 수 있는 최대 연결 수 설정
}
# HTTP 관련 설정 블록
http {
include /etc/nginx/mime.types; # MIME 타입 파일을 포함하여 응답의 Content-Type 설정
default_type application/octet-stream; # 기본 MIME 타입 설정 (명시되지 않은 파일에 대해 이 타입 사용)
# 로그 포맷 정의 (접속 로그 형식 지정)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # 접속 로그 파일 경로와 사용할 로그 포맷 지정
sendfile on; # 파일을 전송할 때 sendfile 사용 (성능 향상)
keepalive_timeout 500; # 클라이언트와의 keep-alive 연결 유지 시간 설정 (초 단위)
upstream docker-fastapi {
server fastapi:7000; # 도커 컨테이너 이름 `fastapi`와 포트 7000으로 연결
}
# 서버 블록 시작 (HTTP 요청을 처리하는 가상 서버 설정)
server {
listen 80; # IPv4에서 포트 80으로 요청 수신
listen [::]:80; # IPv6에서 포트 80으로 요청 수신
server_name $host:1000; # 서버 이름 설정 (호스트 이름 및 포트)
error_page 500 502 503 504 /50x.html; # 에러 페이지 설정 (500, 502, 503, 504 에러 발생 시 사용자 정의 HTML 페이지 사용)
location = /50x.html {
root /usr/share/nginx/html; # 사용자 정의 에러 페이지의 루트 디렉토리 설정
}
# 기본 루트 경로 처리 설정
location / {
root /usr/share/nginx/html; # 정적 파일의 루트 디렉토리 설정
index index.html index.htm; # 기본 인덱스 파일 설정
try_files $uri $uri/ /index.html; # 요청된 파일이 존재하지 않으면 index.html로 대체 (SPA 지원)
}
# /api/ 경로로 들어오는 요청을 FastAPI 서버로 프록시
location /api/ {
rewrite ^/api(/.*)$ $1 break; # /api 접두어를 제거하고 나머지 경로를 유지
proxy_pass http://docker-fastapi/; # 프록시 서버로 요청을 전달 (docker-fastapi 업스트림으로 연결)
proxy_buffering off; # 프록시 버퍼링 비활성화 (실시간 데이터 전송에 유리)
proxy_redirect off; # 자동으로 URL 리다이렉트 비활성화
proxy_set_header Host $host; # 원래 요청의 Host 헤더 전달
proxy_set_header X-Real-IP $remote_addr; # 클라이언트의 실제 IP 주소 전달
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 프록시를 거친 IP 목록 전달
proxy_set_header X-Forwarded-Host $host; # 원래 요청의 호스트 정보 전달
proxy_set_header X-Forwarded-Proto $scheme; # 요청의 프로토콜 정보 전달 (http 또는 https)
}
}
}