์ด์ ๊ธ์์ ๋ฐฑ์๋ ๋ก์ปฌ ์๋ฒ์์๋ ์คํ์ด ์ ๋๋ ๊ฒ์ ํ์ธํ์๋ค. ํ์ง๋ง 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 ์๋ฒ(๋ก์ปฌ/์จํ๋ ๋ฏธ์ค ํ๊ฒฝ)
- ๋ฐฑ์๋ ์๋ฒ ๊ณ ์ IP ์ง์ ์ ๊ทผ
- DNS, Service, Proxy, Pod ๊ฐ๋ ์์
- Next.js API Routes → ํด๋น IP๋ก ๋ฐ๋ก TCP ์ฐ๊ฒฐ
- env๊ฐ ์ผ๋ถ ๊นจ์ ธ๋ IP ํ๋์ฝ๋ฉ์ด ์ด์ ์์ด์ ๋ฌธ์ ๋ฏธ๋ฐ์
โก ๊ตฌ์กฐ์ ์ผ๋ก “๊นจ์ง ์ฌ์ง๊ฐ ์๋ ๋จ์ผ ์๋ฒ ํต์ ”
๐น Kubernetes ์ธํ๋ผ ํ๊ฒฝ
- ๋ฐฑ์๋ ์ ๊ทผ์ 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์ ๋ณ์๋ฅผ ๋ฃ์ผ๋ฉด:
- Next.js๊ฐ ์ด๋ฅผ “์ ์ ํ๊ฒฝ ๋ณ์”๋ก ์ธ์
- ์๋ฒ·ํด๋ผ์ด์ธํธ ๋ฒ๋ค ๋ชจ๋์ embed
- ๋น๋๋ API Routes์์๋ process.env.๋ณ์๋ช ์ผ๋ก ์์ ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅ
๊ฒฐ๋ก ์ ์ผ๋ก, ์ด๋ฒ ํธ๋ฌ๋ธ ์ํ ์ Next.js์ ๋น๋ ๊ตฌ์กฐ + Kubernetes ๋คํธ์ํฌ ๋ชจ๋ธ์ด ๋์์ ๋ง๋ฌผ๋ ค ๋ฐ์ํ ๊ตฌ์กฐ์ ์ฅ์ ์๋ค.
๋ฐ๋ผ์ api routes์์ .env ์ฌ์ฉ์๋ ์ฃผ์๊ฐ ํ์ํจ์ ํ์ธ ํ ์ ์์๋ค.
๋๊ธ