티스토리 뷰
PM2로 Node 서버를 띄우고 있었던 프로젝트에 스케줄링(cron)을 돌리는 로직을 추가하면서
cron을 제어하기 위해 .env에 환경변수를 설정해두었는데
설정을 미실행으로 해놔도 cron이 돌아가고 있었다.
cron 설정 코드
if (process.env.NODE_APP_INSTANCE === '0') {
cron.schedule('0 * * * *', expiredEmailVerification, cronOption);
}
- NODE_APP_INSTANCE === "0" → cron 실행
- != "0" → cron 미실행
.env 설정 (cron 미실행을 위한)
NODE_APP_INSTANCE=1
이렇게 하면 조건문에 걸리지 않으니까 cron이 실행되지 않을 거라고 생각했다.
그런데…
logs를 보니 스케줄링이 정상적으로 실행중이었다. 1시간마다 정확히 로그가 찍히고 있었다.
2026-05-10 13:00:00 [INFO] : 만료된 인증 요청이 없습니다.
2026-05-10 14:00:00 [INFO] : 학교 이메일 인증 만료 처리 완료: 1명 반려
스케줄링을 꺼놨는데 왜 돌아가지???
먼저 환경변수 로딩이 정상적으로 되고 있는지 콘솔을 찍어봤다.
const cron = require("node-cron");
const cronOption = { scheduled: true, timezone: "Asia/Seoul"};
console.log('INSTANCE:', process.env.NODE_APP_INSTANCE);
if (process.env.NODE_APP_INSTANCE === '0') {
console.log('cron 등록됨');
cron.schedule('0 * * * *', expiredEmailVerification, cronOption);
} else {
console.log('cron 스킵됨');
}
결과
INSTANCE: 0
cron 등록됨
.env에 1로 설정했는데 왜 0일까?
원인
NODE_APP_INSTANCE는 내가 설정한 .env의 환경변수이면서 PM2 내부 환경변수이기도 하다.
아래 명령어를 치면 확인할 수 있다.
pm2 env 0
결과

그래서 아무리 프로젝트의 env에서 값을 1로 지정하더라도 PM2 env 값으로 덮어쓰기 때문에 내가 설정한 값은 실제 실행 환경에서 무시되고 있었던 것이다.
왜?
PM2에서 단일 인스턴스로 실행하면 PM2는 자동으로 환경변수 NODE_APP_INSTANCE를 0으로 설정한다.
PM2는 클러스터 모드에서 프로세스 번호를 식별해야 해서 내부적으로 환경변수를 자동 생성한다.
| 프로세스 값 | 프로세스 번호 |
| instance 1 | 0 |
| instance 2 | 1 |
| instance 3 | 2 |
NODE_APP_INSTANCE는 PM2 전용 내부 변수에 가깝다. (개발자가 제어하는 변수 X)
해결
NODE_APP_INSTANCE를 직접 제어하려 하지 말고 cron 전용 환경변수를 새로 만들었다.
.env
CRON_ENABLED=true
코드 수정
if (process.env.CRON_ENABLED === 'true') {
cron.schedule('0 * * * *', expiredEmailVerification, cronOption);
}
이제는 PM2와 충돌할 일이 없이 스케줄링이 정상적으로 제어가 가능해졌다!
'그외 기록 > 트러블 슈팅' 카테고리의 다른 글
- Total
- Today
- Yesterday