nodejs + pm2 application을 구성한 dockfile
을 구성하는 방법에 대해서 알아보도록 하겠습니다.
먼저 code를 어떤 방법으로 배포할지에 대한 process를 정하는 것이 중요합니다. 이는 Dockerfile
을 어떻게 만들지에 대한 방향이 결정나게 됩니다.
배포 Process
제가 구성한 Docker를 이용한 배포 process는 다음과 같습니다.
nvm
설치nvm
을 이용한 node 설치pm2
설치ssh
인증 + git clone
을 통한 code downloadnpm install
.pm2/logs
위치에 따른 host 파일 공유docker run
의 parameter pass를 통한 pm2
start json 파일 전송
1. nvm 설치 & node 설치 & pm2 설치
ubuntu
image를 기본으로 하여 구성을 하도록 하겠습니다. nodejs
application은 npm install
을 통해서 node_modules
을 다운로드 받아서 compile되는 환경이기 때문에 build환경역시 갖추는 것이 중요합니다.
FROM ubuntu
RUN apt-get update
RUN apt-get install -y wget build-essential keychain git python
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 7.3.0
RUN wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
SHELL ["/bin/bash", "-c"]
RUN source $NVM_DIR/nvm.sh; \
nvm install $NODE_VERSION; \
nvm use --delete-prefix $NODE_VERSION;
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN npm install -g pm2
2. ssh 인증 구성
ssh 인증을 위해서 private key
를 image
안에 COPY
할 필요가 있습니다. 그리고 $(ssh-agent)
값을 지정해줄 필요가 있습니다. 그런데, eval
을 이용한 값 설정의 경우, Dockerfile
에서 할 수 없습니다. 따라서 do-ssh.sh
실행 파일을 구성해서 처리할 image 내부에서 실행할 필요가 있습니다.
다음은 do-ssh.sh
파일의 내용입니다.
eval "$(ssh-agent)" && ssh-agent -s
ssh-add /root/.ssh/id_rsa
RUN mkdir /root/.ssh
COPY [ "id_rsa", "/root/.ssh/id_rsa" ]
RUN chmod 600 /root/.ssh/id_rsa
COPY [ "do-ssh.sh", "/root/do-ssh.sh" ]
RUN chmod 777 /root/do-ssh.sh
SHELL ["/bin/sh", "-c"]
RUN /root/do-ssh.sh
RUN ssh -T -v git@10.1.95.184 -o StrictHostKeyChecking=no
3. git code download & npm install
nodejs Application이 위치될 folder를 만들어주고, git clone
을 통해서 code를 받고, npm install
을 하는 구성입니다.
RUN mkdir /apps
SHELL ["/bin/bash", "-c"]
WORKDIR /apps
RUN git clone git@10.1.95.184:/home/git/repo/fms-api-v2.git -o StrictHostKeyChecking=no
WORKDIR /apps/fms-api-v2
RUN npm install
npm install
을 통해서 필요한 node module들을 모두 받아주고 build과정을 거치게 됩니다.
4. PORT 공유 & PM2 Log volume 구성
제가 만든 application은 5000, 8000번 port를 open시켜서 사용합니다. 사용되는 PORT를 EXPOSE
시켜주는 과정이 필요하게 됩니다. 그리고 pm2
의 log 파일을 host에 기록하도록 volume을 추가합니다.
EXPOSE 8000
EXPOSE 5000
VOLUME /root/.pm2/logs
5. 뒷처리과정
매우매우 위험한 파일을 container에 넣어둔것을 기억하고 있어야지됩니다. private key가 바로 그것이지요. 꼭 이 파일을 지워주는 과정이 필요합니다. 마지막으로pm2
실행에 대한 ENTRYPOINT
와 CMD
설정이 필요합니다. 제가 만든 application은 설정 json
파일에 따라서 동작환경이 변경되게 됩니다. 설정 json
파일을 외부에서 parameter로 넣어줄 수 있도록 설정해주는 것이 필요합니다.
RUN rm /root/.ssh/id_rsa
ENTRYPOINT [ "pm2-docker" ]
CMD ["pm2/dev-system.json"]
6. build image & docker run
image를 만들기 위해서, docker build
를 다음과 같이 구성합니다.
docker build -t nodejs-pm2-application .
이제 process가 진행되면 nodejs-pm2-application
으로 image가 만들어지게 됩니다.
만들어진 image를 이용해서 container를 배포하는 명령어는 다음과 같습니다.
docker run -it --name node-app -p 5000:5000 -p 8000:8000 -v /logs/pm2:/root/.pm2/logs -t nodejs-pm2-application pm2/api-system1.json
-p
option으로 5000, 8000번 port를 host에 연결합니다.-v
options으로 /root/.pm2/logs
folder를 host의 /logs/pm2
로 mount 시킵니다.- 마지막에 command로
/pm2/api-system1.json
을 넣어 container의 COMMAND를 pm2-docker pm2/api-system1.json
으로 변경시킵니다.
SUMMARY
Dockerfile을 구성하는 것은 Application의 형태에 따라, 개발환경에 따라 많은 차이를 가지고 오게 됩니다. nodejs
, python
, ruby
와 같이 외부 library를 받아 compile하는 과정을 가지게 된다면 image내부에서 code를 직접 git으로 받아올 필요가 있습니다. 그러나, JAVA
, C#
, GO
와 같이 universal compile이 되는 경우, Docker image를 만들때, compile시켜 ADD
를 통해서 실행파일을 image안에 넣는것이 더 좋을것 같습니다.
다음은 전체 Dockerfile
입니다.
FROM ubuntu
RUN apt-get update
RUN apt-get install -y wget build-essential keychain git python
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 7.3.0
RUN wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
SHELL ["/bin/bash", "-c"]
RUN source $NVM_DIR/nvm.sh; \
nvm install $NODE_VERSION; \
nvm use --delete-prefix $NODE_VERSION;
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN npm install -g pm2
RUN mkdir /root/.ssh
COPY [ "id_rsa", "/root/.ssh/id_rsa" ]
RUN chmod 600 /root/.ssh/id_rsa
COPY [ "do-ssh.sh", "/root/do-ssh.sh" ]
RUN chmod 777 /root/do-ssh.sh
SHELL ["/bin/sh", "-c"]
RUN /root/do-ssh.sh
RUN ssh -T -v git@10.1.95.184 -o StrictHostKeyChecking=no
RUN mkdir /apps
SHELL ["/bin/bash", "-c"]
WORKDIR /apps
RUN git clone git@10.1.95.184:/home/git/repo/fms-api-v2.git -o StrictHostKeyChecking=no
WORKDIR /apps/fms-api-v2
RUN npm install
EXPOSE 8000
EXPOSE 5000
VOLUME /root/.pm2/logs
RUN rm /root/.ssh/id_rsa
ENTRYPOINT [ "pm2-docker" ]
CMD ["pm2/dev-system.json"]
Happy Coding~