๐Ÿ”„ ์„œ๋ฒ„ ์žฌ๋ถ€ํŒ… ์‹œ NGINX๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๋ฉฐ ๋ฐœ์ƒํ•˜๋Š” upstream ์—๋Ÿฌ ํ•ด๊ฒฐํ•˜๊ธฐ (Docker + Blue/Green ๋ฐฐํฌ ํ™˜๊ฒฝ)

์ด๊ฒฝํ—Œยท2025๋…„ 4์›” 10์ผ

๐Ÿ’ก ๋ฐฐ๊ฒฝ

Docker๋ฅผ ํ™œ์šฉํ•ด ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Blue/Green ๋ฐฉ์‹์œผ๋กœ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
eventor-front-blue-1, eventor-front-blue-2 ์™€ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ๋“ค์„ ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด NGINX์˜ upstream ์„ค์ •์„ ํ™œ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

upstream frontend {
  server eventor-front-blue-1:8001;
  server eventor-front-blue-2:8002;
}

โš ๏ธ ๋ฌธ์ œ ์ƒํ™ฉ

์„œ๋ฒ„๊ฐ€ ์žฌ๋ถ€ํŒ…๋˜๋ฉด, NGINX ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๊ณ , ๊ทธ ๋’ค์— ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆ๋“ค์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
์ด๋•Œ, NGINX๊ฐ€ ๋จผ์ € ์˜ฌ๋ผ์˜ค๋ฉด์„œ upstream ์„ค์ •์— ๋ช…์‹œ๋œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค:

[emerg] host not found in upstream "eventor-front-blue-1:8001"

๐Ÿšจ Docker ๋„คํŠธ์›Œํฌ ๋‚ด์—์„œ ์ •์˜๋œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„์ง ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.


โœ… ํ•ด๊ฒฐ ์ „๋žต

  1. ๊ธฐ๋ณธ nginx.conf๋Š” dummy upstream์œผ๋กœ ์„ค์ •ํ•˜์—ฌ NGINX๊ฐ€ ์ •์ƒ ๊ธฐ๋™๋˜๋„๋ก ์„ค์ •
  2. ํ”„๋ก ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ธฐ๋™๋œ ํ›„ ์‹ค์ œ nginx.conf๋กœ ๊ต์ฒด ๋ฐ nginx -s reload ์ˆ˜ํ–‰

๐Ÿ“ nginx.base.conf (nginx-start.sh์—์„œ ๋ณต์‚ฌํ•  ๊ธฐ๋ณธ ์„ค์ •)

upstream frontend {
  server 127.0.0.1:65535;
}

65535 ํฌํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์—ด๋ ค์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ ์š”์ฒญ์€ ์‹คํŒจํ•˜์ง€๋งŒ NGINX๋Š” ์ •์ƒ ๊ธฐ๋™๋ฉ๋‹ˆ๋‹ค.


๐Ÿš€ nginx-start.sh (๊ธฐ๋ณธ conf ๋ณต์‚ฌ)

#!/bin/sh

DEFAULT_CONF="/nginx/nginx.base.conf"
TARGET_CONF="/nginx/nginx.conf"

cp "$DEFAULT_CONF" "$TARGET_CONF"

์ด ์Šคํฌ๋ฆฝํŠธ๋Š” nginx ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰๋  ๋•Œ /nginx/nginx.conf๋ฅผ ์•ˆ์ „ํ•œ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ์„ธํŒ…ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“ฆ docker-compose.yml

services:
  nginx:
    container_name: nginx
    image: nginx:1.27.4
    restart: always
    command: ["/bin/sh", "/nginx-start.sh"]
    volumes:
      - ./nginx:/nginx
      - ./nginx-start.sh:/nginx-start.sh
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      ...

๐Ÿงพ default ์„ค์ •: 502 ์ปค์Šคํ…€ ํŽ˜์ด์ง€ ์ฒ˜๋ฆฌ

location / {
    proxy_intercept_errors on;
    error_page 413 /errors/413.html;
    error_page 502 /errors/502.html;

    location = /errors/ {
        root /usr/share/nginx/html/;
        internal;
    }

    proxy_pass http://frontend;
    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-Proto $scheme;
}

โœ… ํ”„๋ก ํŠธ๊ฐ€ ์•„์ง ๊ธฐ๋™๋˜์ง€ ์•Š์•˜์„ ๋•Œ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์ปค์Šคํ…€ 502 ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.


๐ŸŸข ์ดํ›„ ํ”„๋ก ํŠธ ์•ฑ ์‹คํ–‰ ์‹œ ์Šคํฌ๋ฆฝํŠธ (๋ฒ„์ „์— ๋งž๋Š” ์„ค์ • ์ ์šฉ)

#!/bin/bash

ACTIVE_VERSION=$(cat ./version.txt)

# nginx.conf ๊ต์ฒด ๋ฐ ๋ฆฌ๋กœ๋“œ
cp nginx/nginx.$ACTIVE_VERSION.conf ../nginx/nginx.conf
cd .. && docker-compose exec nginx nginx -s reload

nginx.blue.conf, nginx.green.conf ๋“ฑ ์‹ค์ œ upstream ์„ค์ •์„ ๋ฐ˜์˜ํ•œ ํŒŒ์ผ๋กœ ๊ต์ฒดํ•œ ๋’ค NGINX๋ฅผ reload ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ”ต ์˜ˆ: nginx.blue.conf

upstream frontend {
  server eventor-front-blue-1:8001;
  server eventor-front-blue-2:8002;
}

๐ŸŽ‰ ๋งˆ๋ฌด๋ฆฌ

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋ฉด ์„œ๋ฒ„ ์žฌ๋ถ€ํŒ… ์‹œ NGINX ๊ธฐ๋™ ์˜ค๋ฅ˜ ์—†์ด ์•ˆ์ „ํ•˜๊ฒŒ ์‹œ์ž‘๋˜๋ฉฐ,
ํ”„๋ก ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์˜ฌ๋ผ์˜จ ์ดํ›„์— ์ ์ ˆํ•œ ์„ค์ •์œผ๋กœ nginx๋ฅผ reloadํ•จ์œผ๋กœ์จ ์™„์ „ํžˆ ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ ์ฐธ๊ณ  ์š”์•ฝ

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œNGINX๊ฐ€ ๋จผ์ € ๊ธฐ๋™๋˜๋ฉฐ upstream ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ฐพ์ง€ ๋ชปํ•ด ์—๋Ÿฌ
ํ•ต์‹ฌ ํ•ด๊ฒฐ ์ „๋žต์ดˆ๊ธฐ dummy upstream ์„ค์ • โ†’ ์•ฑ ์‹คํ–‰ ํ›„ ์‹ค์ œ ์„ค์ • ์ ์šฉ + reload
์žฅ์ ์„œ๋ฒ„ ์žฌ๋ถ€ํŒ… ์‹œ์—๋„ NGINX ์˜ค๋ฅ˜ ์—†์ด ์ž‘๋™, ์œ ์—ฐํ•œ ๋ฐฐํฌ ๊ฐ€๋Šฅ

0๊ฐœ์˜ ๋Œ“๊ธ€