※ 본 포스팅은 개인 기록용으로 두서가 없을수도 있고 잘못된 정보를 제공할 수도 있습니다. 혹여나 저와 비슷한 이슈가 있는 분이 있을까봐 결론만 먼저 위에 서술하겠습니다.

 nodemon과 pm2는 같이 사용하면 안된다.

이것이 이번에 했던 뻘짓의 결론입니다.

사용하고 싶어서 같이 사용한 것은 아니지만, 회사의 레거시라 이미 작성이 되어 있는 상태였고, 요구사항은 원본과 루트폴더에 있는 파일을 수정 혹은 추가 없이 이번 이슈를 해결하는 것이었습니다.

제가 했던 프로젝트였다면 ecosystem.config.js 를 만들어서 development, production 환경을 나눠서 돌아가게 할 수 있었을텐데, 하필 회사에서 db에 로직이 추가되면서 백엔드가 주기적으로 뻗는데 pm2가 그것을 감지하지 못하는 이슈가 있었습니다. pm2에서 script를 인자로 받아서 "npm run dev"를 실행하고 있었는데 npm run dev의 script에 nodemon app.js (실제론 app.js는 아니지만 제가 pm2와 nodejs에 대해서 학습한 내용만 기록에 남기는 것이 목표이므로 프로젝트나 회사가 특정될 수 있는 정보는 전부 배제합니다) 구문이 있었기 때문입니다.

pm2로 npm run dev를 실행하는 구문은 다음과 같습니다.

pm2 start npm --name 'test_backend' -- run dev

 

 pm2가 nodemon으로 시작한 앱의 종료를 감지하지 못하는 이유

pm2가 무엇인지, pm2는 nodejs 환경에서 동작하는 내장 로드 밸런서를 포함하고 있는 프로세스 관리자(매니저)라던지와 같은 정보들은 다른 블로그와 선배들의 정리된 글이 많으므로 이번 포스팅에서는 생략하겠습니다. pm2 자체에 대한 학습이 필요하신 분들은 밑의 참고자료들의 링크를 참조해주세요.

결과는 알겠는데, 이것이 어떠한 원리로 인해서 서로 충돌이 있었는지 공부해보게 되었습니다.

이는 pm2가 무엇인지, pm2는 어떻게 동작하는지, nodemon의 목적은 무엇인지를 제대로 파악하고 있었다면 명확하게 알 수 있는 문제입니다.

프로세스 관리자는 프로세스 생성, 종료 및 모니터링과 관련된 다양한 활동을 합니다. pm2는 애플리케이션이 시작된 후 항상 status가 online이 되도록 하는 것을 목표로 합니다. (이는 중단되지 않는 서비스를 목표로 한다는 뜻 입니다.)

nodemon은 node app.js와 ctrl + c 를 계속 해야하는 번거로움을 줄여줄 수 있는 솔루션입니다. 파일 시스템의 변경을 감지하여 서버를 재시작하고 개발자들에게 더 좋은 개발 경험을 주는 것이 목표입니다.

pm2는 각 프로세스끼리 통신하면서 이벤트 혹은 시그널 등을 주고 받으며 기능을 구현하고 있습니다.

프로세스가 준비 되었다면 ready 이벤트를 보내어 이 프로세스가 online이라는 것을 알려주거나,

죽은 프로세스는 SIGOUT 시그널을 보내서 pm2가 프로세스가 종료되었음을 인지하고 다시 시작하게 합니다.

 

여기에서 nodemon과 pm2가 상호 보완적이 아닌, 독립적으로 실행되기 때문에 이슈가 발생했었습니다.

pm2는 어플리케이션이 죽어야 그것을 감지하고 재시작하는 로직인데,

nodemon은 파일의 변경을 바로바로 감지해서 서버를 재시작하기 때문에 백엔드, 프론트, db와의 연결은 상관 없이 nodemon에 의해 서버만 재시작된 상황으로 백엔드는 뻗어있고, 어플리케이션은 확실하게 종료된 적이 없기 때문에 pm2는 어플리케이션을 재시작하지 못했던 것 입니다.

 

좀 더 큰 관점으로 이야기하자면, pm2는 어플리케이션 내부의 로그를 직접 확인하지는 못하고,

내부에서는 이미 nodemon이 다 처리하고 pm2와는 아무런 관계가 없기 때문에 pm2는 몰랐던 것입니다.

 

pm2를 이용한 서버의 재기동 및 해결은 nodejs의 script와 명령어는 어떻게 어디에서 실행되는지와

linux의 cli에 대해서 좀 더 공부한 후에 해결이 가능했으나 본 포스팅에서는 내용이 중구난방이 될 수 있어서 다음에 기회가 된다면 또 정리해보려고 합니다.

(막상 한정된 주제로 이슈를 정리하고 요약하니 얼마 되지 않네요)

 

