본문 바로가기
Docker

Docker - reverse proxy와 nginx 웹서버의 주요 설정

by DGK 2021. 12. 25.

 

도커 입문 수업을 듣고 중요한 내용을 정리했습니다.
개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.

 

reverse proxy & nginx 

nginx 웹 서버의 reverse proxy 테스트를 통해 proxy server의 개념을 학습하고자 한다.

 

proxy server 란?

proxy server는 클라이언트(client)가 다른 네트워크 서비스(server)에 간접적으로 접속할 수 있도록 해주는 시스템 또는 프로그램이다.

 

*참고내용

 

   - forward proxy

 

client가 proxy server에 외부 인터넷 접근을 요청하면, proxy server는 client를 대신하여 외부의 인터넷에 접속한 후 결과를 받아서 이를 client에 다시 전달한다. (client가 직접 외부 인터넷에 접근하는 것이 아님)

 

   - reverse proxy

 

client가 reverse proxy에 접근 요청을 하면, reverse proxy는 관련 요청에 따라 적절한 내부 서버에 접속하여 결과를 받은 후 이를 client에 다시 전달한다. (client가 직접 서버에 접근하는 것이 아님)

 

 

nginx reverse proxy test(1) 

*포트로 구분하기

 

docker-compose를 통해 각각의 nginx reverse proxy 서버와 내부 서버 nginx, apache를 만든 후에, nginx reverse proxy 서버에 두 개의 포트를 오픈하고 외부 IP주소에서 각 포트로 접근 요청을 하면 내부 서버로부터 결과를 받은 후 이를 리턴하는 테스트이다. (nginx의 location 설정으로 nginx reverse proxy 서버 기능을 구현하는 테스트)

 

 

[1단계]

vi docker-compose.yml

 

테스트 폴더에서 docker-compose.yml 파일을 오픈한다.

 

vi docker-compose.yml

 

YAML 파일에서 nginx reverse proxy 서버와 내부 서버인 nginx, apache 서버를 각각 docker container로 만든다. (총 3개의 서버)

 

이 때, 내부 서버는 포트 설정을 두지 않고 오직 nginx reverse proxy 서버의 포트를 통해서만 접속할 수 있도록 한다.

즉, nginx reverse proxy 서버에 두 개의 포트를 오픈하여 각 포트로 내부 서버에 접근할 수 있도록 하는 것이다.

(포트로 접근 구분)

 

 

[2단계]

vi nginx.conf

 

nginx reverse proxy 서버의 기본 설정 파일인 nginx.conf를 오픈한다.

 

nginx/nginx.conf

 

nginx/nginx.conf

 

nginx reverse proxy 서버의 기본 설정 파일인 nginx.conf 파일에서 기존의 설정은 유지한 채 upstream 설정과 server 항목의 location 설정을 추가한다.

 

