설정(데이터베이스 URL, API 키, 포트, 기능 플래그)은 코드에 하드코딩하지 말고 코드 외부의 환경 변수에 두어야 합니다. 이렇게 하면 비밀값이 소스 관리에서 빠지고, 동일한 코드가 다른 설정으로 개발/스테이징/프로덕션에서 실행될 수 있습니다.
원칙: 환경에서 설정 가져오기
js
dbUrl = ;
dbUrl = process..;
port = process.. || ;
이는 twelve-factor app 원칙을 따릅니다. 설정과 코드의 엄격한 분리로, 새 환경에 배포한다는 것은 코드가 아니라 환경 변수를 바꾸는 것을 의미합니다.
# .env — local values, GITIGNORED (never committed)
DATABASE_URL=postgres://localhost/myapp_dev
JWT_SECRET=dev-secret
PORT=3000
// load .env into process.env (older: dotenv; newer Node: --env-file flag)
import "dotenv/config"; // or: node --env-file=.env app.js
const secret = process.env.JWT_SECRET;
.env 파일은 로컬 설정을 담으며 반드시 gitignore해야 합니다. 무엇이 필요한지 문서화하기 위해 (키만 있고 실제 값은 없는) .env.example을 커밋하세요.
import { z } from "zod";
const env = z.object({
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(16),
PORT: z.coerce.number().default(3000),
}).parse(process.env); // ❗ fail FAST at startup if config is missing/invalid
부팅 시 환경 변수를 검증하면(zod/envalid 사용) 누락되거나 잘못된 비밀값이 명확한 메시지와 함께 즉시 충돌합니다. 요청 깊숙한 곳에서 혼란스러운 런타임 실패가 나는 것보다 훨씬 낫습니다.
Dev: .env file (gitignored)
Production: injected by the platform/orchestrator —
cloud secret managers (AWS Secrets Manager, GCP Secret Manager, Vault),
container/orchestrator env vars, CI/CD secrets.
Never put production secrets in .env files committed or shipped with the app.
// config.js — one validated config module the app imports (don't sprinkle process.env everywhere)
export const config = { dbUrl: env.DATABASE_URL, port: env.PORT };
적절한 설정 및 비밀값 관리는 보안이자 운영의 필수 사항입니다.
비밀값을 하드코딩하면 버전 관리로 유출되고(심각하고 흔한 침해), 설정을 코드에 섞으면 환경 간 배포가 고통스러워집니다.
표준 접근법 — 환경 변수, 로컬 개발용 gitignore된 .env, 문서화를 위한 .env.example, 시작 시 검증, 프로덕션의 플랫폼 비밀 관리자 — 은 비밀값을 안전하게 지키고, 앱을 환경 간에 이식 가능하게 하며, 잘못된 설정을 일찍 드러냅니다.
이는 Node 앱을 책임감 있게 운영하는 기초입니다.