조금만 찾아봐도 nodemon은 개발환경에서, pm2는 다른 환경 혹은 서비스 배포 후에 사용한다고 보았는데,

왜 그런지 찾아보면서 부족했던 지식을 공부할 수 있는 기회가 되었습니다.

 

 참고자료

[ReferenceUrl] : https://blog.appsignal.com/2022/03/09/a-complete-guide-to-nodejs-process-management-with-pm2.html 가장 큰 도움을 받은 참고자료 입니다.

[Nodejs Document #processenv] : https://nodejs.org/docs/latest-v17.x/api/process.html#processenv

[Pm2Docs] : https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/ 

[Pm2Github] : https://github.com/Unitech/pm2

[RefArticle] : https://engineering.linecorp.com/ko/blog/pm2-nodejs

 .gitignore(깃 이그노어) 생성하기

git bash나 cmd에서

touch .gitignore 

라고 명령을 실행해서 만들 수 있다. 

아니면 그냥 vscode 등의 편집기나 다른 ide에서 클론한 프로젝트에서 직접 .gitignore라는 파일을 만들어도 무방하다.

 

.gitignore(깃 이그노어) 작성하기

.gitignore를 작성하는 첫번째 방법으로는 파일 이름을 직접 적는 방법이 있다.

예를 들자면 "readme.md", "index.html" 등처럼 직접적인 파일 이름을 명시하는 행위를 말한다.

이렇게 하면 깃은 해당 이름을 한 파일을 더 이상 추적하지 않는다.

자주 gitignore에 넣는 단일 파일들로는 환경변수 설정 파일들이 있다. (.env부터 해서 블라블라블라)

root 경로에 있는 파일이 아니라면 그 파일의 경로를 전부 적어줘야한다.

루트에 views가 있고 파일들과 폴더들이 있는 상황

이런 구조에서 잠시 어떤 이슈가 생겨 advertisement.html을 깃으로 업데이트하지 않기를 원한다면 깃이그노어에

views/advertisement.html

이라고 한줄 추가해주면 깃은 더 이상 이 파일을 추적하지 않게 된다.

엄밀히 말해서 이 경우는 저 파일이 이미 커밋되어서 Repository까지 올라가있던 경우라면 깃에서 저 파일을 삭제한 후

깃 이그노어에 views/advertisement.html 를 저장해야지 제대로 적용이 되는 것을 확인할 수 있다.

경로의 시작이 root인 이유는 보통 .gitignore도 root에 있기 때문인데 파일의 경로는 .gitignore의 위치를 기준으로 깃이 판단하는 모양이다.

 

 

두번째 방법으로는 경로를 지정하는 방법이 있다. (이 문제 때문에 오늘의 포스팅이 있게 되었다.)

형식은 "경로 이름/" 의 모양을 한다.

node.js를 이용한 프로젝트를 혼자서 진행하고 있었는데, 깃에 백업을 하려니 파일의 갯수가 너무나도 많아서 다 푸쉬를 하는게 맞는지 찾아보게 되었다. 알고보니 노드의 modules은 그때그때 npm install을 이용해서 진행하는 것이 간편하다. 그래서 혼자서 할 때 뿐만 아니라 협업할 때에도  "node_modules/" 를 .gitignore에 추가하는 편이 좋다.

경로를 포함한 파일을 깃 이그노어에 추가할 때 추가적으로 알아두면 좋은게 있는데,

routes/**/controller.js
와 같은 식으로 깃 이그노어를 작성한다면 이 문장은

routes/controller.js
routes/front-end/public/controller.js
혹은 이것보다 더 짧거나 긴 디렉토리라도 루트 경로에 있는 파일이 2개의 애스터리스크 전에 경로와 겹치고 뒤의 파일 이름이 같다면 깃은 같은 조건의 파일을 전부 추적하지 않게 됩니다.

비슷하게 

public/css/**

이런 식으로 작성하게 되면 public/css/ 밑의 파일들은 전부 깃 추적에서 제외됩니다.

 

 

세번째 방법으로는 확장자를 지정하는 방법이 있다.

형식은 " *.확장자이름 " 의 모습을 한다.

예를 들자면 *.log 를 깃이그노어에 추가한다면 .log 확장자 파일은 더 이상 깃이 추적하지 않게 된다.

 

 .gitignore.io 이용하기

 

.gitignore.io란 프로젝트를 진행할 때 사용할 환경, 언어 등을 세팅해주면

깃 이그노어에 세팅할 문서를 만들어주는 사이트입니다.

아래의 사진은 이 사이트에 "node" 라는 키워드 하나만 넣었을 때 나오는 요소들 중에서

지금 프로젝트에서 누가 봐도 안쓸만한 요소들을 빼고 다시 정리한 파일입니다.

이 내용을 생성한 .gitignore에 카피하면 끝!

 

 

+ Recent posts