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 하고 다시 실행해보면 이미지를 빌드하지 않고 실행되는 것을 확인할 수 있다.