2025-09-05 00:05

  • PM2는 단일 스레드로 동작하는 Node.js 애플리케이션의 한계를 극복하고, 서버 자원을 최대로 활용하기 위해 탄생한 필수 프로세스 관리자입니다.

  • 클러스터 모드를 통해 CPU 코어 수만큼 프로세스를 복제하여 성능을 극대화하고, 무중단 재시작 기능으로 서비스 안정성을 보장합니다.

  • ecosystem.config.js 설정 파일을 활용하면 여러 애플리케이션의 배포, 환경 변수 주입, 로그 관리 등을 체계적이고 선언적으로 관리할 수 있습니다.

PM2 완벽 정복 가이드 당신의 Nodejs 서버를 지켜드립니다

Node.js로 애플리케이션을 개발하고 처음 서버에 배포할 때, 많은 개발자가 node app.js 라는 명령어를 터미널에 입력하고 뿌듯함을 느낍니다. 하지만 이내 터미널 접속이 끊기면 서버가 멈추고, 알 수 없는 에러로 프로세스가 종료되면 서비스 전체가 마비되는 뼈아픈 경험을 하게 됩니다. 바로 이 지점에서 “왜 PM2가 필요한가?”에 대한 답이 시작됩니다.

PM2는 왜 만들어졌을까요? Node.js 서버의 약한 고리

Node.js는 뛰어난 비동기 I/O 처리 능력 덕분에 단일 스레드(Single Thread)만으로도 높은 성능을 발휘합니다. 하지만 이 구조는 치명적인 약점을 내포하고 있습니다.

  1. 단 한 번의 에러에도 무너지는 서버: 코드 어딘가에서 처리되지 않은 예외(Unhandled Exception)가 발생하면, Node.js 프로세스 전체가 그대로 종료됩니다. 이는 곧 서비스 중단을 의미합니다. 누군가 24시간 서버를 지켜보며 node app.js를 다시 실행해주지 않는 한, 서비스는 그대로 멈춰버립니다.

  2. CPU 코어 하나만 사용하는 비효율: 요즘 서버는 대부분 여러 개의 CPU 코어(Multi-core)를 가지고 있습니다. 하지만 기본적인 Node.js 프로세스는 단 하나의 코어만 사용합니다. 8코어, 16코어 CPU를 탑재한 서버라도 나머지 7개, 15개의 코어는 그저 놀고 있게 되는 셈이죠. 이는 막대한 자원 낭비입니다.

이러한 문제들을 해결하기 위해 똑똑한 프로세스 관리자(Process Manager)가 필요했고, 그 해결책으로 등장한 것이 바로 PM2(Process Manager 2)입니다. PM2를 한마디로 비유하자면, Node.js 애플리케이션이라는 직원들을 24시간 관리하며 절대 쓰러지지 않게 하고, 각자의 능력을 최대로 끌어내는 유능한 매니저라고 할 수 있습니다.


1장: PM2의 심장부, 구조와 작동 원리

PM2는 어떻게 우리 애플리케이션을 안정적으로 관리할 수 있을까요? 그 비밀은 독특한 아키텍처에 있습니다.

PM2 Daemon: 보이지 않는 수호신

우리가 터미널에서 pm2 start app.js 명령을 실행하면, 실제로 애플리케이션을 실행하는 것은 터미널 세션이 아닙니다. 이 명령어는 백그라운드에서 항상 실행되고 있는 PM2 Daemon 프로세스에게 “app.js 파일을 실행하고 관리해줘”라고 요청을 보내는 것과 같습니다.

이 데몬 프로세스가 PM2의 핵심입니다. 데몬은 우리가 관리하도록 등록한 모든 애플리케이션의 목록을 가지고 있으며, 각 애플리케이션의 상태(실행 중, 중지, 에러 등), CPU 및 메모리 사용량을 지속적으로 감시합니다. 만약 특정 애플리케이션이 에러로 인해 갑자기 종료되면, 데몬이 이를 즉시 감지하고 자동으로 재시작해줍니다. 우리가 터미널을 닫거나 로그아웃해도 이 데몬은 서버에서 계속 살아 숨 쉬며 우리의 애플리케이션을 지켜주는 수호신 역할을 합니다.

CLI: 데몬과 소통하는 마법 지팡이

pm2 start, pm2 list, pm2 stop과 같은 명령어들은 PM2 CLI(Command Line Interface)라고 부릅니다. 이 CLI는 우리가 PM2 데몬과 소통할 수 있도록 해주는 인터페이스, 즉 ‘마법 지팡이’입니다. CLI를 통해 데몬에게 명령을 내리면, 데몬은 그에 맞춰 애플리케이션을 실행하거나, 중지하거나, 상태를 보여주는 등의 작업을 수행하고 결과를 다시 우리에게 보여줍니다.

이러한 클라이언트-서버(CLI-Daemon) 구조 덕분에 우리는 터미널 세션에 구애받지 않고 안정적으로 애플리케이션을 운영할 수 있는 것입니다.


