@extends('layouts.app') @section('title', 'PM2 프로세스 관리') @push('styles') @endpush @section('content')
Node.js 앱을 24시간 안정적으로 유지하는 프로세스 매니저 — 비개발자를 위한 실전 가이드
비유: "프로그램이 꺼지면 자동으로 다시 켜주는 비서"
회사에서 중요한 기계가 돌아가고 있다고 상상해보자. 이 기계가 갑자기 멈추면 누군가 와서 다시 켜줘야 한다. PM2는 이 "누군가"의 역할을 자동으로 해주는 프로그램이다. 기계(Node.js 앱)가 멈추면 자동으로 다시 켜주고, 기계의 상태를 계속 감시해준다.
PM2 없이 실행하면 어떤 문제가?
PM2 없이 npm start로 직접 실행하면 다음 문제가 발생한다:
자동 재시작
앱이 에러로 멈추면(crash) PM2가 자동으로 다시 시작해준다. 새벽 3시에 에러가 나도 자동 복구된다.
백그라운드 실행
?백그라운드(Background)란 화면에 보이지 않지만 뒤에서 계속 실행되는 것을 뜻한다. 스마트폰에서 음악 앱을 끄지 않고 다른 앱을 사용해도 음악이 계속 나오는 것과 같다.터미널(SSH)을 닫아도 앱이 꺼지지 않고 계속 실행된다. 서버에 접속하지 않아도 24시간 유지된다.
모니터링
앱의 상태, CPU 사용량, 메모리 사용량, 로그를 한눈에 확인할 수 있다. 문제가 생기면 빠르게 원인을 파악할 수 있다.
SAM 프로젝트에서 PM2는 SAM React (Next.js) 프론트엔드를 운영 서버에서 24시간 유지하는 역할을 한다. 사용자가 SAM 웹사이트에 접속하면, PM2가 관리하는 Next.js 앱이 화면을 보여주는 것이다. PM2가 없으면 서버 관리자가 매번 수동으로 앱을 켜고 감시해야 하지만, PM2 덕분에 이 과정이 완전히 자동화된다.
운영 서버(114.203.209.83)에서 사용자의 요청이 처리되는 과정이다. PM2는 Node.js(Next.js) 앱을 관리하며, Nginx가 사용자의 요청을 PM2가 관리하는 앱으로 전달한다.
운영 서버 (114.203.209.83)
PM2를 사용한다. 서버에 Node.js와 PM2가 직접 설치되어 있으며, sam-react라는 이름으로 Next.js 앱을 관리한다.
로컬 Docker 환경 (내 PC)
PM2를 사용하지 않는다. 로컬에서는 Docker 컨테이너가 React 앱을 실행하므로 PM2가 필요 없다. npm run dev로 개발 서버를 실행한다.
현재 PM2가 관리하고 있는 모든 앱의 상태를 표 형태로 보여준다. 앱 이름, 상태(online/errored/stopped), CPU 사용량, 메모리 사용량을 한눈에 확인할 수 있다.
online = 정상 실행 중,
errored = 에러 발생,
stopped = 수동으로 중지됨
start는 새로운 앱을 PM2에 등록하고 실행한다. restart는 이미 등록된 앱을 껐다가 다시 켠다.
pm2 restart sam-react만 사용한다. pm2 start는 최초 1회만 실행하면 된다.
stop은 앱 실행을 중지하지만 PM2 목록에는 남아있다. delete는 PM2 목록에서 완전히 제거한다.
pm2 stop을 실행하면 SAM 프론트엔드가 접속 불가해진다. 유지보수 목적 외에는 실행하지 않는다.
logs는 앱의 실시간 출력(로그)을 보여준다. 에러 원인 파악에 필수적이다. monit은 CPU, 메모리, 로그를 한 화면에서 실시간으로 볼 수 있는 대시보드이다.
pm2 logs sam-react를 실행하여 에러 메시지를 확인한다.
서버가 재부팅되면 PM2도 함께 꺼진다. 재부팅 후 앱이 자동으로 살아나게 하려면 아래 두 명령을 실행해야 한다.
pm2 save를 실행해야 한다. 그래야 서버 재부팅 후에도 변경된 목록이 유지된다.
PM2 명령어 요약표
| 명령어 | 설명 | 사용 예시 |
|---|---|---|
| pm2 list | 실행 중인 앱 목록 확인 | 앱 이름, 상태, CPU/메모리 표시 |
| pm2 start | 앱 시작 | pm2 start npm --name sam-react -- start |
| pm2 restart | 앱 재시작 | pm2 restart sam-react |
| pm2 stop | 앱 중지 | pm2 stop sam-react |
| pm2 delete | 앱 삭제 (목록에서 제거) | pm2 delete sam-react |
| pm2 logs | 실시간 로그 보기 | pm2 logs sam-react |
| pm2 monit | 실시간 모니터링 대시보드 | CPU, 메모리, 로그 실시간 확인 |
| pm2 save | 현재 프로세스 목록 저장 | 서버 재부팅 후 자동 복구용 |
| pm2 startup | 부팅 시 PM2 자동 시작 설정 | 시스템 서비스로 등록 |
SAM React 코드를 수정한 후, 사용자에게 반영하기까지의 전체 흐름이다.
deploy.sh 스크립트가 이 과정을 자동으로 처리한다.
pm2 restart sam-react를 호출한다. 따라서 배포 시 수동으로 PM2 명령을 실행할 필요가 없다.
서버 빌드 금지!
SAM 운영 서버의 스펙은 2코어 CPU, 3.8GB RAM이다.
Next.js 빌드(npm run build)는 메모리를 많이 사용하는 작업으로,
이 스펙에서 실행하면 20분 이상 소요되거나 메모리 부족으로 실패한다.
그래서 빌드는 로컬(내 PC)에서 하고, 빌드된 결과물(.next 폴더)만 서버에 올리는 방식을 사용한다.
올바른 방법 (로컬 빌드)
잘못된 방법 (서버 빌드)
Process or Namespace sam-react not found
원인:
PM2에 sam-react라는 앱이 등록되어 있지 않다. PM2가 재설치되었거나, pm2 delete로 삭제된 경우 발생한다.
해결:
PM2 앱 상태가 errored
원인:
Node.js 앱(Next.js)에 에러가 발생하여 실행이 중단된 상태이다. 코드 오류, 의존성 문제, 환경 변수 누락 등이 원인일 수 있다.
해결:
서버 재부팅 후 앱이 안 뜸
원인:
이전에 pm2 save를 실행하지 않아서, PM2가 재부팅 후 어떤 앱을 실행해야 하는지 모르는 상태이다.
해결:
포트 3000 이미 사용 중
?포트(Port)는 네트워크에서 프로그램을 식별하는 번호이다. 아파트 호수처럼, 한 서버 안에서 여러 프로그램이 각자 다른 포트 번호를 사용한다. Next.js는 기본적으로 포트 3000을 사용한다.원인:
이전에 실행했던 Node.js 프로세스가 아직 포트 3000을 점유하고 있다. PM2에서 제대로 종료되지 않은 잔여 프로세스가 남아있는 경우 발생한다.
해결:
Node.js 앱을 실행하는 여러 방법을 비교한 표이다. PM2가 모든 면에서 우수하기 때문에 SAM에서 PM2를 선택했다.
| 실행 방법 | 백그라운드 실행 | 자동 재시작 | 모니터링 | 로그 관리 |
|---|---|---|---|---|
| npm start | X | X | X | X |
| nohup npm start & ?nohup은 터미널을 닫아도 프로세스가 종료되지 않게 하는 명령어이다. &는 백그라운드 실행을 의미한다. | O | X | X | X |
| screen / tmux ?screen과 tmux는 터미널 세션을 유지해주는 도구이다. 터미널을 닫아도 세션이 유지되지만, 자동 재시작이나 모니터링 기능은 없다. | O | X | X | X |
| PM2 | O | O | O | O |
결론
npm start는 개발 중에만 사용하는 방법이다.
실제 서비스를 운영할 때는 백그라운드 실행, 자동 재시작, 모니터링, 로그 관리를 모두 지원하는
PM2가 최적의 선택이다.
SAM에서도 이러한 이유로 PM2를 사용하여 Next.js 프론트엔드를 안정적으로 운영하고 있다.