diff --git a/resources/views/academy/pm2-guide.blade.php b/resources/views/academy/pm2-guide.blade.php new file mode 100644 index 00000000..0f2d0de6 --- /dev/null +++ b/resources/views/academy/pm2-guide.blade.php @@ -0,0 +1,888 @@ +@extends('layouts.app') + +@section('title', 'PM2 프로세스 관리') + +@push('styles') + +@endpush + +@section('content') +
+ + {{-- ============================================================ --}} + {{-- 히어로 배너 --}} + {{-- ============================================================ --}} +
+
+
+
+ 아카데미 + + PM2 프로세스 관리 +
+

PM2 프로세스 관리

+

Node.js 앱을 24시간 안정적으로 유지하는 프로세스 매니저 — 비개발자를 위한 실전 가이드

+
+
+
+ ⚙️ +
+
+
+
+ +
+ {{-- ============================================================ --}} + {{-- 좌측 고정 목차 (TOC) --}} + {{-- ============================================================ --}} + + + {{-- ============================================================ --}} + {{-- 우측 콘텐츠 --}} + {{-- ============================================================ --}} +
+ + {{-- 모바일 목차 --}} + + + {{-- ============================================================ --}} + {{-- 1. PM2란? --}} + {{-- ============================================================ --}} +
+
+

+ 1 + PM2란? — 왜 PM2를 쓰는가 +

+ +
+

+ + PM2 = Node.js 프로세스 매니저 + ?프로세스(Process)란 현재 실행 중인 프로그램을 뜻한다. 크롬 브라우저를 열면 크롬 프로세스가 생기는 것처럼, Node.js 앱을 실행하면 Node.js 프로세스가 생긴다. +

+
+

비유: "프로그램이 꺼지면 자동으로 다시 켜주는 비서"

+

+ 회사에서 중요한 기계가 돌아가고 있다고 상상해보자. 이 기계가 갑자기 멈추면 누군가 와서 다시 켜줘야 한다. + PM2는 이 "누군가"의 역할을 자동으로 해주는 프로그램이다. + 기계(Node.js 앱)가 멈추면 자동으로 다시 켜주고, 기계의 상태를 계속 감시해준다. +

+
+ +
+

PM2 없이 실행하면 어떤 문제가?

+

+ PM2 없이 npm start로 직접 실행하면 다음 문제가 발생한다: +

+
    +
  • 1. 터미널을 닫으면 앱이 꺼진다 — SSH 접속을 끊으면 실행 중이던 앱도 함께 종료된다.
  • +
  • 2. 에러가 나면 앱이 중단된다 — 예상치 못한 오류가 발생하면 앱이 멈추고, 누군가 수동으로 다시 켜야 한다.
  • +
  • 3. 상태 확인이 어렵다 — 앱이 잘 돌고 있는지, CPU/메모리를 얼마나 쓰는지 알기 어렵다.
  • +
+
+
+ +
+

+ + PM2가 해결하는 3가지 문제 +

+
+
+
+ 1 +

자동 재시작

+
+

앱이 에러로 멈추면(crash) PM2가 자동으로 다시 시작해준다. 새벽 3시에 에러가 나도 자동 복구된다.

+
+
+
+ 2 +

백그라운드 실행

+ ?백그라운드(Background)란 화면에 보이지 않지만 뒤에서 계속 실행되는 것을 뜻한다. 스마트폰에서 음악 앱을 끄지 않고 다른 앱을 사용해도 음악이 계속 나오는 것과 같다. +
+

터미널(SSH)을 닫아도 앱이 꺼지지 않고 계속 실행된다. 서버에 접속하지 않아도 24시간 유지된다.

+
+
+
+ 3 +

모니터링

+
+

앱의 상태, CPU 사용량, 메모리 사용량, 로그를 한눈에 확인할 수 있다. 문제가 생기면 빠르게 원인을 파악할 수 있다.

+
+
+
+ +
+

+ + SAM에서의 역할 +

+
+

+ SAM 프로젝트에서 PM2는 SAM React (Next.js) 프론트엔드를 운영 서버에서 24시간 유지하는 역할을 한다. + 사용자가 SAM 웹사이트에 접속하면, PM2가 관리하는 Next.js 앱이 화면을 보여주는 것이다. + PM2가 없으면 서버 관리자가 매번 수동으로 앱을 켜고 감시해야 하지만, PM2 덕분에 이 과정이 완전히 자동화된다. +

+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 2. SAM에서 PM2 사용 구조 --}} + {{-- ============================================================ --}} +
+
+

+ 2 + SAM에서 PM2 사용 구조 +

+ +
+

+ + 구조 다이어그램 +

+

