1. package.json
npm init명령을 통해 package.json을 생성할 수 있다.
{
"name": "nodejs-docker-app",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "4.18.1"
}
}
2. server.js
const express = require('express');
const PORT = 8080;
const HOST = '0.0.0.0';
const app = express();
app.get('/', (req, res) => {
res.send("Hello World");
});
app.listen(PORT, HOST);
console.log('Running on http://${HOST}:${PORT}');
1. 기본 뼈대
#Base Image
FROM node:10
#도커 이미지 실행 전 실행될 쉘 명령어
RUN npm install
#컨테이너 시작시 실행될 명령어
CMD ["node", "server.js"]
2. COPY

위의 dockerfile로 build하는 경우 에러가 발생한다.
Base Image로 임시 컨테이너를 생성한 후, 그 임시 컨테이너 바탕으로 이미지를 생성하는데 임시 컨테이너에는 package.json이 존재하지 않기 때문이다. 즉, package.json은 컨테이너 밖에 있는 상황이다.
따라서 로컬에 있는 package.json을 COPY를 이용해 컨테이너 안으로 넣어줘야 한다.
#Base Image
FROM node:10
#복사할 파일 경로 -> 컨테이너 내에 저장될 경로
COPY ./ ./
#도커 이미지 실행 전 실행될 쉘 명령어
RUN npm install
#컨테이너 시작시 실행될 명령어
CMD ["node", "server.js"]
그 후, tag를 지정하여 build 및 run을 해준다.
docker build -t jym3263/nodejs ./

docker run 명령시, 컨테이너 네트워크와 로컬 호스트 네트워크를 연결시켜줘야한다.
#포트 매핑
docker run -p 5000:8080 jym3263/nodejs
: 이미지안에서 어플리케이션 소스 코드를 갖고 있을 디렉토리를 생성하는 것

따라서 work 디렉토리를 따로 파서 보관하도록 한다.
#Base Image
FROM node:10
#work directory 지정
WORKDIR /usr/src/app
#복사할 파일 경로 -> 컨테이너 내에 저장될 경로
COPY ./ ./
#도커 이미지 실행 전 실행될 쉘 명령어
RUN npm install
#컨테이너 시작시 실행될 명령어
CMD ["node", "server.js"]
다시 ls 명령을 하게 된다면 work directory에서 애플리케이션과 관련된 소스들을 확인 할 수 있다.

또한 root 디렉토리로 이동해 리스트를 조회할 수 있다.

소스코드 변경으로 이미지 생성부터 다시 실행해야 한다. 변경된 부분은 server.js 하나 뿐일때, COPY ./ ./에 의해 node module에 있는 종속성까지 다시 다운을 받아야하는데, 이러한 과정은 매우 비효율적이다.
따라서 dockerfile을 아래와 같이 변경해 준다.

순서를 변경하면 npm install에서 package.json이 변경이 되지 않아 캐시를 사용하고 불필요한 종속성을 다시 다운 받지 않는다.
이전 단계에 의해서 종속성은 새로 다운받지 않아도 되게 되었다. 하지만 COPY 후 이미지를 빌드해주고 컨테이너를 실행해줘야 변경된 소스가 반영이 된다. 이러한 문제를 해결하기 위해 docker volume을 사용하게 된다.

볼륨은 도커 컨테이너에서 호스트 디렉터리에 있는 파일들을 매핑해서 사용을 한다.
docker run -p 8080:8080 -v /usr/src/app/node_modules -v $(pwd):/usr/src/app jym3263/nodejs

docker 를 stop 하고 다시 실행해보면 이미지를 빌드하지 않고 실행되는 것을 확인할 수 있다.