๊ด€๋ฆฌ ๋ฉ”๋‰ด

JiYoung Dev ๐Ÿ–ฅ

Nginx๋กœ Reverse Proxy ์„ค์ •ํ•˜๊ธฐ ๋ณธ๋ฌธ

Study/Back-End

Nginx๋กœ Reverse Proxy ์„ค์ •ํ•˜๊ธฐ

Shinjio 2024. 11. 6. 21:43
๋ฐ˜์‘ํ˜•

๐Ÿ”Ž ๋ฌธ์ œ ์ƒํ™ฉ

์ „์‹œํšŒ ์ฐธ์—ฌ๋ฅผ ์œ„ํ•ด ์‚ฌ๋‚ด ์„œ๋ฒ„(Private๋ง)์— ๊ตฌ์ถ•๋˜์–ด ์žˆ๋Š” ์†”๋ฃจ์…˜์„ ์™ธ๋ถ€๋ง์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„คํŠธ์›Œํฌ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ผ์ด ์žˆ์—ˆ๋‹ค. ๋ผ์šฐํŒ…์„ ํ–ˆ๋Š”์ง€ ์•„๋‹˜ ํฌํŠธํฌ์›Œ๋”ฉ์„ ํ–ˆ๋Š”์ง€๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ(์•„๋งˆ๋„ ํฌํŠธํฌ์›Œ๋”ฉ?) ์–ด์จŒ๋“  ๊ฒฐ๋ก ์€ ์‚ฌ๋‚ด๋ง IP๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋˜ ๊ฒƒ์„ ์™ธ๋ถ€๋ง์—์„œ๋„ ์ ‘์†์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ณ€๊ฒฝํ•œ ๊ฒƒ์ด๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ์ด๋ ‡๊ฒŒ ์™ธ๋ถ€๋ง์—์„œ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ๋ฆฌ์•กํŠธ ์•ฑ์ด ์—ฐ๊ณ„๋œ API ์„œ๋ฒ„์™€ ์—ฐ๋™์ด ์•ˆ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค. ํ˜„์žฌ ์šฐ๋ฆฌ ์†”๋ฃจ์…˜์˜ ์•„ํ‚คํ…์ฒ˜๋Š” ์•ฝ๊ฐ„ ๋…ํŠนํ•˜๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š”๋ฐ CSR์ธ ๋ฆฌ์•กํŠธ๋ฅผ Node.js ์„œ๋ฒ„ ์œ„์— ์˜ฌ๋ฆฌ๊ณ , ๋ฆฌ์•กํŠธ์—์„œ Node.js, Spring Server ๋ฐ python Server์™€ ํ†ต์‹ ํ•˜๋Š” ๊ตฌ์กฐ์ด๋‹ค.

 

 

๋ฆฌ์•กํŠธ ์•ฑ์—์„œ ๊ฐ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” API URL์„ ์‚ฌ๋‚ด๋ง ์„œ๋ฒ„์˜ IP๋กœ ์—ฐ๋™์„ ํ•ด ๋‘์—ˆ๋Š”๋ฐ, ๋ฆฌ์•กํŠธ๊ฐ€ ์™ธ๋ถ€๋ง์—์„œ ๋™์ž‘ํ•˜๋‹ค ๋ณด๋‹ˆ ์‚ฌ๋‚ด๋ง์œผ๋กœ ์ ‘๊ทผ์ด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๋‹ค.

 

์™ธ๋ถ€๋ง์—์„œ ๋ฆฌ์•กํŠธ ์•ฑ์ด ๋กœ๋“œ ๋˜์—ˆ์„ ๋•Œ์—๋Š” ๋ฆฌ์•กํŠธ ์•ฑ์ด ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์‹คํ–‰๋˜๋ฏ€๋กœ, ๋‚ด๋ถ€๋ง์œผ๋กœ ์ง์ ‘ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. (์™ธ๋ถ€๋งIP๋ฅผ ํ†ตํ•ด ๋‚ด๋ถ€๋งIP๋กœ์˜ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•˜๋”๋ผ๋„, ์‹ค์ œ ๋„คํŠธ์›Œํฌ๋Š” ๊ฒฉ๋ฆฌ๋œ ์ƒํƒœ)

๋”ฐ๋ผ์„œ ์™ธ๋ถ€๋ง IP๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•˜๊ณ , ์ด๋ฅผ ์œ„ํ•ด Reverse Proxy ์„ค์ •์„ ํ†ตํ•ด ๋‚ด๋ถ€๋ง์œผ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

 

๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Nginx๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ(์™ธ๋ถ€๋ง)์—์„œ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์„ Nginx๋ฅผ ๊ฑฐ์ณ ์„œ๋ฒ„์— ์ „๋‹ฌ์ด ๋˜๋„๋ก ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

 

๐ŸŽ ํ•ด๊ฒฐ๋ฐฉ์•ˆ

โœ” Reverse Proxy๋ž€

Reverse Proxy๋ž€ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋Œ€์‹  ๋ฐ›์•„ ๋‚ด๋ถ€ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด /api/spring ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ๋“ค์€ Nginx์˜ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„ค์ •์„ ํ†ตํ•ด ์Šคํ”„๋ง ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , /api/python ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์€ ํŒŒ์ด์ฌ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ํ•œ๋‹ค.

 

โœ” Nginx Reverse Proxy ์„ค์ •

# nginx์˜ ๊ธฐ๋ณธ server ๋ธ”๋ก ์„ค์ •
# /etc/nginx/conf.d/default.conf

server {
    listen       80;
    server_name  localhost;

		location / {
		    proxy_pass http://127.0.0.1:8080;
		}
		
		location /api {
		    proxy_pass http://127.0.0.1:5000;
		}
}

 

Nginx ์„ค์ •์„ ์œ„์™€ ๊ฐ™์ด ํ•˜๊ฒŒ ๋˜๋ฉด localhost์˜ 80ํฌํŠธ๋ฅผ nginx๊ฐ€ ๋ณด๊ณ  ์žˆ์–ด, localhost์˜ 80 ํฌํŠธ๋กœ ์ ‘์†ํ•˜๋ฉด nginx๋กœ ์ ‘์†ํ•˜๊ฒŒ ๋˜๊ณ  localhost:80/ ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ•  ๋•Œ์—๋Š” 8080 ํฌํŠธ๋กœ ์š”์ฒญ์ด ์ „๋‹ฌ๋˜๊ณ , localhost:80/api ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ•˜๋ฉด 5000 ํฌํŠธ๋กœ ์š”์ฒญ์ด ์ „๋‹ฌ๋œ๋‹ค.

 

 

์‹ค์ œ๋กœ๋Š” ์œ„์˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •์„ ์ž‘์„ฑํ•˜์˜€๋‹ค.

api ํ˜น์€ ai์ผ ๊ฒฝ์šฐ์˜ ๊ฒฝ๋กœ๋ฅผ ์šฐ์„  ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด location์˜ ์œ„์น˜๋ฅผ /api, /ai ๋‹ค์Œ /๋กœ ์„ค์ • ํ•˜์˜€๋‹ค.

 

server {
    listen       5000;
    server_name  ์‚ฌ๋‚ด๋งIP;
    
		location /api {
		    proxy_pass http://์‚ฌ๋‚ด๋งIP:3000/api;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		    proxy_set_header Host $host;
		    client_max_body_size 10M;
		}
		
		location /ai {
		    proxy_pass http://์‚ฌ๋‚ด๋งIP:8010/ai;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		    proxy_set_header Host $host;
		    client_max_body_size 10M;
		}
		
		location / {
		    proxy_pass http://์‚ฌ๋‚ด๋งIP:3000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		    proxy_set_header Host $host;
		    client_max_body_size 10M;
		}	
}

 

๐Ÿ‘Š ์ ์šฉ ํ›„ CORS ์—๋Ÿฌ ๋ฐœ์ƒ!

์œ„์™€ ๊ฐ™์ด Nginx ์„ค์น˜ ๋ฐ ์„ค์ • ํ›„ Spring Server๋‹จ์—์„œ CORS ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

์›์ธ์€ Spring Server์—์„œ Cors๊ฐ€ ์‚ฌ๋‚ด๋งIP๋กœ๋งŒ ์„ค์ •์ด ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ฒฐ๊ตญ ์™ธ๋ถ€๋ง์—์„œ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์€ ์™ธ๋ถ€๋ง IP๋ฅผ ํƒ€๊ณ  ๋“ค์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€๋ง IP๊นŒ์ง€ ํ—ˆ์šฉํ•ด์ฃผ์–ด์•ผ CORS ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

Reverse Proxy๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋Œ€์‹  ๋ฐ›์•„ ๋‚ด๋ถ€ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•ด ์ฃผ๋Š” ์—ญํ• ๋งŒ ํ•˜๋ฉฐ, CORS๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์›๋ž˜ ์ถœ์ฒ˜(Origin)์„ ๊ธฐ์ค€์œผ๋กœ ํ—ˆ์šฉ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€๋ง IP๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ฉด ์š”์ฒญ์ด ์ฐจ๋‹จ๋œ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์„ค์ • ํ›„ ํ…Œ์ŠคํŠธ ํ•œ ๊ฒฐ๊ณผ ์ •์ƒ์ ์œผ๋กœ ์š”์ฒญ์„ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

