Nodejs 앱을 도커 환경에서 실행하려면
간단한 프로젝트를 작성해보자. 구조는 다음과 같다.
nodejs
ㄴpackage.json
ㄴserver.js
ㄴDockerfile
//server.js
const express = require("express");
const PORT = 8080;
const app = express();
app.get("/", (req, res) => {
res.send("hello world");
});
app.listen(PORT);
console.log(`Running on http://127.0.0.1:${PORT}`);
이미지를 생성하기 위해 Dockerfile을 작성해보자
FROM node:10
WORKDIR /usr/src/app
#로컬에 있는 파일을 도커 컨테이너의 지정된 장소에 복사
#여기서는 현재 디렉토리에 있는 모든 파일 복사
COPY ./ ./
RUN npm install
CMD ["node", "server.js"]
Working Directory
Working Directory란 이미지 안에서 어플리케이션 소스 코드를 갖고 있을 디렉토리를 생성하는 것이다. 그리고 이 디렉토리가 어플리케이션의 working directory가 된다.
근데 왜 working directory가 필요한 것인가?
- 원래 이미지에 있던 파일과 이름이 같은 걸 복사해버릴 경우 덮어씌우기 때문에 문제가 발생할 수 있다.
- 이것저것 베이스 이미지 파일들과 섞이기에 지저분하다.
이미지를 생성하고 컨테이너를 실행해보자.
docker build -t <이미지_이름> ./
docker run <이미지_이름>
자 이제 들어가보자
http://127.0.0.1:8080
이렇게 하면 어플리케이션 실행 시 접근이 안된다.
우리가 이미지를 만들 때 로컬에 있던 파일(package.json 등)을 컨테이너에 복사해줘야 했었다. 비슷하게, 네트워크도 로컬 네트워크에 있던 것을 컨테이너 내부에 있는 네트워크에 연결을 시켜줘야 한다!
포트를 매핑시켜줍시다.
docker run -p <포트_번호>:<포트_번호> <이미지_이름>
우리는 로컬의 5000에서 컨테이너의 8080을 매핑해보자.
docker run -p 5000:8080 <이미지_이름>
다시 들어가보자
http://127.0.0.1:5000
잘 실행되는 것을 확인할 수 있다.
FROM node:10
WORKDIR /usr/src/app
COPY ./ ./
RUN npm install
CMD ["node", "server.js"]
기존 파일로는 소스코드를 변경했는데 종속성을 다시 다운받고 있는 비효율적인 모습을 보인다. 따라서 다음과 같이 변경한다.
FROM node:10
WORKDIR /usr/src/app
# 변경된 부분-----------------
COPY package.json ./
RUN npm install
#--------------------------
CMD ["node", "server.js"]
먼저 package.json 부분을 COPY 해주면서 모듈은 모듈에 변화가 생길 때만 다시 다운을 받아주며, 소스코드에 변화가 생길 때 모듈을 다시 받는 현상을 없애줬다.
기존 Dockerfile로는 소스 하나 변경할 때 마다 이미지 빌드 다시하고, 컨테이너 실행시켜야하고 너무 귀찮지 않은가!
기존에는 로컬에 있는 파일들을 복사해서 도커 컨테이너에 넣었다면, 이제는 볼륨을 사용해 로컬에 있는 파일들을 도커 컨테이너에서 참조하도록 변경해보자.
docker run -p 4000:8080 -v /user/src/app/node_modules -v $(pwd):/user/src/app <이미지_아이디>
하나씩 뜻을 살펴보면
-v /user/src/app/node_modules
: 호스트 디렉토리에 node_modules가 없기에 컨테이너 맵핑 하지 x-v $(pwd):/usr/src/app
: pwd 경로에 있는 디렉토리 혹은 파일을 /usr/src/app 경로에서 참조pwd(pring working directory)
현재 작업 중인 디렉터리의 이름을 출력하는데 쓰인다
이제는 이미지를 다시 생성하지 않아도, 컨테이너만 껐다가 켜면 변경된 소스코드가 반영되어 있는 것을 확인할 수 있다!