2장: PM2 첫걸음, 필수 사용법 마스터하기

PM2의 강력함을 경험하기 위해 알아야 할 기본적인 명령어는 몇 개 되지 않습니다. 이 명령어들만 익혀도 기본적인 서버 관리는 충분합니다.

1. 설치

먼저 npm을 이용해 PM2를 전역(global)으로 설치합니다.

Bash

npm install pm2 -g

2. 애플리케이션 시작 및 관리

가장 기본적인 명령어들입니다.

명령어설명예시
pm2 start애플리케이션을 시작하고 PM2의 관리 목록에 등록합니다.pm2 start app.js --name "my-api"
pm2 listPM2가 현재 관리하고 있는 모든 애플리케이션의 목록과 상태를 보여줍니다.pm2 list
pm2 stop특정 애플리케이션 또는 모든 애플리케이션을 중지시킵니다. (목록에서는 사라지지 않음)pm2 stop 0 또는 pm2 stop my-api
pm2 restart애플리케이션을 재시작합니다. 코드 변경 사항을 적용할 때 유용합니다.pm2 restart my-api
pm2 delete특정 애플리케이션을 PM2 관리 목록에서 완전히 삭제합니다.pm2 delete my-api

3. 실시간 모니터링: pm2 monit

터미널에서 애플리케이션의 CPU, 메모리 사용량과 로그를 한눈에 볼 수 있는 강력한 대시보드를 제공합니다.

Bash

pm2 monit

이 명령어를 실행하면 어떤 프로세스가 자원을 많이 사용하는지, 실시간으로 어떤 로그가 쌓이는지 직관적으로 파악할 수 있어 문제 해결에 큰 도움이 됩니다.

4. 로그 관리: pm2 logs

애플리케이션에서 발생하는 모든 로그(console.log 등)는 PM2가 별도의 파일로 관리해줍니다.

Bash

# 모든 앱의 실시간 로그를 확인
pm2 logs

# 특정 앱의 로그만 확인
pm2 logs my-api

# 과거 로그까지 모두 출력
pm2 logs --lines 1000

로그 파일은 보통 ~/.pm2/logs 디렉토리에 [앱이름]-out.log(일반 로그)와 [앱이름]-error.log(에러 로그) 파일로 저장됩니다.


3장: 서버 효율 극대화, 클러스터 모드

이제 PM2의 진정한 힘을 경험해 볼 차례입니다. 앞서 언급했듯 Node.js는 싱글 스레드라 CPU 코어를 하나밖에 사용하지 못합니다. 클러스터(Cluster) 모드는 이 한계를 돌파하는 기술입니다.

클러스터 모드란?

클러스터 모드는 하나의 Node.js 프로세스를 여러 개로 복제하여 각 프로세스가 서로 다른 CPU 코어에서 동시에 실행되도록 만드는 기능입니다. 마치 1명의 유능한 요리사가 모든 주문을 처리하던 주방에, 똑같이 유능한 요리사 여러 명을 투입해 주방 전체의 처리량을 폭발적으로 늘리는 것과 같습니다.

PM2는 Node.js에 내장된 cluster 모듈을 매우 쉽고 우아하게 사용할 수 있도록 도와줍니다. 들어오는 요청(Request)은 PM2가 알아서 쉬고 있는 프로세스(요리사)에게 균등하게 분배(Load Balancing)해줍니다.

사용법: -i 옵션 하나면 끝!

클러스터 모드를 사용하는 방법은 놀랍도록 간단합니다. pm2 start 명령어에 -i 옵션을 추가하기만 하면 됩니다.

Bash

# 현재 서버의 모든 CPU 코어를 사용해서 클러스터 모드로 실행
pm2 start app.js -i 0

# 'max' 키워드를 사용해도 동일하게 동작
pm2 start app.js -i max

# 4개의 프로세스만 사용하고 싶을 경우
pm2 start app.js -i 4

-i 0 또는 -i max 옵션을 주면 PM2가 서버의 CPU 코어 수를 자동으로 파악하여 그 개수만큼 프로세스를 생성합니다. pm2 list 명령어로 확인해보면, 동일한 이름의 애플리케이션이 여러 개(CPU 코어 수만큼) 실행되고 있는 것을 볼 수 있습니다.

무중단 재시작 (Zero-downtime Reload)

클러스터 모드의 또 다른 강력한 장점은 바로 ‘무중단 재시작’입니다. 코드 변경 후 서버에 반영할 때 pm2 restart를 사용하면 모든 프로세스가 동시에 종료되었다가 다시 시작되기 때문에 아주 짧은 순간 서비스 다운타임이 발생합니다.

하지만 pm2 reload 명령어를 사용하면 PM2는 각 프로세스를 하나씩 순차적으로 재시작합니다. 즉, 첫 번째 프로세스를 재시작하는 동안 나머지 프로세스들은 계속해서 요청을 처리하고, 첫 번째 프로세스가 완전히 준비되면 두 번째 프로세스를 재시작하는 방식입니다. 이 덕분에 사용자는 서비스 중단을 전혀 느끼지 못한 채로 새로운 버전의 코드가 서버에 배포될 수 있습니다.

