๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Develop ๐Ÿ’ป/Docker

[Docker] Docker๋ฅผ ์ด์šฉํ•œ Nginx Reverse Proxy ์„œ๋ฒ„

by jungin 2021. 7. 27.

Intro


์ฒ˜์Œ์—๋Š” ๋‹จ์ˆœํžˆ ํ•˜๋‚˜์˜ ์„œ๋ฒ„๋ฅผ ๊ฐ€์ง€๊ณ  ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์›น ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์‹ถ์–ด ์‹œ์ž‘ํ•˜์˜€๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ณต๋ถ€๋ฅผ ํ•˜๋ฉด ํ• ์ˆ˜๋ก Reverse Proxy ์„œ๋ฒ„๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๊ณ  Docker๋ฅผ ์ด์šฉํ•˜๋ฉด์„œ ์—ฌ๋Ÿฌ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ฒช์—ˆ๊ธฐ์— ๊ธ€๋กœ ๊ธฐ๋กํ•ด๋ณธ๋‹ค..

 

What is Proxy Server??


ํ”„๋ก์‹œ ์„œ๋ฒ„๋Š” ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž์™€ ์„œ๋ฒ„์™€์˜ ์ค‘๊ณ„์ธ ์—ญํ• ์„ ํ•ด์ค€๋‹ค

ํ”„๋ก์‹œ๋Š” ํฌ๊ฒŒ Forward Proxy์™€ Reverse Proxy๋กœ ๋‚˜๋‰œ๋‹ค

 

Forward Proxy


Forward Proxy๋Š” ์ธํ„ฐ๋„ท์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์ „์— ํ”„๋ก์‹œ ์„œ๋ฒ„ํ•œํ…Œ ์š”์ฒญ์„ ํ•˜๊ณ  ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ์‹ค์ œ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ํ•œ ํ›„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ์ „๋‹ฌํ•ด์ค€๋‹ค. 

์‰ฝ๊ฒŒ ๋งํ•ด์„œ ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ ๋Œ€์‹  ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค ! ๋งŒ์•ฝ์— ์šฐ๋ฆฌ๊ฐ€ ๊ณต์œ ๊ธฐ์— ์—ฐ๊ฒฐ๋œ ์ปดํ“จํ„ฐ๋กœ naver.com์„ ์—ฐ๊ฒฐํ•˜๋ฉด naver.com์— ์ง์ ‘ ์š”์ฒญํ•œ ๊ฒƒ์€ ์šฐ๋ฆฌ ์ง‘ ์ปดํ“จํ„ฐ๊ฐ€  ์•„๋‹ˆ๋ผ ๊ณต์œ ๊ธฐ(proxy)๊ฐ€ ์š”์ฒญ์„ ํ•œ ๊ฒƒ์ด๋‹ค.

Forward Proxy์˜ ์žฅ์ 

1. ํด๋ผ์ด์–ธํŠธ ์ž…์žฅ์—์„œ ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ๋Œ€์‹  ์š”์ฒญํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ์˜ IP๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

2. ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•ด์„œ ๋„คํŠธ์›Œํฌ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ทธ ์™ธ ๋ณด์•ˆ ๋“ฑ๋“ฑ..

Reverse Proxy


Reverse Proxy๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‚ด๋ถ€ ์„œ๋ฒ„์— ์ ‘๊ทผ ์‹œ, Proxy ์„œ๋ฒ„๋ฅผ ๋จผ์ € ๊ฑฐ์นœ ํ›„์— ๋‚ด๋ถ€ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์ด๋‹ค.

Reverse Proxy์˜ ์žฅ์ 

1. Forward์™€๋Š” ๋ฐ˜๋Œ€๋กœ ํด๋ผ์ด์–ธํŠธ๋Š” ์‹ค์ œ ๋‚ด๋ถ€๋ง์— ์žˆ๋Š” ์„œ๋ฒ„์˜ IP๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋‹ค