단, default.conf 설정과 겹치지 않기 위해 해당 파일에서 include /etc/nginx/conf.d/*.conf; 설정은 삭제했다. 

 

*참고내용

 

   - upstream 설정

upstream docker-nginx {
        server nginx:80;
    }

    upstream docker-apache {
        server apache:80;
    }

 

upstream 설정은 docker-compose를 통해 docker container 안에서 실행되는 각각의 내부 서버인 nginx와 apache의 80번 포트를 오픈하는 설정이다. 즉, nginx reverse proxy 서버와 각각의 내부 서버들 사이에 (내부)통신을 할 때 필요한 포트를 오픈하는 설정이다.

 

   - server 항목(location 설정)

    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;
        }
    }

 

앞서 삭제한 default.conf 파일에 존재하는 server 항목을 해당 파일(nginx.conf)에 새로운 설정으로 추가한 것이다.

(nginx 웹 서버의 설정 충돌을 방지하기 위함)

 

위의 location 설정은 각 포트(8080 or 8081)로 들어온 요청을 proxy_pass에 적힌 경로로 전달해주는 설정이다.

즉, 8080 포트로 외부 요청이 들어오면 location 설정에 따라 " http://docker-nginx; "로 해당 요청을 전송하고, 8081 포트로 외부 요청이 들어오면 location 설정에 따라 " http://docker-apache; "로 해당 요청을 전송해주는 설정이다.

 

 

[3단계]

docker-compose up -d

 

" docker-compose up -d " 명령을 사용하여 YAML 파일로 총 세 개의 docker container를 생성한 후 실행시킨다.

 

docker ps -a

 

docker-compose를 통해 실행 중인 docker container를 확인할 수 있다. (nginx reverse proxy, nginx, apache)

 

EC2 서버의 보안그룹 인바운드규칙

 

그 후에, EC2 서버의 보안그룹에서 8080포트와 8081포트를 오픈하는 인바운드규칙을 추가해야 한다. 

 

3.38.14.143:8080
3.38.14.143:8081

 

마지막으로 외부 IP주소:8080 또는 외부 IP주소:8081로 접속하면, 이제는 위의 결과처럼 nginx와 apache의 default index.html 파일이 각각 리턴되는 것을 확인할 수 있다.

 

 

nginx reverse proxy test(2) 

*경로로 구분하기

 

docker-compose를 통해 각각의 nginx reverse proxy 서버와 내부 서버 nginx, apache를 만든 후에, nginx reverse proxy 서버에 80포트를 오픈하고 외부 IP주소에서 해당 포트의 특정 경로로 접근을 요청하면 경로에 맞는 내부 서버로부터 결과를 받은 후 이를 리턴하는 테스트이다. (nginx의 location 설정으로 nginx reverse proxy 서버 기능을 구현하는 테스트)

 

 

[1단계]

vi docker-compose.yml

 

테스트 폴더에서 docker-compose.yml 파일을 오픈한다.

 

vi docker-compose.yml

 

YAML 파일에서 nginx reverse proxy 서버와 내부 서버인 nginx, apache 서버를 각각 docker container로 만든다. (총 3개의 서버)

 

이 때, 내부 서버는 포트 설정을 두지 않고 오직 nginx reverse proxy 서버의 포트를 통해서만 접속할 수 있도록 한다.

즉, nginx reverse proxy 서버에 80포트를 오픈하여 요청 경로에 맞는 내부 서버에 접근할 수 있도록 하는 것이다.

(경로로 접근 구분)

 

 

[2단계]

vi nginx.conf

 

nginx reverse proxy 서버의 기본 설정 파일인 nginx.conf를 오픈한다.

 

nginx/nginx.conf

 

nginx/nginx.conf

 

nginx reverse proxy 서버의 기본 설정 파일인 nginx.conf 파일에서 기존의 설정은 유지한 채 upstream 설정과 server 항목의 location 설정을 추가한다. 

 

즉, listen 설정으로 80포트를 오픈하고 location 설정으로 blog 경로와 community 경로의 설정을 만들어 준다.

 

*참고내용

 

   - upstream 설정

upstream docker-nginx {
        server nginx:80;
    }

    upstream docker-apache {
        server apache:80;
    }

 

upstream 설정은 docker-compose를 통해 docker container 안에서 실행되는 각각의 내부 서버인 nginx와 apache의 80번 포트를 오픈하는 설정이다. 즉, nginx reverse proxy 서버와 각각의 내부 서버들 사이에 (내부)통신을 할 때 필요한 포트를 오픈하는 설정이다.

 

   - server 항목(location 설정)

server {
        listen 80;

        location /blog/ {
            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;
        }

        location /community/ {
            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;
        }
    }

 

이전의 테스트와 동일하게, 원래 default.conf 파일에 존재하는 server 항목을 해당 파일(nginx.conf)에 새로운 설정으로 추가한 것이다. (nginx 웹 서버의 설정 충돌을 막기 위함) 

 

위의 location 설정은 80포트를 통해 특정 경로로 들어온 요청을 proxy_pass에 적힌 경로로 전달해주는 설정이다.

즉, " 외부 IP주소/blog "로 요청이 들어오면 location 설정에 따라 " http://docker-nginx; "로 해당 요청을 전송하고, " 외부 IP주소/community "로 요청이 들어오면 location 설정에 따라 " http://docker-apache; "로 해당 요청을 전송해주는 설정이다.

 

 

[3단계]

docker-compose up -d

 

" docker-compose up -d " 명령을 사용하여 YAML 파일로 총 세 개의 docker container를 생성한 후 실행시킨다.

docker-compose를 통해 실행 중인 docker container를 확인할 수 있다. (nginx reverse proxy, nginx, apache)

 

 

[4단계]

docker exec -it 04_nginx_proxy_path_nginx_1 /bin/bash

 

" docker exec -it 컨테이너명 /bin/bash " 명령으로 nginx 내부 서버가 실행 중인 컨테이너로 들어간다.

그 다음 find 명령으로 nginx 내부 서버의 기본 설정 파일(nginx.conf)이 존재하는 경로를 찾은 후, " vi nginx.conf " 명령으로 해당 파일에 들어간다.

 

/etc/nginx/nginx.conf

 

해당 파일의 include 설정을 참고하여, /etc/nginx/conf.d/ 경로로 이동하여 추가적으로 nginx 내부 서버의 기본 설정을 확인한다.

 

vi default.conf

 

" vi default.conf " 명령으로 /etc/nginx/conf.d/ 경로에 존재하는 default.conf 파일에 들어간다.

 

/etc/nginx/conf.d/default.conf

 

default.conf 파일의 location 설정에 따라, nginx 내부 서버의 디폴트 파일이 존재하는 경로를 확인한다.

(root 폴더 : /usr/share/nginx/html)

 

/usr/share/nginx/html

 

/usr/share/nginx/html 경로로 이동한 후, " mkdir blog " 명령으로 blog 디렉토리를 만들고 해당 디렉토리에 test.html 파일을 만든다.

 

/usr/share/nginx/html/blog/test.html

 

/usr/share/nginx/html/blog/test.html

 

해당 파일(test.html)은 /usr/share/nginx/html/blog 경로에 존재하는 파일로, 만약 외부 IP주소/blog/test.html의 경로로 nginx 내부 서버에 접속하면 디폴트 값으로 test.html 파일을 리턴할 것이다.

 

 

[5단계]

3.38.14.143/blog/test.html

 

이는 nginx reverse proxy 서버를 통해 외부 IP주소/blog/test.html 경로로 nginx 내부 서버에 접속하여 얻은 결과 값을 리턴한 것이다.

 

단, EC2 서버의 보안그룹에서 80포트를 오픈하는 인바운드 규칙을 추가해야 한다.

 

 

*참고내용

nginx reverse proxy 서버를 통해 community 경로로 apache 내부 서버에 접속하는 과정도 blog 경로로 nginx 내부 서버에 접속하는 과정과 동일하다.

 

(요약)

 

[1단계]

docker exec -it 04_nginx_proxy_path_apache_1 /bin/bash

 

[2단계]

/usr/local/apache2/conf

 

[3단계]

vi httpd.conf

 

[4단계]

/usr/local/apache2/htdocs/community

 

[5단계]

vi test.html

 

[6단계]

3.38.14.143/community/test.html

 

 

nginx reverse proxy test(3) 

*경로로 구분하기(내부 서버에 요청하는 경로 변경)

 

기본적으로 테스트(2)에서 진행했던 경로로 구분하는 방식과 거의 동일하지만 내부 서버에 요청하는 경로가 변경된다는 차이점이 존재한다.

 

예를 들어, 외부 IP주소/blog/index.html로 nginx reverse proxy 서버에 요청할 경우 nginx와 apache 내부 서버에는 외부 IP주소/index.html로 요청한 것으로 경로가 변경되는 것이다.

(nginx의 location 설정으로 nginx reverse proxy 서버 기능을 구현하는 테스트)

 

 

[1단계]

vi docker-compose.yml

 

테스트 폴더에서 docker-compose.yml 파일을 오픈한다.

 

 

[2단계]

docker-compose.yml

 

YAML 파일에서 nginx reverse proxy 서버와 내부 서버인 nginx, apache 서버를 각각 docker container로 만든다. (총 3개의 서버)

 

이 때, 내부 서버는 포트 설정을 두지 않고 오직 nginx reverse proxy 서버의 포트를 통해서만 접속할 수 있도록 한다.

즉, nginx reverse proxy 서버에 80포트를 오픈하여 요청 경로에 맞는 내부 서버에 접근할 수 있도록 하는 것이다.

(경로로 접근 구분)

 

 

[3단계]

nginx/nginx.conf

 

nginx reverse proxy 서버의 기본 설정 파일인 nginx.conf를 오픈한다.

 

nginx.conf

 

nginx.conf

 

nginx reverse proxy 서버의 기본 설정 파일인 nginx.conf 파일에서 기존의 설정은 유지한 채 upstream 설정과 server 항목의 location 설정을 추가한다.

 

즉, listen 설정으로 80포트를 오픈하고 location 설정으로 blog 경로와 community 경로의 설정을 만들어 준다.

또한, 내부 서버로 요청되는 경로를 변경하기 위해서는 location 설정의 rewrite 옵션을 추가해야 한다.

 

*참고내용

 

   - upstream 설정

 

upstream 설정은 앞서 진행한 테스트(2)의 설정과 동일하다. 

 

   - server 항목(location 설정)

server {
        listen 80;

        location /blog/ {
            rewrite            ^/blog(.*)$ $1 break;
            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;
        }

        location /comm/ {
            rewrite            ^/comm(.*)$ $1 break;
            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;
        }
    }

 

(rewrite 옵션의 이해)

 

   - 기본 구조

rewrite regex URL [flag];

 

  • regex는 정규표현식으로 매칭되는 URL 패턴을 설정한다.
  • URL에는 변경될 URL을 설정한다.
  • [flag]에는 주로 break가 사용된다.
  • break는 다수의 location 설정으로 변경된 URL이 또 다시 location에 매칭되는 것을 방지하는 설정이다.

 

   - 예시

rewrite ^/blog(.*)$ $1 break;

 

 

  • ^는 문자열의 시작을 의미하므로, ^/blog는 " /blog "로 시작하는 URL 경로를 뜻한다.
  • (.*)은 임의의 한 문자가 0회 이상 등장하는 것을 의미한다.
  • $은 끝나는 문자열을 의미한다.
  • $1은 (.*)의 부분을 의미한다.

즉, 위의 규칙들의 의미를 종합해보면 ^/blog(.*)$은 blog로 시작하며 그 뒤로 임의의 문자 1개가 등장하고 끝나거나 어떤 문자도 등장하지 않고 끝나는 경우를 의미한다. 또한, $1은 (.*)의 부분을 뜻하기 때문에 결국 " ^/blog(.*)$ $1 "은 nginx reverse proxy 서버로 요청된 경로 " ^blog(.*)$ "를 (.*)로 변경하겠다는 의미이다.

(ex. 외부 IP주소/blog/index.html -> 외부 IP주소/index.html)

 

 

[4단계]

docker-compose up -d

 

" docker-compose up -d " 명령을 사용하여 YAML 파일로 총 세 개의 docker container를 생성한 후 실행시킨다.

docker-compose를 통해 실행 중인 docker container를 확인할 수 있다. (nginx reverse proxy, nginx, apache)

 

docker exec -it 05_nginx_proxy_ch_path_nginx_1 /bin/bash

 

" docker exec -it 컨테이너명 /bin/bash " 명령으로 nginx 내부 서버가 실행 중인 컨테이너로 들어간다.

그 다음 find 명령으로 nginx 내부 서버의 기본 설정 파일(nginx.conf)이 존재하는 경로를 찾은 후, " vi nginx.conf " 명령으로 해당 파일에 들어간다.

 

 

[5단계]

vi nginx.conf

 

해당 파일의 include 설정을 참고하여, /etc/nginx/conf.d/ 경로로 이동하여 추가적으로 nginx 내부 서버의 기본 설정을 확인한다.

 

vi default.conf

 

" vi default.conf " 명령으로 /etc/nginx/conf.d/ 경로에 존재하는 default.conf 파일에 들어간다.

 

/etc/nginx/conf.d/default.conf

 

default.conf 파일의 location 설정에 따라, nginx 내부 서버의 디폴트 파일이 존재하는 경로를 확인한다.

(root 폴더 : /usr/share/nginx/html)

 

/usr/share/nginx/html

 

/usr/share/nginx/html 경로로 이동하여, 해당 경로에 index.html 파일이 존재하는 것을 확인한다.

 

 

[6단계]

vi index.html

 

3.38.14.143/blog/index.html

 

3.38.14.143/comm/index.html

 

위의 결과는 " 외부 IP주소/blog/index.html "과 " 외부 IP주소/comm/index.html " 경로로 nginx reverse proxy 서버에 요청하여 내부 서버인 nginx와 apache에 접속하여 결과 값을 리턴한 것이다.

 

이 때, " blog "와 " comm "이라는 경로로 nginx reverse proxy 서버에 요청했지만 내부 서버에서는 해당 경로를 제외하고 리턴한 것을 알 수 있다. 즉, 3.38.14.143/blog/index.html 경로는 3.38.14.143/index.html 경로로 변경되어 nginx 내부 서버로 접속된 것이다.

 

이것이 nginx 내부 서버의 /usr/share/nginx/html 경로에 존재하는 index.html 파일이 리턴된 이유이다.

참고로, 3.38.14.143/comm/index.html 경로도 3.38.14.143/index.html 경로로 변경되어 apache 내부 서버에 접속된 것이다.

 

 

댓글