Nginx Reverse Proxy Test : Port-Based Routing

SummerToday·2024년 3월 15일

도커, 서버 기술

목록 보기
25/34
post-thumbnail

docker-compose.yml 구성

NGINX 프록시가 요청을 받아들이고 적절한 서비스로 라우팅하며, NGINX와 Apache는 프록시 서버를 통해 요청을 받아 처리할 수 있도록 설정한다.

version: "3"

services:
    nginxproxy:
        image: nginx:1.18.0
        ports:
            - "8080:8080"
            - "8081:8081"
        restart: always
        volumes:
            - "./nginx/nginx.conf:/etc/nginx/nginx.conf"

    nginx:
        depends_on:
            - nginxproxy
        image: nginx:1.18.0
        restart: always

    apache:
        depends_on:
            - nginxproxy
        image: httpd:2.4.46
        restart: always
  • /nginx/nginx.conf:/etc/nginx/nginx.conf"는 호스트 시스템의 ./nginx/nginx.conf 파일을 컨테이너 내부의 /etc/nginx/nginx.conf 파일에 마운트하는 것을 나타낸다.

  • nginxproxy
    해당 컨테이너는 nginx:1.18.0 이미지를 사용하여 NGINX 프록시를 실행한다. 해당 서비스는 호스트의 8080 및 8081 포트를 컨테이너 내부의 8080 및 8081 포트에 매핑하며, 항상 다시 시작하도록 구성되어 있다. 또한 호스트의 ./nginx/nginx.conf 파일을 컨테이너 내부의 /etc/nginx/nginx.conf 파일로 마운트하여 NGINX 설정을 제공한다.

  • nginx
    해당 컨테이너는 nginx:1.18.0 이미지를 사용하여 단순히 NGINX 웹 서버를 실행한다. 해당 서비스는 nginxproxy 서비스에 의존하며, 항상 다시 시작하도록 구성되어 있다.

  • apache
    해당 컨테이너는 httpd:2.4.46 이미지를 사용하여 Apache 웹 서버를 실행한다. 해당 서비스도 nginxproxy 서비스에 의존하며, 항상 다시 시작하도록 구성되어 있다


nginx.conf

기본 nginx.conf 설정에 upstream 설정과 server 설정을 추가하였다.
default.conf 설정과 겹치지 않도록, 기본 nginx.conf에서 다음 항목은 삭제한다.

