PM2는 Node.js 애플리케이션을 위한 강력한 프로세스 관리자입니다. 프로덕션 환경에서 애플리케이션을 실행하고 관리하는 데 필요한 많은 기능을 제공합니다. 이 블로그 포스트에서는 PM2의 기본 개념과 사용법에 대해 알아보겠습니다.
PM2란?
PM2(Process Manager 2)는 애플리케이션을 위한 프로덕션 프로세스 관리자입니다. 다음과 같은 주요 기능을 제공합니다:
- 프로세스 관리: 애플리케이션을 백그라운드에서 실행하고 관리
- 자동 재시작: 애플리케이션 충돌 시 자동으로 재시작
- 로드 밸런싱: 클러스터 모드를 통한 CPU 코어 활용 최적화
- 로그 관리: 애플리케이션 로그를 쉽게 관리
- 모니터링: 메모리 사용량, CPU 사용량 등 모니터링
- 무중단 배포: 애플리케이션 재시작 없이 업데이트 가능
설치 방법
PM2는 npm을 통해 전역으로 설치할 수 있습니다:
npm install pm2 -g
기본 사용법
애플리케이션 시작하기
가장 기본적인 사용법은 다음과 같습니다:
pm2 start app.js
주요 명령어
# 애플리케이션 목록 보기
pm2 list
# 특정 애플리케이션 중지
pm2 stop app_name_or_id
# 모든 애플리케이션 중지
pm2 stop all
# 특정 애플리케이션 재시작
pm2 restart app_name_or_id
# 특정 애플리케이션 삭제
pm2 delete app_name_or_id
# 로그 보기
pm2 logs
# 특정 애플리케이션 로그 보기
pm2 logs app_name_or_id
# 모니터링 대시보드
pm2 monit
# 현재의 프로세스 리스트를 저장
pm2 save
# save했었던 프로세스 리스트를 그대로 복구
pm2 resurrect



