๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • What would life be If we had no courage to attemp anything?
๐“๐จ๐๐š๐ฒ ๐ˆ ๐‹๐ž๐š๐ซ๐ง

์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ ๊ตฌํ˜„ ํ•˜๊ธฐ : 3. ์ธํ”„๋ผ ํ™˜๊ฒฝ์—์„œ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ (with. trouble shooting)

by DevIseo 2025. 12. 7.

์ด์ „ ๊ธ€์—์„œ ๋ฐฑ์—”๋“œ ๋กœ์ปฌ ์„œ๋ฒ„์—์„œ๋Š” ์‹คํ–‰์ด ์ž˜ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์˜€๋‹ค. ํ•˜์ง€๋งŒ k8s ์ธํ”„๋ผ ํ™˜๊ฒฝ์— ์˜ฌ๋ ธ์„ ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Next.js API Routes + SSE ํ”„๋ก์‹œ ๊ตฌ์„ฑ ์‹œ K8s ํ™˜๊ฒฝ์—์„œ localhost๋กœ ์—ฐ๊ฒฐ๋˜๋˜ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ž‘์„ฑํ•ด๋ณด๋ ค ํ•œ๋‹ค.

 

Next.js API Routes๋ฅผ ์‚ฌ์šฉํ•ด SSE(Server-Sent Events) ํ”„๋ก์‹œ๋ฅผ ๊ตฌํ˜„ํ•˜๋˜ ์ค‘, ๋กœ์ปฌ(Linux ์„œ๋ฒ„)์—์„œ๋Š” ์ •์ƒ ๋™์ž‘ํ•˜๋˜ ์ฝ”๋“œ๊ฐ€ Kubernetes(K8s) ์ธํ”„๋ผ ํ™˜๊ฒฝ์— ๋ฐฐํฌ๋˜์ž localhost๋กœ ์ž˜๋ชป ์—ฐ๊ฒฐ๋˜๋ฉฐ ์‹คํŒจํ•˜๋Š” ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

 

์ด ๊ธ€์—์„œ๋Š” ๋‹จ์ˆœํ•œ “env ์„ค์ • ์‹ค์ˆ˜”๋ฅผ ๋„˜์–ด,IP ์ง์ ‘ ์ ‘๊ทผ ↔ Service Name ๊ธฐ๋ฐ˜ ์ ‘๊ทผ์˜ ๊ตฌ์กฐ์  ์ฐจ์ด,
๊ทธ๋ฆฌ๊ณ  Next.js์˜ ๋นŒ๋“œ·๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ์–ด๋–ป๊ฒŒ ์žฅ์• ๋กœ ์ด์–ด์กŒ๋Š”์ง€๋ฅผ ์ •๋ฆฌํ•œ๋‹ค.

 

1. ๋ฌธ์ œ ํ˜„์ƒ

K8s ํ™˜๊ฒฝ์—์„œ SSE ํ”„๋ก์‹œ API๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

 

์œ ํ˜• ๋กœ๊ทธ ๊ฒฐ๊ณผ
์—ฐ๊ฒฐ ๊ฑฐ๋ถ€ ECONNREFUSED ::1:80 SSE ์—ฐ๊ฒฐ ์‹คํŒจ
์ž˜๋ชป๋œ URL _currentUrl: 'http://localhost/test/sse/event' ์‹ค์ œ ๋ฐฑ์—”๋“œ๊ฐ€ ์•„๋‹Œ localhost ์—ฐ๊ฒฐ

์ฆ‰, ์˜๋„ํ•œ ๋ฐฑ์—”๋“œ๋Š” http://our-service-backend์˜€์œผ๋‚˜, ์‹ค์ œ ์—ฐ๊ฒฐ์€ http://localhost๋กœ ์‹œ๋„๋˜๊ณ  ์žˆ์—ˆ๋‹ค.

 

2. ์ดˆ๋ฐ˜ ์ถ”์ •: “SSE๋‚˜ HTTP ํด๋ผ์ด์–ธํŠธ ๋ฌธ์ œ์ธ๊ฐ€?”

์ดˆ๊ธฐ์—  APM ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์ „์—๋Š” ๋‹ค์Œ์„ ์˜์‹ฌํ–ˆ๋‹ค.

  • HTTP ํด๋ผ์ด์–ธํŠธ์˜ SSE ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฏธ์ง€์›
  • keep-alive, buffer, gzip ์„ค์ • ๋ฌธ์ œ