Bash

# my-api 애플리케이션을 무중단으로 재시작
pm2 reload my-api

4장: 전문가를 위한 PM2 심화 관리

PM2를 단순히 커맨드로만 사용하는 것을 넘어, 설정 파일을 통해 훨씬 더 체계적이고 선언적으로 관리할 수 있습니다.

궁극의 설정 파일: ecosystem.config.js

ecosystem.config.js 파일은 여러 애플리케이션의 설정, 환경 변수, 실행 모드, 배포 스크립트 등을 하나의 자바스크립트 파일 안에 정의할 수 있게 해줍니다.

먼저, 아래 명령어로 설정 파일 템플릿을 생성합니다.

Bash

pm2 ecosystem

그러면 ecosystem.config.js 파일이 생성됩니다. 이 파일을 열어 우리에게 맞게 수정해 봅시다.

JavaScript

// ecosystem.config.js
module.exports = {
  apps: [
    {
      name: 'api-server', // 애플리케이션 이름
      script: './app.js', // 실행할 스크립트 파일
      instances: 0, // 0 또는 'max'로 설정하면 CPU 코어 수만큼 인스턴스 생성
      exec_mode: 'cluster', // 클러스터 모드로 실행
      watch: false, // 파일 변경 감지 여부 (개발 환경에서만 유용)
      max_memory_restart: '300M', // 프로세스 메모리가 300MB를 초과하면 재시작
      env: {
        // 공통 환경 변수
        NODE_ENV: 'development',
      },
      env_production: {
        // 운영 환경 전용 환경 변수
        NODE_ENV: 'production',
        PORT: 8080,
      },
    },
    {
      name: 'worker',
      script: './worker.js',
      instances: 2, // 워커 프로세스는 2개만 실행
    }
  ],
};

이 파일 하나로 api-serverworker라는 두 개의 다른 애플리케이션을 동시에 관리할 수 있습니다. 또한, 운영 환경과 개발 환경의 환경 변수를 분리하여 관리의 효율성을 높였습니다.

이제 이 설정 파일을 사용하는 방법은 간단합니다.

Bash

# 설정 파일에 정의된 모든 앱을 개발 모드로 시작
pm2 start ecosystem.config.js

# 설정 파일에 정의된 모든 앱을 운영 모드로 시작
pm2 start ecosystem.config.js --env production

# 특정 앱만 시작
pm2 start ecosystem.config.js --only api-server

# 무중단 재시작도 동일하게 적용 가능
pm2 reload ecosystem.config.js --env production

명령줄에 길게 옵션을 나열하는 대신, 잘 정의된 설정 파일 하나로 복잡한 애플리케이션 환경을 일관되게 관리할 수 있습니다.

서버 재부팅에도 끄떡없는 자동 시작 스크립트

서버를 예기치 않게 재부팅해야 할 때, PM2가 관리하던 프로세스들을 다시 수동으로 실행해야 한다면 매우 번거로울 것입니다. pm2 startup은 서버가 부팅될 때 PM2 데몬과 관리하던 프로세스들을 자동으로 다시 시작해주는 스크립트를 생성해줍니다.

Bash

# 현재 운영체제에 맞는 시작 스크립트를 생성하고 등록 방법을 안내
pm2 startup

# 현재 실행 중인 프로세스 목록을 저장
pm2 save

pm2 startup을 실행하면 시스템 서비스로 등록하는 명령어를 출력해줍니다. 그 명령어를 복사하여 실행하면, 다음부터 서버가 재부팅되어도 pm2 save로 저장했던 프로세스 목록이 자동으로 복원되어 실행됩니다.


결론: PM2, 당신의 가장 든든한 서버 파트너

node app.js로 시작된 여정은 PM2를 만나면서 비로소 프로덕션 수준의 안정성과 효율성을 갖추게 됩니다. PM2는 단순히 프로세스를 실행시켜주는 도구를 넘어, 다음과 같은 가치를 제공하는 든든한 파트너입니다.

  • 안정성: 예기치 않은 에러로 프로세스가 죽어도 즉시 되살려 서비스 중단을 막아줍니다.

  • 성능: 클러스터 모드로 서버의 멀티코어 CPU 자원을 100% 활용하여 애플리케이션의 처리량을 극대화합니다.

  • 관리 편의성: ecosystem.config.js를 통해 복잡한 애플리케이션 구성을 명료하게 관리하고, 로그, 모니터링, 무중단 배포 등 운영에 필요한 거의 모든 기능을 손쉽게 제공합니다.

이제 당신의 Node.js 애플리케이션을 더 이상 홀로 두지 마세요. PM2라는 유능한 매니저에게 맡겨두고, 당신은 더 중요한 비즈니스 로직 개발에 집중하시길 바랍니다.