๐Ÿ‘Š ์ ์šฉ ํ›„ 1MB ์ด์ƒ ํŒŒ์ผ ์—…๋กœ๋“œ ์•ˆ๋˜๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ!

๋˜ํ•œ NGINX ์„ค์ • ํ›„ 1MB ์ด์ƒ์˜ ํŒŒ์ผ์ด ์—…๋กœ๋“œ ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ Nginx์—์„œ๋Š” ํŒŒ์ผ ์—…๋กœ๋“œ์‹œ 1M ์ด์ƒ์˜ ํŒŒ์ผ์ด ์—…๋กœ๋“œ ๋˜์ง€ ์•Š๊ฒŒ ๋˜์–ด์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„์˜ conf ํŒŒ์ผ์—์„œ ์—…๋กœ๋“œ ํฌ๊ธฐ ์ œํ•œ ์„ค์ •์„ ๋ณ€๊ฒฝํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

โ‰ proxy_set_header X-Forwarded-For์™€ proxy_set_header Host ์„ค์ •ํ•˜๋Š” ์ด์œ 

  1. X-Forwarded-For
    • ์›๋ž˜ ํด๋ผ์ด์–ธํŠธ IP๋ฅผ ๋‚ด๋ถ€ ์„œ๋ฒ„์— ์ „๋‹ฌํ•œ๋‹ค.
    • ๊ธฐ๋ณธ์ ์œผ๋กœ Nginx๋Š” ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ๋กœ ์ž‘๋™ํ•  ๋•Œ, ์š”์ฒญ์ด ๋งˆ์น˜ Nginx ์„œ๋ฒ„์—์„œ ์˜จ ๊ฒƒ์ฒ˜๋Ÿผ ๋‚ด๋ถ€ ์„œ๋ฒ„์— ์ „๋‹ฌํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚ด๋ถ€ ์„œ๋ฒ„๋Š” ์›๋ž˜ ํด๋ผ์ด์–ธํŠธ์˜ IP๋ฅผ ์•Œ ์ˆ˜ ์—†๋‹ค.
    • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, Nginx๊ฐ€ ์›๋ž˜ ์š”์ฒญ์˜ ํด๋ผ์ด์–ธํŠธ IP๋ฅผ X-Forwarded-For ํ—ค๋”์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋‚ด๋ถ€ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋‚ด๋ถ€ ์„œ๋ฒ„๋Š” ์š”์ฒญ์˜ ์›๋ž˜ ์ถœ์ฒ˜ IP๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋กœ๊ทธ ๋ถ„์„์ด๋‚˜ ๋ณด์•ˆ ์„ค์ •์— ์œ ์šฉํ•˜๋‹ค.
  2. Host
    • ์›๋ž˜ ์š”์ฒญ์˜ ํ˜ธ์ŠคํŠธ ํ—ค๋”๋ฅผ ๋‚ด๋ถ€ ์„œ๋ฒ„์— ์ „๋‹ฌํ•œ๋‹ค.
    • ์ด ์„ค์ •์ด ์—†์œผ๋ฉด, ๋‚ด๋ถ€ ์„œ๋ฒ„๋Š” Nginx๊ฐ€ ์„ค์ •ํ•œ IP๋‚˜ ํ˜ธ์ŠคํŠธ ์ •๋ณด๋ฅผ ํ˜ธ์ŠคํŠธ๋กœ ์ธ์‹ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค.
    • ์ด ์„ค์ •์€ ํŠนํžˆ, ๊ฐ€์ƒ ํ˜ธ์ŠคํŠธ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•œ๋ฐ, ๋‚ด๋ถ€ ์„œ๋ฒ„๊ฐ€ ์—ฌ๋Ÿฌ ํ˜ธ์ŠคํŠธ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์‘๋‹ตํ•˜๋Š” ๊ฒฝ์šฐ, ์›๋ž˜ ์š”์ฒญ์˜ ํ˜ธ์ŠคํŠธ ์ •๋ณด๋ฅผ ์•Œ์•„์•ผ ์ •ํ™•ํ•œ ์‘๋‹ต์„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ

https://narup.tistory.com/238

๋ฐ˜์‘ํ˜•