๊ทธ๋Ÿฌ๋‚˜ ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•œ ๊ฒฐ๊ณผ ๋ฌธ์ œ๋Š” ๋„คํŠธ์›Œํฌ ๊ณ„์ธต์ด๋‚˜ SSE๊ฐ€ ์•„๋‹ˆ๋ผ, URL ์ž์ฒด๊ฐ€ ์ž˜๋ชป ๋งŒ๋“ค์–ด์ง€๊ณ  ์žˆ์Œ์ด ๋“œ๋Ÿฌ๋‚ฌ๋‹ค.

_currentUrl: 'http://localhost/test/sse/event'

โžก ๋ฐฑ์—”๋“œ ์ฃผ์†Œ๋ฅผ ๋ชป ์ฐพ์€ ์ƒํƒœ์—์„œ HTTP ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ธ localhost:80์œผ๋กœ ํด๋ฐฑํ•œ ์ƒํ™ฉ์ด์—ˆ๋‹ค.

 

3. ๊ฒฐ์ •์ ์ธ ์ฐจ์ด: Linux ์„œ๋ฒ„ vs Kubernetes ์ธํ”„๋ผ

์ด๋ฒˆ ์ด์Šˆ์˜ ํ•ต์‹ฌ์€ ๋‹จ์ˆœํ•œ env ๋ˆ„๋ฝ์ด ์•„๋‹ˆ๋ผ, “๋ฐฑ์—”๋“œ ์—”๋“œํฌ์ธํŠธ๋ฅผ IP๋กœ ์ง์ ‘ ์ฐ”๋ €๋А๋ƒ, Service Name์œผ๋กœ ์ ‘๊ทผํ–ˆ๋А๋ƒ”์˜ ์ฐจ์ด์˜€๋‹ค.

 

๐Ÿ”น Linux ์„œ๋ฒ„(๋กœ์ปฌ/์˜จํ”„๋ ˆ๋ฏธ์Šค ํ™˜๊ฒฝ)

http://43.xxx.xxx.xxx:9999
  • ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ๊ณ ์ • IP ์ง์ ‘ ์ ‘๊ทผ
  • DNS, Service, Proxy, Pod ๊ฐœ๋… ์—†์Œ
  • Next.js API Routes → ํ•ด๋‹น IP๋กœ ๋ฐ”๋กœ TCP ์—ฐ๊ฒฐ
  • env๊ฐ€ ์ผ๋ถ€ ๊นจ์ ธ๋„ IP ํ•˜๋“œ์ฝ”๋”ฉ์ด ์‚ด์•„ ์žˆ์–ด์„œ ๋ฌธ์ œ ๋ฏธ๋ฐœ์ƒ

โžก ๊ตฌ์กฐ์ ์œผ๋กœ “๊นจ์งˆ ์—ฌ์ง€๊ฐ€ ์—†๋Š” ๋‹จ์ผ ์„œ๋ฒ„ ํ†ต์‹ ”

 

๐Ÿ”น Kubernetes ์ธํ”„๋ผ ํ™˜๊ฒฝ

 
http://our-service-backend
  • ๋ฐฑ์—”๋“œ ์ ‘๊ทผ์€ K8s Service Name ๊ธฐ๋ฐ˜
  • ์‹ค์ œ ๋ฌผ๋ฆฌ IP๋Š” Pod ์žฌ๊ธฐ๋™, ์Šค์ผ€์ผ๋ง ์‹œ๋งˆ๋‹ค ๋ณ€๊ฒฝ
  • ๋ฐ˜๋“œ์‹œ ๋‹ค์Œ์ด ์ „์ œ๋จ:
    •  ์ •์ƒ์ ์ธ DNS ํ•ด์„
    •  ์˜ฌ๋ฐ”๋ฅธ Service Name
    •  env๋ฅผ ํ†ตํ•œ ์ •ํ™•ํ•œ baseURL ์ „๋‹ฌ