2. ํ•˜๋‚˜์˜ IP, ์„œ๋ฒ„๋ฅผ ๊ฐ€์ง€๊ณ   ์„œ๋ธŒ๋„๋ฉ”์ธ์„ ์ด์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์›น ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‚ด๊ฐ€ ์ด๊ฑฐ ํ•˜๋ ค๊ณ  ์Œฉ๊ณ ์ƒ์„ ํ–ˆ๋‹ค.)

3. ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ์„ ํ†ตํ•ด ์š”์ฒญ์„ ๋ถ„๋ฐฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

How to use Nginx Reverse Proxy with Docker?


Docker ๊ฐœ๋…๋งŒ ์•Œ๊ณ  ์‹ค์ œ๋กœ ์จ๋ณด์งˆ ๋ชปํ•ด์„œ ์ด๋ฒˆ์— ํ•œ ๋ฒˆ ์จ ๋ณด์ž ํ•˜๋Š” ๋งˆ์Œ์œผ๋กœ docker๋ฅผ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„ ์„ธํŒ…์„ ํ•ด๋ณด์•˜๋‹ค. ์‹ค์ œ ์„œ๋น„์Šค๋Š” ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ์ด๋‹ค.

Nginx Reverse Proxy ์„œ๋ฒ„๋ฅผ ์ด์šฉํ•˜์—ฌ nginx ์„œ๋ฒ„ ๋‘๊ฐœ์™€ node api ์„œ๋ฒ„๋ฅผ ์—ฐ๊ฒฐํ•  ๊ฒƒ์ด๋‹ค.

ํŒŒ์ผ ๊ตฌ์กฐ๋Š” ์ด๋Ÿฌํ•ฉ๋‹ˆ๋‹ค.

- workspace
ใ„ด dev
	ใ„ด source
    ใ„ด nginx.conf
ใ„ด main
	ใ„ด source
    ใ„ด nginx.conf
ใ„ด study_apiServer
	ใ„ด ์†Œ์ŠคํŒŒ์ผ
    ใ„ด Dockerfile
    ใ„ด .dockerignore
ใ„ด proxy
	ใ„ด nginx.conf
ใ„ด docker-compose.yml

docker-compose.yml


version: "3"
services:
  nginx-proxy:
    container_name: nginx-proxy
    depends_on:
      - main
      - dev
      - express
    image: nginx:latest
    ports:
      - "80:80"
      - "433:433"
    volumes:
      - ./proxy/nginx.conf:/etc/nginx/nginx.conf
    restart: always
  main:
    container_name: main
    image: nginx:latest
    expose:
      - "8080"
    volumes:
      - ./main/nginx.conf:/etc/nginx/nginx.conf
      - /root/workspace/main/source:/usr/share/nginx/html
    restart: always
  dev:
    container_name: dev
    image: nginx:latest
    expose:
      - "8081"
    volumes:
      - ./dev/nginx.conf:/etc/nginx/nginx.conf
      - /root/workspace/dev/source:/usr/share/nginx/html
    restart: always
  express:
    build:
      context: ./study_apiServer 
    container_name: express
    expose:
      - "8082" 
    volumes:
      - ./study_apiServer:/source 
      - /study_apiServer/node_modules 
    restart: "unless-stopped"

nginx-proxy: Reverse Proxy ์—ญํ• ์„ ์ปจํ…Œ์ด๋„ˆ์ด๋ฉฐ host์™€ 80,443 ํฌํŠธ๋ฅผ ๋ฐ”์ธ๋”ฉํ–ˆ์Šต๋‹ˆ๋‹ค. depends_on์œผ๋กœ main, dev, express๊ฐ€ ์‹คํ–‰๋œ ํ›„ ์ œ์ผ ๋งˆ์ง€๋ง‰์— ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. volumes์œผ๋กœ host์˜

./proxy/nginx.conf์™€ /etc/nginx/nginx.conf ํŒŒ์ผ์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

