[Synology] 시놀로지 Docker에 Node.js nodemon 설치해서 사용하는 방법


저는 보통 Node.js로 서버를 만들어서 배포할 때 일반적으로 아마존 AWS나 클라우드 서비스를 이용하지 않고 NAS에 서버를 올려서 사용하는 편입니다. 가격이라고 해봤자 저희 집 전기세 몇천원에 24시간 돌아가고, https 도메인도 가지고 있습니다. 단점이라고 하면 성능이 좀 구지다는 거네요.

특히 여러 서버를 돌리고 있어서 가상환경을 지원하는 Docker을 애용하고 있구요.

 

시놀로지에서 Docker로 Node.js 서버를 돌리려면 간단히 Node.js 이미지만 다운로드 받아서 컨테이너로 설치해주면 됩니다만.. 제일 불편했던 점이 컨테이너 안에서 nodemon 을 사용할 수 없다는 점이였습니다.

NAS에서 서버 코드를 변경해도 일일히 Node.js 컨테이너를 껐다 켜줘야 합니다 -.-

 

Docker로 돌리면 환경 자체가 가상으로 분리되기 때문에 Docker 안에는 사실상 node.js 가 설치되어 있는 리눅스 시스템이 하나 더 돌아가는거랑 마찬가지라서 Docker 안에서 nodemon 을 설치하기가 매우 어렵습니다.

 

사실 Docker 컨테이너 만들고 터미널 탭 간다음에 bash 탭을 열어서 npm i -g nodemon 만 해주고 안에서 nodemon index.js 와 같은 형태로 터미널 안에 실행만 해주면 끝이긴한데, 이렇게 하면 결정적으로 docker 실행 명령어 (execution command) 에 아무것도 적을 수 없습니다. (또 제가 알기로 여기서 터미널 화면을 꺼버리면 nodemon 실행이 꺼져버리는걸로 알고 있습니다.)

 

정확히 말해서 예를 들어서 docker node.js 컨테이너가 실행되자마자 nodemon index.js 를 바로 실행시키고 싶은데, 이렇게 실행명령어를 주면 nodemon 을 찾을수가 없어서 컨테이너가 바로 꺼져버립니다. 터미널에 접근해서 nodemon 을 설치하기 전에 바로 나가버리구요.

 

그렇다고 아무 실행 명령어 없이 node.js 컨테이너를 만든다음에 터미널을 열어서 nodemon 설치 후 실행해주면 서버는 켤 수 있는데 이러면 실행 명령어에 nodemon 명령어를 추가할 수 없습니다.

 

왜냐면 시놀로지에서 Docker 컨테이너를 만들면 이후에 실행 명령어를 수정할 수 없기 때문입니다.

실행 명령어를 수정하고 싶으면 컨테이너를 새로 제작해야 합니다.

 

<현재 상황 정리>

 

=> 아무 실행 명령어 없이 node.js 컨테이너 실행 후, 터미널을 열어서 nodemon 설치 후 터미널 안에서 nodemon 실행 : 실행 명령어에 nodemon 이 없어서 서버가 꺼지면 터미널에 들어가서 일일히 nodemon 명령어를 다시 입력해줘야 함

 

=> nodemon 실행 명령어를 주고 새 컨테이너 생성 : 당연히 가상 컨테이너 환경엔 nodemon 이 설치되어 있지 않아서 계속 컨테이너가 오류로 튕겨서 아무것도 할 수 없음.

 

도대체 왜 이렇게 만든지 모르겠는데 일반적으로 Docker 컨테이너를 만들면 실행 명령어가 컴파일 되어서 만들어지는걸까요..? 이유는 잘 모르겠습니다. 

사실 나중에 실행 명령어를 바꿀 수 있었으면 이런 걱정도 없었는데 말이죠.

 

인터넷을 찾아봐도 마땅한 해결방법이 없네요. 그래서 직접 해결하고 얻어낸 솔루션을 특별히 공짜로 먹여드리겠습니다 여러분.

 


 

그래서 현재 목표는 실행명령어에 nodemon index.js 를 주고, 생성한 Node.js Docker 컨테이너에서 정상적으로 nodemon까지 정상 사용하는 방법이 되겠습니다.

 

=> 즉 어떻게 해서든 Docker 컨테이너 안에 nodemon 도 설치하고 실행 명령어도 nodemon index.js로 주는 방법을 모색해봅니다.

 

뻘짓

아래는 제가 시도해서 다 실패한 방법입니다.

해결법이 궁금하면 바로 아래 해결법 탭으로 이동해주세요.

1. SSH로 접속해서 npm i -g nodemon 명령어 실행 후 컨테이너에서 nodemon 명령어 실행

=> 애초에 Docker 컨테이너로 실행한 node.js 환경은 별도의 환경이라 global 로 설치하는 방법이 별 의미가 없었습니다. Docker 환경이 아니라 시놀로지 npm 환경에 전역적으로 설치되는 것 이였습니다.

 