ํ•˜์ง€๋งŒ ์ด ์ค‘ env ์ „๋‹ฌ์ด ๊นจ์ง€๋ฉด์„œ baseURL์ด undefined๊ฐ€ ๋˜์—ˆ๊ณ , ๊ทธ ๊ฒฐ๊ณผ Axios๊ฐ€ ์ƒ๋Œ€๊ฒฝ๋กœ๋กœ ์š”์ฒญ์„ ํ•ด์„ํ•˜๋ฉด์„œ localhost๋กœ ํด๋ฐฑํ–ˆ๋‹ค.

โžก K8s ํ™˜๊ฒฝ์—์„œ๋Š” env ๋ˆ„๋ฝ์ด ๊ณง “์ž˜๋ชป๋œ ๋„คํŠธ์›Œํฌ ๋ผ์šฐํŒ…”์œผ๋กœ ์ง๊ฒฐ๋œ๋‹ค.

 

 

4. ๊ทผ๋ณธ ์›์ธ: Next.js API Routes์—์„œ env๊ฐ€ ์œ ์‹ค๋จ

ํ”„๋ก์‹œ API Routes ๋‚ด๋ถ€์—์„œ ๋‹ค์Œ์ฒ˜๋Ÿผ ์ž‘์„ฑ๋˜์–ด ์žˆ์—ˆ๋‹ค.

const baseUrl = process.env.CLOUD_BACKEND_URL;

K8s Deployment YAML์—์„œ๋Š” ๋ถ„๋ช… CLOUD_BACKEND_URL์ด ์ฃผ์ž…๋˜์–ด ์žˆ์—ˆ์ง€๋งŒ, Next.js ์„œ๋ฒ„(Node ํ”„๋กœ์„ธ์Šค)์—์„œ๋Š” ์ด ๊ฐ’์ด undefined๋กœ ํ‰๊ฐ€๋˜๊ณ  ์žˆ์—ˆ๋‹ค.

โžก ์ด๋กœ ์ธํ•ด Axios๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์š”์ฒญ์„ ๋งŒ๋“ค์–ด๋ฒ„๋ ธ๋‹ค.

http://localhost/test/sse/event

 

5. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• - next.config.js๋ฅผ ํ†ตํ•œ env ๋ช…์‹œ์  ์ „๋‹ฌ

Next.js๋Š” ์ผ๋ฐ˜ Node.js ์„œ๋ฒ„์™€ ๋‹ฌ๋ฆฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๋นŒ๋“œ ํƒ€์ž„ ๊ธฐ์ค€์œผ๋กœ ๋ฒˆ๋“ค์— ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ๋‹ค.
๋”ฐ๋ผ์„œ K8s์—์„œ ์ฃผ์ž…๋œ env๋„ next.config.js๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ ๋ช…์‹œ์ ์œผ๋กœ ์ „๋‹ฌํ•ด์•ผ ์•ˆ์ •์ ์ด๋‹ค.

// next.config.js
module.exports = {
  env: {
    BACKEND_URL: process.env.BACKEND_URL,
  },
};

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•œ ์ดํ›„๋ถ€ํ„ฐ API Routes์—์„œ๋„ ๋‹ค์Œ์ด ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ–ˆ๋‹ค.

 

 

Next.js API Routes์—์„œ env๊ฐ€ ๋ฏผ๊ฐํ•œ ์ด์œ 

Next.js๋Š” ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค๊ณผ ์„œ๋ฒ„(Runtime) ์˜์—ญ์ด ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋œ ๋นŒ๋“œ·์‹คํ–‰ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์—, ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์–ด๋””์—์„œ ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋Š”์ง€๊ฐ€ ์ผ๋ฐ˜์ ์ธ Node.js์™€ ๋‹ค๋ฅด๋‹ค. Next.js์—๋Š” ๋‘ ๊ฐœ์˜ ์‹คํ–‰ ์„ธ๊ณ„๊ฐ€ ์กด์žฌํ•œ๋‹ค.

1) ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค(๋ธŒ๋ผ์šฐ์ € ์‹คํ–‰)

  • .env๋Š” Node.js ์„œ๋ฒ„์— ์กด์žฌ
  • ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „๋‹ฌ๋˜๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” ๋นŒ๋“œ ํƒ€์ž„์— ์ •์ ์œผ๋กœ ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๊ฐ’๋งŒ ๊ฐ€๋Šฅ
  • ๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ์—์„œ env๋ฅผ ์“ฐ๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ next.config.js.env์— ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค

2) ์„œ๋ฒ„ ๋ฒˆ๋“ค(API Routes / SSR / Route Handlers)

  • Node.js ๊ธฐ๋ฐ˜์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์›์น™์ ์œผ๋กœ๋Š” .env ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ํ•˜์ง€๋งŒ Next.js๊ฐ€ ์ด ์ฝ”๋“œ๋ฅผ ๋ฒˆ๋“ค๋ง ๋ฐ ์ตœ์ ํ™”ํ•œ๋‹ค๋Š” ํŠน์ˆ˜์„ฑ์ด ์กด์žฌํ•œ๋‹ค

์ฆ‰, API Routes๊ฐ€ “๊ทธ๋ƒฅ Node.js”๊ฐ€ ์•„๋‹ˆ๋ผ Next.js๊ฐ€ ๊ตฌ์„ฑํ•œ ์„œ๋ฒ„ ๋Ÿฐํƒ€์ž„์˜ ์ผ๋ถ€๋ผ๋Š” ์  ๋•Œ๋ฌธ์— ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ „๋‹ฌ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

API Routes๋„ Next.js์— ์˜ํ•ด ๋ฒˆ๋“ค๋ง๋œ๋‹ค

Next.js์˜ pages/api/*.ts๋Š” Node.js์—์„œ ์‹คํ–‰๋˜์ง€๋งŒ, Next.js ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ์„ ์ง€๋‚˜๊ฐ„๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ:

  • Next.js๋Š” "์‚ฌ์šฉ๋˜๋Š” env"๋ผ๊ณ  ํŒ๋‹จํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฒˆ๋“ค์—์„œ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋˜๋Š” output: "standalone" ๊ฐ™์€ ๋ชจ๋“œ์—์„œ๋Š” ํ•„์š”ํ•œ env๋งŒ ํฌํ•จ์‹œ์ผœ ์‹คํ–‰ ํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค
  • ๋”ฐ๋ผ์„œ ์•ˆ์ •์ ์ธ ์ ‘๊ทผ์„ ์œ„ํ•ด Next.js๊ฐ€ env๋ฅผ ์ง์ ‘ ์ฃผ์ž…ํ•ด์•ผ ํ•œ๋‹ค

Next.js ๊ณต์‹ ๋ฌธ์„œ ๋ช…์‹œ:

API Routes๋Š” ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜์ง€๋งŒ Next.js์— ์˜ํ•ด ์ตœ์ ํ™”๋˜๋ฏ€๋กœ, ๋ชจ๋“  ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์ž๋™์œผ๋กœ ํฌํ•จ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

 

์™œ next.config.js์˜ env์— ๋„ฃ์œผ๋ฉด ํ•ด๊ฒฐ๋˜๋Š”๊ฐ€?

next.config.js๋Š” ๋นŒ๋“œ ํƒ€์ž„์— Node.js ํ™˜๊ฒฝ์—์„œ 100% ์‹คํ–‰๋˜๋Š” ์„ค์ • ํŒŒ์ผ์ด๋‹ค.

 

์—ฌ๊ธฐ์„œ env์— ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์œผ๋ฉด:

  1. Next.js๊ฐ€ ์ด๋ฅผ “์ •์  ํ™˜๊ฒฝ ๋ณ€์ˆ˜”๋กœ ์ธ์‹
  2. ์„œ๋ฒ„·ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค ๋ชจ๋‘์— embed
  3. ๋นŒ๋“œ๋œ API Routes์—์„œ๋„ process.env.๋ณ€์ˆ˜๋ช…์œผ๋กœ ์•ˆ์ •์ ์œผ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ

 

 

๊ฒฐ๋ก ์ ์œผ๋กœ, ์ด๋ฒˆ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…์€ Next.js์˜ ๋นŒ๋“œ ๊ตฌ์กฐ + Kubernetes ๋„คํŠธ์›Œํฌ ๋ชจ๋ธ์ด ๋™์‹œ์— ๋งž๋ฌผ๋ ค ๋ฐœ์ƒํ•œ ๊ตฌ์กฐ์  ์žฅ์• ์˜€๋‹ค.

๋”ฐ๋ผ์„œ api routes์—์„œ .env ์‚ฌ์šฉ์‹œ๋Š” ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•จ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋Œ“๊ธ€