콘텐츠로 이동

Node.js 런타임 운영 기준 (Production)

운영 서버(Production Server) 에서 Node.js 애플리케이션을 실행할 때
런타임 옵션, 환경 변수, 프로세스 동작 방식에 대한 운영 기준을 정의함.

코드 작성법이나 프레임워크 설정이 아닌, Node.js 프로세스를 어떤 상태로 실행해야 안정적인가에 집중함.


1. Node.js 런타임의 책임 범위

운영 환경에서 Node.js 런타임의 책임은 명확함.

  • HTTP 요청 처리 (Nginx 이후)
  • 비즈니스 로직 실행
  • 내부 서비스 호출
  • 상태 없는(stateless) 프로세스 유지

Node.js 런타임이 직접 책임지지 않는 영역:

  • TLS / HTTPS
  • 인증 / 접근 제어
  • Rate / Connection Limit
  • 정적 파일 제공

위 영역은 모두 Nginx의 책임


2. 런타임 옵션을 명시적으로 관리해야 하는 이유

Node.js는 기본 옵션만으로도 실행되지만,
운영 환경에서는 명시적 설정이 없을 경우 장애가 늦게 발견되거나, 원인 추적이 어려워짐.

대표적인 문제:

  • 메모리 누수 발생 시 OOM Kill
  • 예외 미처리로 인한 프로세스 종료
  • 환경별 동작 차이 발생
  • 로그만 보고는 재현 불가

따라서 운영 환경에서는:

Node.js 실행 옵션과 환경 변수를 “암묵적”으로 두지 않음


3. 필수 런타임 환경 변수

3.1 NODE_ENV

운영 환경에서는 반드시 production 으로 고정함.

NODE_ENV=production

이유

  • 라이브러리 동작 분기
  • 디버그 로깅 비활성화
  • 성능 최적화 코드 활성화

잘못된 사례

  • NODE_ENV 미설정
  • development 상태로 운영

3.2 PORT 환경 변수

Node.js 애플리케이션은 포트를 코드에 하드코딩하지 않음.

PORT=3000

운영 기준

  • Node.js는 내부 포트만 사용
  • 외부 포트는 Nginx에서만 관리
  • 방화벽에서 Node 포트는 열지 않음

4. 메모리 관련 런타임 옵션

Node.js는 V8 엔진 기반이며,
기본 메모리 제한은 서버 스펙 대비 매우 작을 수 있음.

4.1 max_old_space_size

--max-old-space-size=1024

(단위: MB)

적용 기준 예시

서버 메모리 권장 값
2GB 512
4GB 1024
8GB 2048

이 옵션을 설정하지 않으면

  • 메모리 여유가 있어도 OOM 발생
  • 갑작스러운 프로세스 종료
  • 원인 로그 없이 서비스 중단

설정 방법

  1. node 직접 실행 시
node --max-old-space-size=1024 app.js
  • 테스트 또는 임시 실행 용도로 사용함

  • PM2 CLI 실행 시

pm2 start app.js --node-args="--max-old-space-size=1024"
  • 단순 실행은 가능하나 재기동 시 옵션 유실 위험 있음

  • PM2 ecosystem.config.cjs (운영 권장)

module.exports = {
  apps: [
    {
      name: "api-server",
      script: "app.js",
      node_args: "--max-old-space-size=1024",
      exec_mode: "fork",
      instances: 1
    }
  ]
};
pm2 start ecosystem.config.cjs
pm2 reload ecosystem.config.cjs
  • 운영 환경에서는 반드시 설정 파일 기반으로 관리함

  • 환경변수 방식 (NODE_OPTIONS)

export NODE_OPTIONS="--max-old-space-size=1024"
node app.js
  • 모든 Node 프로세스에 전역 적용됨
  • 빌드 스크립트·배치 작업에도 영향 주므로 운영 서버에서는 주의함

  • Docker 환경

CMD ["node", "--max-old-space-size=1024", "app.js"]

또는

ENV NODE_OPTIONS="--max-old-space-size=1024"

운영 기준

  • 서버 전체 메모리의 50~60% 이내로 설정함
  • PM2 cluster 모드 사용 시
    총 메모리 ÷ 인스턴스 수 기준으로 인스턴스별 값 산정함
  • 설정 적용 여부는 다음 명령으로 확인함
pm2 describe <app_name>

또는

ps aux | grep node

4.2 미설정 시 기본 동작

  • --max-old-space-size를 지정하지 않으면
    Node.js는 V8 엔진의 기본 힙 제한을 그대로 사용함
  • 이 값은 서버 전체 메모리를 기준으로 자동 계산되나
    상한이 낮게 고정되는 구조

일반적인 디폴트 (64bit Linux 기준)

Node.js 버전 Old Space 한계
Node 12 이하 약 1.4 GB
Node 14~16 약 2.0 GB
Node 18+ 약 2.0 ~ 4.0 GB
  • 서버 메모리가 8GB, 16GB여도
    Old Space는 위 범위를 초과하지 않음

이로 인해 발생하는 문제

  • OS 메모리는 충분하나
  • V8 Old Space 한계 도달
  • GC 과다 → JavaScript heap out of memory
  • 또는 SIGKILL로 즉시 프로세스 종료됨

디폴트 값 확인 방법

node -e "console.log(require('v8').getHeapStatistics().heap_size_limit / 1024 / 1024)"

운영 기준

  • 서버 전체 메모리의 50~60% 이내로 설정함
  • PM2 cluster 모드 사용 시
    총 메모리 ÷ 인스턴스 수 기준으로 인스턴스별 값 산정함
  • 설정 적용 여부는 다음 명령으로 확인함
pm2 describe <app_name>

또는

ps aux | grep node

5. 예외(Exception) 처리 기준

5.1 uncaughtException / unhandledRejection

운영 환경에서 다음 패턴은 허용하지 않음.

  • 예외를 삼켜서 프로세스를 계속 살려두는 구조
  • 로그만 남기고 무시하는 방식

운영 원칙

치명적인 예외 발생 시 프로세스는 종료되어야 함
재시작은 PM2가 담당함

이유:

  • 깨진 상태로 살아있는 프로세스가 더 위험함
  • 상태 불일치로 데이터 손상 가능성

6. 로그 출력 기준

6.1 stdout / stderr 사용

운영 환경에서는:

  • 파일 직접 기록 ❌
  • stdout / stderr 출력 ⭕
  • 로그 수집은 PM2 / systemd / 외부 로거가 담당

이유

  • 로그 로테이션 중앙화
  • 컨테이너/프로세스 매니저 호환성
  • 장애 분석 일관성 확보

7. 런타임 실행 형태 (요약)

운영 환경에서 Node.js 실행은 다음 형태를 전제로 함.

Nginx
  ↓
PM2
  ↓
Node.js (production, 명시적 옵션)

직접 실행 형태는 허용하지 않음.

node app.js   # ❌

8. 이 문서에서 의도적으로 다루지 않는 것

다음 항목은 이 문서 범위를 벗어남.

  • PM2 설정 상세
  • 클러스터 모드 구성
  • Nginx 연동
  • CI/CD 파이프라인

각 항목은 별도 문서에서 정의함.


9. 정리

  • Node.js 런타임은 명시적으로 설정되어야 함
  • 암묵적 기본값에 의존하지 않음
  • 실패는 빠르게, 복구는 자동으로
  • “살아있는 장애”보다 “죽고 다시 뜨는 프로세스”가 안전함

Node.js 런타임 운영의 기준선임.
이후 모든 실행 방식은 이 기준을 전제로 함.