main: static ํ™”๋ฉด์„ ๋ณด์—ฌ์ค„ nginx ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. expose๋กœ ๋„์ปค ๋‚ด๋ถ€์—์„œ 8080 ํฌํŠธ๋ฅผ openํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. host์˜

./main/nginx.conf, /root/workspace/main/source๋ฅผ ๊ฐ๊ฐ /etc/nginx/nginx.conf, /usr/share/nginx/html๊ณผ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

dev: main๊ณผ ๊ฐ™์œผ๋ฉฐ 8081 ํฌํŠธ๋ฅผ openํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค

 

express: node๋กœ ๋˜์žˆ๋Š” api ์„œ๋ฒ„์ด๋ฉฐ host์˜ ./study_apiServer ๊ณผ /source ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. build์—์„œ context ์œ„์น˜์— ์žˆ๋Š” dockerfile์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•œ ํ›„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

Reverse Proxy ์„œ๋ฒ„ ์—ญํ• ์„ ํ•  Nginx์˜ nginx.conf 


# proxy/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;
   
    server {
        server_name jungin.me;
        location / {
            proxy_pass         http://main:8080;
            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;
        }
    }
    server{
        server_name dev.jungin.me;
        location / {
            proxy_pass        http://dev:8081;
            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;
        }
    }

    server {
        server_name studyapi.jungin.me;
        location / {
            proxy_pass         http://express:8082;
	    proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }


    
    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;
    include /etc/nginx/conf.d/*.conf;
}

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ๋งŒ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

server {
        server_name jungin.me;
        location / {
            proxy_pass         http://main:8080;
            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;
        }
    }

server_name , jungin.me๋กœ ์š”์ฒญ์ด ์˜ค๋ฉด proxy_pass http://main:8080์œผ๋กœ ๊ฐ€๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.  nginx ์›น์„œ๋ฒ„์˜ nginx.conf ์„ ๋ณด๋ฉด

worker_processes  1;
events {
    worker_connections  1024;
}
http{
    server {
    listen 8080;
 
    server_name jungin.me;
    root /usr/share/nginx/html;
    index index.html;
 
    error_log /var/log/nginx/api_error.log;
    access_log /var/log/nginx/api_access.log;
   }
}

8080 ํฌํŠธ๋ฅผ listen์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ root ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ /usr/share/nginx/html๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

api ์„œ๋ฒ„๋Š” dockerfile์„ ์ด์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ณ  8082 ํฌํŠธ๋ฅผ ์˜คํ”ˆํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

dockerfile์€ ์ด๋Ÿฌํ•ฉ๋‹ˆ๋‹ค

FROM node:12

WORKDIR /study_apiServer
COPY . .

RUN npm install

CMD node ./bin/www

.dockerignore์€ node_modules์€ image๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฌด์‹œํ•˜๋„๋ก ์„ค์ •ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. gitignore๊ณผ ์‚ฌ์šฉ๋ฒ•์ด ๊ฐ™์Šต๋‹ˆ๋‹ค.

node_moudles/

Do it !


์ด์ œ ์„ค์ •์„ ๋‹ค ํ–ˆ์œผ๋‹ˆ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค.

docker-compose up -d

๋จผ์ € nginx ์›น์„œ๋ฒ„๋ถ€ํ„ฐ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค

jungin.me
dev.jungin.me

์ด์ œ api ์„œ๋ฒ„๊ฐ€ ์ž˜ ๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด postman์„ ~~

studyapi.jungin.me

์š”์ฒญ์— ๋งž๊ฒŒ ์ž˜ ์˜ค๋„ค์š” !! ~

 

Reference


https://medium.com/sjk5766/docker-compose%EB%A1%9C-localhost-nginx-%EB%A6%AC%EB%B2%84%EC%8A%A4-%ED%94%84%EB%A1%9D%EC%8B%9C-%EA%B5%AC%EC%84%B1-8214d41a94fc

๋Œ“๊ธ€