본문 바로가기
C.W.K.
Stream
Lesson 07 of 09 · published

환경 변수의 서버·클라이언트 경계

~18 min · env, NEXT_PUBLIC_, secrets

Level 0호기심
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

접두사가 공개 범위를 결정해

이름보이는 곳
접두사 없음서버에서 실행 시점에 읽으며 브라우저로 보내지 않아.
NEXT_PUBLIC_빌드할 때 클라이언트 번들에 값이 박혀 DevTools에서도 보여.

NEXT_PUBLIC_은 “브라우저에서도 쓸 수 있는 비밀”이 아니라 완전히 공개해도 되는 설정이라는 뜻이야. 키 이름에 secret이나 token이 들어간다면 접두사를 붙이기 전에 설계부터 다시 봐.

클라이언트 값은 컨테이너 실행 때 바뀌지 않아

같은 Docker 이미지를 staging과 production에 배포해도 이미 next build 때 박힌 공개 변수는 같아. 실행 중인 컨테이너에 다른 값을 넣어도 번들은 변하지 않아. 환경별로 다시 빌드하거나 서버가 실행 시점에 값을 내려 주는 별도 구성이 필요해.

여러 파일이 있으면 먼저 찾은 값이 이겨

  1. 이미 설정된 process.env
  2. .env.production.local 또는 .env.development.local
  3. .env.local, 단 test에서는 건너뜀
  4. .env.production 또는 .env.development
  5. .env

환경 변수 목록을 공개 가능·서버 비밀·빌드 선택으로 분류하고 소유자와 회전 절차를 적어. CI에서는 필요한 키의 존재만 검증하고 값을 출력하지 마. Docker를 여러 환경에 재사용한다면 공개 설정을 빌드할지 서버 endpoint로 내려 줄지 배포 계약으로 정해. 공개 변수와 비밀 변수의 이름이 비슷할수록 리뷰에서 놓치기 쉬워. 클라이언트 번들 검색과 배포 환경 점검을 자동화하고, 비밀이 바뀌었을 때 재빌드와 재시작 중 무엇이 필요한지도 변수마다 기록해.

접두사가 없다고 비밀이 자동으로 안전해지는 건 아니야. 서버 값을 클라이언트 prop이나 오류 메시지에 넣으면 그대로 새어 나가. 반대로 공개 API base URL은 숨길 가치가 없어. 이름보다 실제 데이터 흐름을 따라 어느 응답과 번들에 들어가는지 확인해. 공개 변수와 서버 비밀을 넣은 production build를 만든 뒤 정적 chunk 검색과 실행 중 process.env 변경을 비교해. 같은 이미지를 두 환경에 올려 어떤 값이 그대로인지 확인하고, 오류 응답과 client prop 어디에도 비밀이 포함되지 않는지 자동 검사해.

Code

.env.local·bash
# 서버 전용 — 절대 노출 안 함
DATABASE_URL=postgresql://localhost:5432/myapp
AUTH_SECRET=change-me
STRIPE_SECRET_KEY=sk_test_xxx

# 클라이언트에 공개 가능(빌드 시 인라인)
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_STRIPE_KEY=pk_test_xxx
서버와 클라이언트의 접근 범위·tsx
// 서버 컴포넌트 — 다 봄
export default async function Page() {
  const dbUrl = process.env.DATABASE_URL;        // ✅
  const appUrl = process.env.NEXT_PUBLIC_APP_URL; // ✅
}

// 클라이언트 컴포넌트 — NEXT_PUBLIC_*만
'use client';
export function Stripe() {
  const key = process.env.NEXT_PUBLIC_STRIPE_KEY; // ✅
  // process.env.DATABASE_URL — 여기서는 정의되지 않아
}

External links

Exercise

환경 변수를 모두 공개·서버 비밀·빌드 선택으로 분류해. 잘못 공개한 값을 서버로 옮기고 클라이언트 bundle과 오류 응답에 비밀이 없는지 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.