+ 운영 서버(114.203.209.83)에서 사용자의 요청이 처리되는 과정이다. + PM2는 Node.js(Next.js) 앱을 관리하며, Nginx가 사용자의 요청을 PM2가 관리하는 앱으로 전달한다. +

+
사용자 브라우저 (크롬, 사파리 등) + + + ┌─────────────────────────────────────┐ + Nginx (웹서버, 포트 80/443) + - 사용자 요청을 받아서 전달하는 역할 + └────────────────┬────────────────────┘ + │ 프록시 (요청 전달) + + ┌─────────────────────────────────────┐ + PM2Node.js (Next.js, 포트 3000) + - SAM 프론트엔드 화면 생성 + - PM2가 이 앱을 감시/관리 + └────────────────┬────────────────────┘ + │ API 호출 + + ┌─────────────────────────────────────┐ + API 서버 (Laravel, PHP) + - 데이터 처리 & DB 접근 + └─────────────────────────────────────┘
+ +
+ 요약: 사용자가 SAM에 접속하면 Nginx가 요청을 받고, + PM2가 관리하는 Next.js 앱이 화면을 생성하고, 필요한 데이터는 API 서버에서 가져온다. +
+
+ +
+

+ + PM2 사용 환경 +

+
+
+

운영 서버 (114.203.209.83)

+

PM2를 사용한다. 서버에 Node.js와 PM2가 직접 설치되어 있으며, sam-react라는 이름으로 Next.js 앱을 관리한다.

+
+
+

로컬 Docker 환경 (내 PC)

+

PM2를 사용하지 않는다. 로컬에서는 Docker 컨테이너가 React 앱을 실행하므로 PM2가 필요 없다. npm run dev로 개발 서버를 실행한다.

+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 3. 자주 쓰는 PM2 명령어 --}} + {{-- ============================================================ --}} +
+
+

+ 3 + 자주 쓰는 PM2 명령어 +

+ +
+ 참고: 아래 명령어들은 모두 운영 서버에 SSH로 접속한 후 실행한다. 로컬(내 PC)에서는 사용하지 않는다. +
+ + {{-- pm2 list --}} +
+

+ + pm2 list — 실행 중인 앱 목록 확인 +

+
+

현재 PM2가 관리하고 있는 모든 앱의 상태를 표 형태로 보여준다. 앱 이름, 상태(online/errored/stopped), CPU 사용량, 메모리 사용량을 한눈에 확인할 수 있다.

+
$ pm2 list +┌────┬──────────────┬─────────────┬─────────┬──────────┬───────────┐ +│ id │ name │ mode │ status │ cpu │ memory │ +├────┼──────────────┼─────────────┼─────────┼──────────┼───────────┤ +│ 0 │ sam-react │ fork │ online │ 0.1% │ 120.5 MB │ +└────┴──────────────┴─────────────┴─────────┴──────────┴───────────┘
+
+
+ 상태 의미: + online = 정상 실행 중, + errored = 에러 발생, + stopped = 수동으로 중지됨 +
+
+ + {{-- pm2 start / restart --}} +
+

+ + pm2 start / pm2 restart — 앱 시작 & 재시작 +

+
+

start는 새로운 앱을 PM2에 등록하고 실행한다. restart는 이미 등록된 앱을 껐다가 다시 켠다.

+
# 새 앱 시작 (PM2에 처음 등록할 때) +$ pm2 start npm --name sam-react -- start +# 해석: npm start 명령을 "sam-react"라는 이름으로 PM2에 등록하여 실행 + +# 이미 등록된 앱 재시작 (배포 후 주로 사용) +$ pm2 restart sam-react +# 해석: sam-react 앱을 껐다가 다시 켠다 (코드 변경 반영)
+
+
+ 실무 팁: 배포 시에는 보통 pm2 restart sam-react만 사용한다. pm2 start는 최초 1회만 실행하면 된다. +
+
+ + {{-- pm2 stop / delete --}} +
+

+ + pm2 stop / pm2 delete — 앱 중지 & 삭제 +

+
+

stop은 앱 실행을 중지하지만 PM2 목록에는 남아있다. delete는 PM2 목록에서 완전히 제거한다.

+
# 앱 중지 (목록에는 남아있음, 나중에 pm2 start로 다시 실행 가능) +$ pm2 stop sam-react + +# 앱 삭제 (PM2 목록에서 완전히 제거) +$ pm2 delete sam-react +# 삭제 후 다시 사용하려면 pm2 start로 새로 등록해야 한다
+
+
+ 주의: pm2 stop을 실행하면 SAM 프론트엔드가 접속 불가해진다. 유지보수 목적 외에는 실행하지 않는다. +
+
+ + {{-- pm2 logs / monit --}} +
+

+ + pm2 logs / pm2 monit — 로그 & 모니터링 +

+
+