2. 아무 실행 명령어도 없는 (node 명령어만 있는) 컨테이너로 nodemon 설치 후 그 컨테이너 삭제한 다음 같은 폴더 마운트 해서 nodemon 명령어 실행해보기

=> 사실상 이것도 애초에 컨테이너를 새로 생성할때마다 별개의 node.js 리눅스 환경이 생성되어 의미가 없었습니다.

 

3. 이외에도 global 설치 대신 --save 로 설치하거나 여러 가지 방법으로 시도

=> 근본적으로 Docker 컨테이너 환경에서 설치가 안되기 때문에 의미가 없었습니다.

 

해결법

위에서 수 많은 실패를 겪어본 끝에 갑자기 아이디어가 하나 떠올랐고 문제를 전부해결 할 수 있었습니다.

(docker 실행 명령어를 수정할 수 없는 문제라던가, nodemon 을 Docker 환경에서 직접 설치해야 한다던가.)

 

사실 위에서 문제를 해결할 수 없었던 이유는 근본적으로 Docker 환경 자체가 격리된 환경이였기 때문입니다. 저희는 마운트로 파일만 연결해 놓고 Docker 환경이 그 파일들을 실행하도록 하는거였죠.

그러면 *.sh 파일로 스크립트 파일을 줘서 여기에 nodemon 설치 명령어라던가, nodemon 실행 명령어를 작성해놓고, Docker 컨테이너 환경 안에서 실행하게 된다면? !!

 

Docker 환경에서 *.sh 파일을 실행해서 그 환경이 nodemon 설치를 하게 되고, nodemon 실행도 할 수 있게 됩니다. 또 저희는 즉 *.sh 파일로 스크립트 파일을 생성해서 Docker 실행 명령어에 sh 파일을 주고, 저희는 그 sh 파일만 건듦으로써 Docker에서 실행 명령어 내용을 바꿀 수 없다는 문제 또한 해결되게 됩니다.

 

사실 시놀로지에서 *.sh 파일을 만들어서 실행시키고 나중에 수정을 원하면 *.sh 파일을 바꾸는 형태로 진행을 하는 일종의 꼼수(?) 가 있었는데 이게 갑자기 기억나서 문제를 해결할 수 있게 되었습니다 ㅠㅠ

 

<글 읽기가 귀찮으시면 그냥 아래에 제가 한 방법대로 따라하시면 됩니다>

 

우선 2022-09-26 기준 node:latest 이미지 파일을 기준으로 컨테이너를 생성하겠습니다.

 

컨테이너 이름은 마음대로 하시면 됩니다.

이후 고급 설정으로 이동합니다.

 

자동 재시작 활성화를 탭합니다. (선택)

 

이제 nodemon 테스트를 위해 만들어둔 폴더 docker/nodemon_test 를 /home/node/app 에 마운팅 해줍니다.

마운트 경로는 반드시 /home/node/app 고정입니다. 기본적으로 작업을 하는 베이스 경로가 저곳입니다.

 

나중에 스크립트를 실행할때도 마운트 폴더가 저기에 있어서 만약에 docker/nodemon_test에 있는 index.js를 Docker에서 실행시키고 싶으시면 node /home/node/app/index.js 와 같은 형태로 실행해주셔야 합니다.

 

그리고 설정을 하기 전에 docker/nodemon_test 에 파일 2개를 만듭니다.

1. index.js, 2. run.sh

 

//index.js

console.log("A");

//run.sh
npm i -g nodemon
cd /home/node/app/
nodemon index.js

index.js 가 nodemon 으로 실행해볼 파일이고, run.sh 가 실제로 Docker에서 실행 명령어에서 실행할 스크립트 파일입니다. 저곳에 nodemon 설치 명령어와 nodemon 실행 명령어를 작성해줍니다.

 

서버를 열 포트도 지정해줍니다. 위 예제는 서버를 여는게 아니라 단순히 nodemon 으로 index.js를 실행하는 것이라 따로 설정할 필요는 없습니다.

 

그리고 실행 명령에 다음과 같이 입력합니다.

방금 만든 run.sh 를 docker 컨테이너 실행 시 실행 하도록 합니다.

 

이제 컨테이너 실행 후 터미널 쪽을 확인해보면 매우 감동적이게도 nodemon 이 제대로 실행되는걸 알 수 있습니다. ㅠㅠ

혹시나 해서 NAS에 있는 파일을 VScode로 열어서 수정해보니 실시간으로 변경 사항을 확인하고 다시 켜주는걸 알 수 있습니다. 감동적이네요.

 

cd /home/node/app/
nodemon index.js

한번 실행해서 nodemon 을 이미 설치했으므로 이제 실행할 때마다 nodemon을 설치해줄 필요는 없겠죠? run.sh 파일을 열어서 nodemon 설치 명령어를 지우거나 주석 처리해주면 끝입니다.

이제 알아서 nodemon 서버가 실행됩니다!

COMMENT WRITE