콘텐츠로 이동

Next.js 프로세스 운영 기준 (PM2)

운영 서버(Production Server) 에서 Next.js 애플리케이션을 프론트엔드 서버 런타임(Node.js 프로세스) 으로
어떤 방식으로 실행·유지·복구할 것인지에 대한 프로세스 관리 기준을 정의함.

PM2를 유일한 프로세스 매니저로 전제함.

참고: PM2 공식 문서
https://pm2.keymetrics.io/


⚠️ 가장 중요한 운영 원칙 (반드시 숙지)

PM2는 운영 도구이므로 root 권한으로 전역 설치한다.
단, PM2 데몬과 Next.js 프론트엔드 서버 실행은 반드시 운영 사용자 계정으로 수행한다.

이 원칙이 깨질 경우 다음 문제가 발생함.

  • 서버 재부팅 후 서비스 미기동
  • PM2 프로세스 유실
  • 로그 및 권한 꼬임
  • 보안 감사 실패
  • 운영자 외 복구 불가 상태

1. Next.js 프로세스 운영 원칙

운영 환경에서 Next.js 프론트엔드 서버 런타임은 다음 원칙을 따름.

  • Next.js는 단독 실행하지 않음
  • 프로세스 생명주기는 애플리케이션이 아닌 PM2가 관리
  • 장애 발생 시
    • 원인 분석은 로그
    • 복구는 PM2 자동 재시작에 위임

Next.js 프론트엔드 서버는 “살아 있으려고 노력하지 않음”
살아있게 만드는 책임은 PM2에 있음


2. PM2 사용을 전제로 하는 이유 (Next.js 기준)

PM2는 Next.js 운영에서 다음 문제를 해결함.

  • 프로세스 비정상 종료 감지
  • 자동 재시작
  • 로그 수집 및 분리
  • 메모리 초과 감지
  • cluster 기반 확장
  • 무중단 reload 지원

따라서 운영 환경에서는 다음 방식은 금지함.

next start        # ❌
npm run start     # ❌
node server.js    # ❌

운영 표준은 다음과 같음.

pm2 start ecosystem.config.cjs --env production --update-env

3. 운영 실행 위치 기준

PM2 관련 모든 작업은 운영 실행 디렉터리 기준으로 수행함.

  • 기준 경로: /var/www/[ProjectName]/current
cd /var/www/[ProjectName]/current

Next.js 릴리즈 구조(releases/current)를 사용하는 경우
반드시 current 심링크 기준으로 실행함.


4. PM2 설치 및 기본 준비

4.1 PM2 전역 설치 (root)

PM2는 운영 도구이므로 반드시 root 권한으로 전역 설치함.

sudo npm install -g pm2@latest
  • 이 단계는 전역 바이너리(/usr/bin/pm2) 설치만 담당함

⚠️ 주의
이 단계까지만 root 권한 사용
이후 PM2 관련 실행은 절대 root로 하지 않음

4.2 pm2-logrotate 설치 (운영 사용자)

pm2-logrotatePM2 데몬 단위 모듈이므로
반드시 실제 애플리케이션을 실행하는 운영 사용자 기준으로 설치함.

su - [User]
pm2 install pm2-logrotate
  • sudo pm2 install pm2-logrotate 방식은 root PM2 데몬에 설치될 수 있으므로 지양함
  • 파일 로그 기반 운영 시 pm2-logrotate 적용을 권장함

4.3 설치 확인

which pm2
pm2 -v

정상 경로 예시:

/usr/bin/pm2

다음 경로는 운영 기준 위반임.

  • /root/.nvm/...
  • /home/user/.npm/...

5. ecosystem.config.cjs 운영 기준

5.1 ecosystem 파일 생성 (운영 사용자)

PM2 실행은 반드시 운영 사용자 계정으로 수행함.

su - [User]
cd /var/www/[ProjectName]/current
pm2 ecosystem

CLI 옵션 기반 실행은 허용하지 않음
모든 실행 정의는 ecosystem.config.cjs로 관리함

5.2 ecosystem 예시 (Next.js 프론트엔드 서버)

⚠️ 주의
아래 예시는 형식 참고용
인증 토큰, API KEY 등 민감정보를 평문으로 저장하지 않음

module.exports = {
    apps: [
        {
            name: "frontend.example.com",

            cwd: "/var/www/frontend.example.com/current",

            script: "node_modules/next/dist/bin/next",
            interpreter: "/usr/bin/node",
            args: "start",

            /**
             * 실행 모드
             */
            instances: 1,
            exec_mode: "fork",

            /**
             * 메모리 옵션
             */
            node_args: "--max-old-space-size=1024",

            /**
             * 환경 변수
             */
            env_production: {
              NODE_ENV: "production",
              PORT: 3000,
              HOSTNAME: "127.0.0.1",
              NEXT_TELEMETRY_DISABLED: "1",
            },

            /**
             * 안정성 옵션
             */
            autorestart: true,
            watch: false,
            listen_timeout: 8000,
            kill_timeout: 8000,

            /**
             * 로그
             */
            merge_logs: true,
            time: true,
        },
    ],
};

6. 실행 및 반영 절차 (운영 사용자)

6.1 최초 실행

su - [User]
cd /var/www/[ProjectName]/current
pm2 start ecosystem.config.cjs --env production --update-env

6.2 설정 변경 반영 (권장)

pm2 reload ecosystem.config.cjs --env production --update-env

restart가 아닌 reload를 우선 사용함


7. 로그 로테이션 기준 (pm2-logrotate)

PM2 로그 로테이션은 애플리케이션 또는 ecosystem 설정이 아니라 PM2 모듈 설정으로 관리함.
따라서 ecosystem.config.cjs에 포함할 수 없음.

7.1 동작 구조

  • pm2-logrotate는 PM2 모듈
  • 애플리케이션과 독립적으로 동작
  • 설정은 PM2 데몬 단위로 적용됨

설정 값은 다음 위치에 저장됨.

~/.pm2/module_conf.json

ecosystem.config.cjs와 완전히 무관
앱 reload / restart와 관계없이 유지됨

⚠️ 중요
pm2 set ... 명령은
PM2 데몬을 실행하는 운영 사용자 계정 기준으로 저장됨

7.2 기본 권장 설정

pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:dateFormat YYYY-MM-DD_HH-mm-ss

7.3 추가 옵션 (필요 시)

pm2 set pm2-logrotate:workerInterval 30
pm2 set pm2-logrotate:rotateInterval '0 0 * * *'
pm2 set pm2-logrotate:TZ Asia/Seoul
  • workerInterval : 로그 크기 체크 주기 (초)
  • rotateInterval : 시간 기반 로테이션 (cron)
  • TZ : 타임존 지정

일반 서버에서는 크기 기반(max_size)만으로 충분함

7.4 확인

pm2 conf pm2-logrotate

8. PM2 startup systemd 자동 기동 개요

  • PM2는 기본적으로 사용자 계정 기준 프로세스 매니저임.
  • 아무 설정도 하지 않으면 서버 재부팅 시 PM2 프로세스 목록이 자동 복구되지 않음.
  • 자동 기동을 위해서는 반드시 systemd 연동 설정이 필요함.
  • 단, systemd unit 파일 생성에는 root 권한이 필요하지만, PM2 startup 대상 사용자는 반드시 운영 사용자여야 함.
  • 정상적으로 생성된 systemd unit은 다음 기준을 만족해야 함.
/etc/systemd/system/pm2-[User].service
User=[User]
Environment=PM2_HOME=/home/[User]/.pm2

PM2 startup 상세 절차: 자동 기동 기준 (PM2 startup + systemd)


9. PM2는 왜 root로 설치하고 user로 실행하는가

이 구조는 선택이 아니라 운영 필수 구조임.

9.1 root로 설치하는 이유

  • /usr/bin/pm2 전역 제공
  • systemd, startup 스크립트 충돌 없음
  • 서버 표준 운영 도구로 관리 가능

9.2 user로 실행하는 이유

  • root 권한 앱 실행은 보안 사고 위험
  • 파일/시스템 손상 가능성
  • 최소 권한 원칙 위반

9.3 최종 구조 요약

PM2 설치                  : root
PM2 바이너리              : /usr/bin/pm2
PM2 startup unit 생성 권한 : root
PM2 startup 대상 사용자    : 운영 사용자
PM2 systemd unit User      : 운영 사용자
PM2_HOME                  : /home/[User]/.pm2
PM2 save                  : 운영 사용자
PM2 실행/관리             : 운영 사용자
Node.js 앱 실행           : 운영 사용자

PM2는 root가 “설치”하고, systemd unit 파일 생성에만 root 권한을 사용함.
PM2 daemon, PM2_HOME, Node.js 애플리케이션 실행 주체는 반드시 운영 사용자여야 함.


10. 최종 정리

  • pm2-logrotate 설정은 ecosystem에 넣을 수 없음
  • 로그 정책은 PM2 데몬 단위로 관리함
  • PM2는 root 설치 + user 실행 구조가 정석
  • PM2 설정은 “누가 실행했는가”에 따라 결과가 완전히 달라짐