logs는 앱의 실시간 출력(로그)을 보여준다. 에러 원인 파악에 필수적이다. monit은 CPU, 메모리, 로그를 한 화면에서 실시간으로 볼 수 있는 대시보드이다.

+
# 실시간 로그 보기 (Ctrl+C로 종료) +$ pm2 logs sam-react +0|sam-react | ▲ Next.js 14.x +0|sam-react | - Local: http://localhost:3000 +0|sam-react | ✓ Ready in 2.3s + +# 최근 100줄만 보기 +$ pm2 logs sam-react --lines 100 + +# 실시간 모니터링 대시보드 (Ctrl+C로 종료) +$ pm2 monit +# CPU, 메모리, 로그를 한 화면에서 실시간 확인
+
+
+ 실무 팁: 앱에 문제가 생기면 가장 먼저 pm2 logs sam-react를 실행하여 에러 메시지를 확인한다. +
+
+ + {{-- pm2 save / startup --}} +
+

+ + pm2 save / pm2 startup — 서버 재부팅 대비 + ?pm2 save는 현재 PM2가 관리하는 앱 목록을 파일로 저장한다. pm2 startup은 서버가 부팅될 때 PM2를 자동으로 시작하도록 시스템에 등록한다. 이 두 명령을 함께 사용하면 서버 재부팅 후에도 앱이 자동으로 살아난다. +

+
+

서버가 재부팅되면 PM2도 함께 꺼진다. 재부팅 후 앱이 자동으로 살아나게 하려면 아래 두 명령을 실행해야 한다.

+
# 현재 프로세스 목록 저장 (재부팅 후 자동 복구용) +$ pm2 save +[PM2] Saving current process list... +[PM2] Successfully saved in /home/pro/.pm2/dump.pm2 + +# 부팅 시 PM2 자동 시작 설정 (최초 1회만 실행) +$ pm2 startup +# 시스템 서비스로 등록 — 서버 켜질 때 PM2가 자동 실행된다
+
+
+ 중요: 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 자동 시작 설정시스템 서비스로 등록
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 4. SAM 배포와 PM2 --}} + {{-- ============================================================ --}} +
+
+

+ 4 + SAM 배포와 PM2 +

+ +
+

+ + 배포 흐름 +

+

+ SAM React 코드를 수정한 후, 사용자에게 반영하기까지의 전체 흐름이다. + deploy.sh 스크립트가 이 과정을 자동으로 처리한다. +

+
배포 흐름 (deploy.sh가 자동으로 처리) + + ① 로컬에서 코드 수정 & git commit + + + ② ./deploy.sh 실행 + + ├──▶ ③ git pull (최신 코드 받기) + + ├──▶ ④ npm run build (로컬에서 빌드) + + ├──▶ ⑤ .next 폴더 압축 → 서버 업로드 + + ├──▶ ⑥ 서버에서 압축 해제 + + └──▶ ⑦ pm2 restart sam-react (앱 재시작!) + + → 사용자가 새 화면을 볼 수 있게 됨
+ +
+ 핵심: deploy.sh 스크립트가 마지막 단계에서 자동으로 pm2 restart sam-react를 호출한다. 따라서 배포 시 수동으로 PM2 명령을 실행할 필요가 없다. +
+
+ +
+

+ + 서버에서 빌드하지 않는 이유 +

+
+

서버 빌드 금지!

+

+ SAM 운영 서버의 스펙은 2코어 CPU, 3.8GB RAM이다. + Next.js 빌드(npm run build)는 메모리를 많이 사용하는 작업으로, + 이 스펙에서 실행하면 20분 이상 소요되거나 메모리 부족으로 실패한다. + 그래서 빌드는 로컬(내 PC)에서 하고, 빌드된 결과물(.next 폴더)만 서버에 올리는 방식을 사용한다. +

+
+
+
+

올바른 방법 (로컬 빌드)

+
# 로컬(내 PC)에서 +$ npm run build +# 빌드 결과물을 서버로 전송 +# PM2 재시작
+
+
+

잘못된 방법 (서버 빌드)

+
# 서버에서 직접 빌드 — 금지! +$ ssh 서버 +$ npm run build +# → 메모리 부족, 서버 먹통 위험!
+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 5. 트러블슈팅 --}} + {{-- ============================================================ --}} +
+
+

+ 5 + 트러블슈팅 — "이럴 땐 어떻게?" +

+ + {{-- 문제 1 --}} +
+
+
+ 1 +

Process or Namespace sam-react not found

+
+
$ pm2 restart sam-react +[PM2][ERROR] Process or Namespace sam-react not found
+
+

원인:

+

PM2에 sam-react라는 앱이 등록되어 있지 않다. PM2가 재설치되었거나, pm2 delete로 삭제된 경우 발생한다.