include /etc/nginx/conf.d/*.conf; 삭제 후 해당 파일 내용을 nginx.conf 파일에 한번에 작성.

user nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-nginx {
        server nginx:80;
    }

    upstream docker-apache {
        server apache:80;
    }

    server {
        listen 8080;

        location / {
            proxy_pass         http://docker-nginx;
            proxy_redirect     off;
            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-Host $server_name;
        }
    }

    server {
        listen 8081;

        location / {
            proxy_pass         http://docker-apache;
            proxy_redirect     off;
            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-Host $server_name;
        }
    }
}
  • user nginx;
    NGINX 서버 프로세스가 실행될 사용자를 지정한다. 일반적으로 보안상의 이유로 웹 서버 프로세스는 특정 사용자로 실행된다.

  • worker_processes auto;
    NGINX 워커 프로세스의 수를 자동으로 설정한다. 이는 사용 가능한 CPU 코어의 수에 따라 자동으로 조정된다.

  • error_log /var/log/nginx/error.log warn;
    NGINX의 에러 로그를 지정된 경로에 기록한다. 해당 설정에서는 /var/log/nginx/error.log에 기록하며, 로그 레벨은 warn으로 설정되어 있다.

    • Nginx 로그 레벨 종류

      • debug
        디버그 정보를 기록한다. 가장 상세한 로깅 레벨이다.

      • info
        정보 메시지를 기록한다. 일반적인 운영 조건과 관련된 메시지를 기록한다.

      • notice
        중요한 이벤트를 기록한다. 예를 들어, 서버 재시작이나 중단된 서비스를 다시 시작하는 경우와 같은 중요한 작업에 대한 메시지를 기록한다.

      • warn
        경고 메시지를 기록한다. 일부 문제가 발생했지만 서버의 정상적인 운영을 방해하지 않는 문제에 대한 경고를 기록한다.

      • error
        에러 메시지를 기록한다. 서버에서 심각한 문제가 발생했음을 나타낸다.

      • crit
        치명적인 에러 메시지를 기록한다. 서버에 심각한 문제가 발생했으며 즉시 조치가 필요한 경우를 나타낸다.

      • alert
        심각한 문제가 발생했음을 나타내는 메시지를 기록한다. warn보다 더 심각한 상태를 나타낸다.

      • emerg
        시스템이 더 이상 작동하지 않을 정도로 심각한 문제가 발생했음을 나타내는 메시지를 기록한다. 가장 심각한 로깅 레벨이다.
  • pid /var/run/nginx.pid;
    NGINX 마스터 프로세스의 PID 파일의 경로를 지정합니다. 해당 파일은 NGINX 마스터 프로세스의 PID를 저장한다.

  • events
    해당 블록에서는 NGINX가 처리하는 이벤트에 대한 설정을 지정한다. 여기서는 worker_connections를 1024로 설정하여 각 워커 프로세스당 최대 동시 연결 수를 제한한다.

  • http
    해당 블록에서는 HTTP 서버에 대한 설정을 지정한다. 여기서는 MIME 유형, 로그 포맷, 액세스 로그 경로 등을 설정합니다. 또한 sendfile 및 keepalive_timeout와 같은 HTTP 관련 설정을 지정한다.

    • include /etc/nginx/mime.types;
      MIME 유형을 정의한 파일을 포함한다. MIME 유형은 파일의 유형과 그 내용을 식별하기 위해 사용된다.

      • MIME 유형은 일반적으로 두 부분으로 구성된다.

        • 주 타입 (Main Type): 데이터의 주요 범주를 나타낸다. 예를 들어, 텍스트, 이미지, 오디오, 비디오 등이 있다.

        • 서브 타입 (Sub Type): 주 타입의 하위 유형을 나타낸다. 예를 들어, 텍스트의 서브 타입으로는 plain, html 등이 있다.

          예를 들어, text/plain, text/html, image/jpeg, application/json과 같은 MIME 유형이 있다.
    • default_type application/octet-stream;
      MIME 유형을 지정하지 않은 파일에 대한 기본 유형을 설정한다. 여기서는 application/octet-stream으로 설정되어 있으며, 이는 이진 파일을 나타낸다.

    • log_format main ...;
      로그 포맷을 정의한다. 해당 부분에서는 로그 포맷의 형식을 지정한다. $remote_addr, $remote_user, $time_local, $request, $status, $body_bytes_sent, $http_referer, $http_user_agent, $http_x_forwarded_for 등의 변수(nginx의 변수)를 포함하는 로그 메시지의 형식으로 지정한다.

      ex. 127.0.0.1 - - [15/Mar/2024:10:30:00 +0000] "GET /index.html HTTP/1.1" 200 1234 "http://example.com/previous-page" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.1234.56 Safari/537.36" "-"

    • access_log /var/log/nginx/access.log main;
      액세스 로그 파일의 경로와 사용할 로그 포맷을 지정한다. 해당 설정은 클라이언트의 요청과 서버의 응답에 대한 로그를 기록한다.

    • sendfile on;
      sendfile 시스템 호출은 파일을 커널 버퍼에서 네트워크로 직접 복사하는 방법을 말한다. 이는 파일을 메모리에서 직접 소켓 버퍼로 전송하기 때문에, 시스템 자원을 절약하면서 파일을 빠르고 효율적으로 전송할 수 있다. 일반적으로 서버 구성에서 sendfile on;으로 설정하는 것이 권장된다.

    • keepalive_timeout 65;
      클라이언트와 서버 간의 keep-alive 연결을 유지하는 시간을 설정한다. 해당 구성에서는 65초로 설정한다.

    • upstream docker-nginx
      docker-nginx라는 업스트림 서버(NGINX에서 프록시하는 대상 서버의 그룹)를 정의한다. 해당 서버는 NGINX 프록시 서버로 사용될 것이며, nginx:80 서버를 가리킨다. 따라서 NGINX는 이 업스트림 서버로 클라이언트 요청을 프록시한다.

      cf. upstream [원하는 업스트림 서버 이름(일종의 변수 이름임)]
      cf. nginx는 docker-compose.yml의 nginx 서버를 의미.

    • upstream docker-apache
      docker-apache라는 업스트림 서버를 정의한다. 해당 서버는 Apache 웹 서버로 사용될 것이며, apache:80 서버를 가리킨다.

    • server {~}

      • listen 8080;
        포트 8080에서 들어오는 요청을 처리한다.

      • location / {~}
        모든 경로에 대한 요청을 처리한다.

      • proxy_pass http://docker-nginx;
        요청을 http://docker-nginx로 프록시하도록 지시한다. 여기서 docker-nginx는 이전에 정의된 Nginx 업스트림 서버를 가리킨다.

        cf. 밑의 해당 설정들은 일반적으로는 별도로 바꾸지 않고 그대로 사용한다. 참고만 해도 된다.
        reverse proxy와 내부 서버 사이에 http 통신을 할 시, 실제 외부 클라이언트의 정보가 누락되므로 이상동작을 할 수 있어 밑의 설정들을 해준다.

        • proxy_redirect
          내부 서버에서 클라이언트로 보내주는 응답 헤더의 주소 변경 여부 설정.
          보안의 이유로 내부 서버의 주소를 외부 클라이언트에게 숨길 수 있다.

        • proxy_set_header
          프록시된 요청에 추가적인 헤더를 설정한다.

        • Host $host;
          프록시 서버의 이름을 의미한다. (프록시 서버가 여러개일 수 있다.)

        • X-Real-IP $remote_addr;
          클라이언트 IP 주소를 의미한다.

        • X-Forwarded-For $proxy_add_x_forwarded_for;
          클라이언트 IP부터 중간 서버 IP들을 리스트로 작성한다.
          해당 설정이 없으면, 모든 http 요청은 reverse proxy가 한 것으로 기록되므로, 클라이언트 IP 기록을 위해 필요하다.

        • X-Forwarded-Host $server_name;
          클라이언트 호스트 이름을 식별하기 위한 설정이다.

        • proxy_set_header X-Forwarded-Proto $scheme;
          원래 클라이언트가 요청할 때 사용한 프로토콜은 무엇인지를 의미한다. (ex. https)



해당 글은 다음 강의의 내용을 참고한 글임을 밝힙니다. 자세한 내용은 다음 강의에서 확인해볼 수 있습니다.
인프런, 잔재미 코딩, ⌜풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]⌟
profile
블로그 이관했습니다.

0개의 댓글