고급 사용법
클러스터 모드로 실행하기
Node.js는 단일 스레드로 동작하지만, PM2의 클러스터 모드를 사용하면 여러 CPU 코어를 활용할 수 있습니다:
# CPU 코어 수만큼 인스턴스 생성
pm2 start app.js -i max
# 특정 개수의 인스턴스 생성
pm2 start app.js -i 4
환경 변수 설정
pm2 start app.js --env production
프로세스 이름 지정
pm2 start app.js --name "my-api"
로그 파일 설정
pm2 start app.js --log ./logs/app.log
설정 파일 사용하기
복잡한 설정은 ecosystem.config.js
파일을 사용하여 관리할 수 있습니다:
module.exports = {
apps: [{
name: "app",
script: "./app.js",
instances: "max",
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}, {
name: "worker",
script: "./worker.js"
}]
}
설정 파일을 사용하여 애플리케이션을 시작하려면:
pm2 start ecosystem.config.js
실제 사용 예제
예제 1: Express 애플리케이션 실행
# 기본 실행
pm2 start app.js --name "my-api"
# 클러스터 모드로 실행
pm2 start app.js --name "my-api" -i max
# 환경 변수와 함께 실행
pm2 start app.js --name "my-api" --env production
예제 2: 웹 서버와 워커 함께 실행하기
다음과 같은 ecosystem.config.js
파일을 만들어 여러 애플리케이션을 관리할 수 있습니다:
module.exports = {
apps: [{
name: "web-api",
script: "./app.js",
instances: 4,
exec_mode: "cluster",
watch: true,
env: {
PORT: 3000,
NODE_ENV: "development"
},
env_production: {
PORT: 80,
NODE_ENV: "production"
}
}, {
name: "worker",
script: "./worker.js",
instances: 2,
watch: true,
env: {
NODE_ENV: "development"
}
}]
}
실행:
# 개발 환경으로 실행
pm2 start ecosystem.config.js
# 프로덕션 환경으로 실행
pm2 start ecosystem.config.js --env production
예제 3: 로그 관리와 모니터링
# 모든 로그 보기
pm2 logs
# 특정 앱의 로그만 보기
pm2 logs web-api
# 모니터링 대시보드 실행
pm2 monit
자동 시작 설정
서버 재부팅 후에도 PM2가 자동으로 시작되도록 설정할 수 있습니다:
# 현재 실행 중인 애플리케이션 구성 저장
pm2 save
# 시작 스크립트 생성
pm2 startup
# 표시된 명령어를 실행하여 시스템에 등록
PM2로 Python 애플리케이션 실행하기
PM2는 주로 Node.js 애플리케이션을 위한 프로세스 관리자로 알려져 있지만, Python을 포함한 다른 언어로 작성된 애플리케이션도 관리할 수 있습니다. 아래에서 PM2를 사용하여 Python 애플리케이션을 실행하는 방법에 대해도 자세히 설명해 드리겠습니다.
기본 Python 스크립트 실행
Python 스크립트를 PM2로 실행하는 가장 기본적인 방법은 다음과 같습니다:
pm2 start app.py --interpreter python
Python 버전을 명시적으로 지정하려면:
pm2 start app.py --interpreter python3
가상 환경(Virtual Environment)에서 실행
Python 프로젝트는 대부분 가상 환경을 사용하므로, 가상 환경에 설치된 Python을 사용하여 스크립트를 실행하는 방법은 다음과 같습니다:
pm2 start app.py --interpreter /path/to/venv/bin/python
예를 들어:
pm2 start app.py --interpreter ./venv/bin/python
Python 웹 애플리케이션 실행 예제
Flask 애플리케이션 실행
pm2 start app.py --name "flask-app" --interpreter python3
Django 애플리케이션 실행
pm2 start manage.py --name "django-app" --interpreter python3 -- runserver 0.0.0.0:8000
이때 --
뒤에 오는 인자들은 Python 스크립트에 전달됩니다.
ecosystem.config.js를 사용한 설정
보다 복잡한 설정은 configuration 파일을 사용하면 편리합니다:
module.exports = {
apps: [{
name: "flask-app",
script: "./app.py",
interpreter: "python3",
instances: 1,
env: {
FLASK_ENV: "development",
FLASK_APP: "app.py"
},
env_production: {
FLASK_ENV: "production",
FLASK_APP: "app.py"
}
}, {
name: "data-processor",
script: "./process_data.py",
interpreter: "./venv/bin/python",
cron_restart: "0 0 * * *", // 매일 자정에 재시작
watch: false
}]
}
그리고 다음과 같이 실행합니다:
pm2 start ecosystem.config.js
고급 설정 옵션
명령줄 인자 전달
pm2 start data_processor.py --interpreter python3 -- --input-file=data.csv --output-file=results.csv
환경 변수 설정
pm2 start app.py --interpreter python3 --env-production
자동 재시작 설정
pm2 start app.py --interpreter python3 --cron-restart="0 0 * * *"
로그 파일 지정
pm2 start app.py --interpreter python3 --log ./logs/python-app.log
실제 사용 예제
예제 1: Flask API 서버
// ecosystem.config.js
module.exports = {
apps: [{
name: "flask-api",
script: "./api.py",
interpreter: "/home/user/projects/myapp/venv/bin/python",
instances: 4, // 4개 인스턴스 생성
exec_mode: "fork", // Python은 'cluster' 모드를 지원하지 않음
watch: true,
env: {
FLASK_ENV: "development",
FLASK_APP: "api.py",
FLASK_DEBUG: "1"
},
env_production: {
FLASK_ENV: "production",
FLASK_APP: "api.py",
FLASK_DEBUG: "0"
}
}]
}
예제 2: 주기적 실행 작업
// ecosystem.config.js
module.exports = {
apps: [{
name: "data-collector",
script: "./collect_data.py",
interpreter: "python3",
autorestart: false,
cron_restart: "0 */2 * * *", // 2시간마다 실행
watch: false,
env: {
PYTHONUNBUFFERED: "1" // 버퍼 없이 즉시 로그 출력
}
}]
}
예제 3: Flask와 Celery 워커 함께 실행
// ecosystem.config.js
module.exports = {
apps: [{
name: "flask-app",
script: "./app.py",
interpreter: "./venv/bin/python",
instances: 2,
env: {
FLASK_APP: "app.py"
}
}, {
name: "celery-worker",
script: "./venv/bin/celery",
args: "-A tasks worker --loglevel=info",
interpreter: "none", // 이미 실행 파일이므로 인터프리터 필요 없음
instances: 2
}]
}
유의사항
- Python 애플리케이션은 Node.js와 달리 PM2의 클러스터 모드(
-i max
)를 직접적으로 활용할 수 없습니다. 대신 여러 인스턴스를 개별적으로 실행해야 합니다. - 가상 환경을 사용하는 경우 항상 절대 경로를 사용하는 것이 안전합니다.
- Python 애플리케이션이 출력하는 로그가 즉시 표시되지 않는 경우,
PYTHONUNBUFFERED=1
환경 변수를 설정하여 버퍼링을 비활성화할 수 있습니다. - Flask나 Django와 같은 웹 프레임워크를 사용할 때는 개발 서버가 아닌 Gunicorn이나 uWSGI와 같은 프로덕션 WSGI 서버를 사용하는 것이 좋습니다.
pm2 start "gunicorn app:app -b 0.0.0.0:8000" --name "flask-gunicorn"
PM2를 활용하여 Python 애플리케이션을 관리함으로써, 안정적인 실행 환경과 모니터링, 자동 재시작 등의 기능을 활용할 수 있습니다. 특히 웹 애플리케이션이나 주기적인 데이터 처리 작업에 매우 유용합니다.
결론
PM2는 애플리케이션의 프로덕션 환경 관리를 위한 강력한 도구입니다. 프로세스 관리, 자동 재시작, 로드 밸런싱, 모니터링 등 다양한 기능을 제공하여 안정적인 서비스 운영을 가능하게 합니다. 이 글을 통해 PM2의 기본적인 사용법부터 고급 설정, Python까지 알아보았습니다. 애플리케이션을 프로덕션 환경에서 운영한다면 PM2는 반드시 고려해야 할 도구입니다.
답글 남기기