+
+
+

해결:

+
# Next.js 프로젝트 폴더로 이동 +$ cd /home/webservice/react + +# PM2에 앱을 새로 등록하고 시작 +$ pm2 start npm --name sam-react -- start + +# 목록 저장 (재부팅 대비) +$ pm2 save
+
+
+
+ + {{-- 문제 2 --}} +
+
+
+ 2 +

PM2 앱 상태가 errored

+
+
$ pm2 list +│ 0 │ sam-react │ fork │ errored │ 0% │ 0 B │
+
+

원인:

+

Node.js 앱(Next.js)에 에러가 발생하여 실행이 중단된 상태이다. 코드 오류, 의존성 문제, 환경 변수 누락 등이 원인일 수 있다.

+
+
+

해결:

+
# 1. 먼저 에러 로그를 확인한다 +$ pm2 logs sam-react --lines 50 + +# 2. 에러 원인을 파악한 후 수정 +# 3. 앱 재시작 +$ pm2 restart sam-react + +# 4. 상태 확인 (online이면 정상) +$ pm2 list
+
+
+
+ + {{-- 문제 3 --}} +
+
+
+ 3 +

서버 재부팅 후 앱이 안 뜸

+
+
$ pm2 list +┌────┬──────┬──────┬──────┬─────┬────────┐ +│ id │ name │ mode │ ... │ ... │ ... │ +└────┴──────┴──────┴──────┴─────┴────────┘ +(목록이 비어있음)
+
+

원인:

+

이전에 pm2 save를 실행하지 않아서, PM2가 재부팅 후 어떤 앱을 실행해야 하는지 모르는 상태이다.

+
+
+

해결:

+
# 1. Next.js 프로젝트 폴더로 이동 +$ cd /home/webservice/react + +# 2. 앱 다시 시작 +$ pm2 start npm --name sam-react -- start + +# 3. 반드시 저장! (다음 재부팅에 대비) +$ pm2 save + +# 4. (선택) 부팅 시 PM2 자동 시작 확인 +$ pm2 startup
+
+
+
+ + {{-- 문제 4 --}} +
+
+
+ 4 +

포트 3000 이미 사용 중

+ ?포트(Port)는 네트워크에서 프로그램을 식별하는 번호이다. 아파트 호수처럼, 한 서버 안에서 여러 프로그램이 각자 다른 포트 번호를 사용한다. Next.js는 기본적으로 포트 3000을 사용한다. +
+
$ pm2 start npm --name sam-react -- start +Error: listen EADDRINUSE: address already in use :::3000
+
+

원인:

+

이전에 실행했던 Node.js 프로세스가 아직 포트 3000을 점유하고 있다. PM2에서 제대로 종료되지 않은 잔여 프로세스가 남아있는 경우 발생한다.

+
+
+

해결:

+
# 1. 기존 앱을 PM2에서 완전히 제거 +$ pm2 delete sam-react + +# 2. 혹시 남아있는 Node.js 프로세스 확인 +$ ss -tulnp | grep :3000 + +# 3. 다시 시작 +$ cd /home/webservice/react +$ pm2 start npm --name sam-react -- start + +# 4. 목록 저장 +$ pm2 save
+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 6. PM2 vs 다른 방법 비교 --}} + {{-- ============================================================ --}} +
+
+

+ 6 + PM2 vs 다른 방법 비교 +

+ +

+ Node.js 앱을 실행하는 여러 방법을 비교한 표이다. PM2가 모든 면에서 우수하기 때문에 SAM에서 PM2를 선택했다. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
실행 방법백그라운드 실행자동 재시작모니터링로그 관리
npm startXXXX
nohup npm start & + ?nohup은 터미널을 닫아도 프로세스가 종료되지 않게 하는 명령어이다. &는 백그라운드 실행을 의미한다. + OXXX
screen / tmux + ?screentmux는 터미널 세션을 유지해주는 도구이다. 터미널을 닫아도 세션이 유지되지만, 자동 재시작이나 모니터링 기능은 없다. + OXXX
PM2OOOO
+
+ +
+

결론

+

+ npm start는 개발 중에만 사용하는 방법이다. + 실제 서비스를 운영할 때는 백그라운드 실행, 자동 재시작, 모니터링, 로그 관리를 모두 지원하는 + PM2가 최적의 선택이다. + SAM에서도 이러한 이유로 PM2를 사용하여 Next.js 프론트엔드를 안정적으로 운영하고 있다. +

+
+
+
+ +
+
+ +
+ +{{-- Hover Preview --}} +
+ +
+
+ +{{-- Lightbox --}} + + +@include('components.academy-glossary', ['domain' => 'pm2-guide']) +@endsection + +@push('scripts') + +@endpush