반응형
0. 도커 이미지 빌드 예제 개요 : node.js를 이용하여 간단한 프로그램 만들기
- package.json 파일 작성
- server.js 파일 작성
- Dockerfile 작성
- Docker build
- 실행
- 도커 이미지 빌드 예제 코드의 문제점
- 완성 코드
- volume을 사용하여 실행
1. 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.17.1"
}
}
- package.json 파일은 node.js에서 프로젝트에서 사용하는 패키지들의 의존성 정보를 관리하는 파일.
- express 는 jQuery 처럼 node.js를 좀 더 편하고 쉽게 사용할 수 있도록 해주는 패키지.
2. 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("Server is running");
- server.js 파일은 시작점으로서 가장 먼저 실행되는 파일
3. Dockerfile 작성 예제
# 베이스 이미지 파일
FROM node:10
# Work directory 설정
WORKDIR /usr/src/app
# 위에 FROM 에서 사용한 node 베이스 이미지 파일 안에는 package.json와 server.js 파일이 없기 때문에 에러가 난다.
# 내 로컬에 있는 package.json 파일을 실행할 컨테이너 안으로 복사해서 넣어줘야 정상적으로 실행이 된다.
# "COPY package.json ./" 이런 식으로 하나의 파일만 복사 할 수도 있고,
# "COPY ./ ./" 이런 식으로 경로 안에 있는 모든 파일을 넣어주는 것도 가능하다.
COPY ./ ./
# 베이스 이미지를 사용하기 위한 추가 설치
RUN npm install
# 실행 명령어
CMD ["node", "server.js"]
- 위 Dockerfile 예제 에서는 COPY 부분이 중요하다.
- node.js를 실행하기 위해서는 npm(node.js에서 사용하는 패키지를 관리하는 모듈) 설치가 필수이다.
npm을 설치할때 package.json 파일을 참조하여 의존성 정보를 읽어서 불러오게 되는데 해당 파일이 "FROM node:10" 로 설정해준 베이스 이미지 파일에 들어있지 않아 빌드시 오류가 발생한다. - 따라서 이미지 내부에 없는 파일을 로컬에 미리 만들어 둔 다음에 Dockerfile 내부에 COPY 명령어를 사용하여 생성할 컨테이너 안쪽으로 넣어줘야 한다.
- "COPY package.json ./" 이런 식으로 하나의 파일만 복사 할 수도 있고
- "COPY ./ ./" 이런 식으로 경로 안에 있는 모든 파일을 넣어주는 것도 가능하다.
- 하지만 COPY를 통해서 복사할 파일이 기존에 이미지 파일 내부에 있는 파일의 이름과 동일한 경우 덮어쓰기를 할 수도 있고, 파일 관리를 편하게 하기 위해서 working directory를 따로 지정해주는 것이 좋다.
=> WORKDIR 명령어를 이용하여 임의의 파일 경로를 지정하면 그곳으로 COPY로 복사해온 파일들이 저장된다.
- 위에서 설명한 COPY 부분의 설명을 도식화 한 부분이다.
4. Docker build 예제
docker build -t koreanckh/nodejs ./
5. 실행
# docker run -d -p <로컬 포트>:<컨테이너 포트> <이미지 이름>
docker run -d -p 12345:8080 koreanckh/nodejs
- -d 옵션 : docker를 실행하고서 바로 터미널을 닫아주는 옵션(detach).
- -p 옵션 : 컨테이너 내부에서 서버를 띄우는 경우에는 로컬 호스트의 포트와 매핑을 해줘야 한다.
- 위 설명에서 로컬 네트워크의 포트와 컨테이너 네트워크의 포트를 이어준다는 내용을 도식화 하였다.
6. 도커 이미지 빌드 예제 코드의 문제점
- 도커 이미지를 빌드할때 기존에 변경점이 없으면 캐시에 저장되어 있는 데이터를 그대로 불러와 재사용하기 때문에 package.json에 관리되고 있는 패키지들을 다시 받을 필요가 없어진다.
- 3번에서 작성한 Dockerfile을 보면 "RUN npm install"을 하기 위해 작성한 "COPY ./ ./"을 한 경우에는 package.json 이외의 파일을 수정하더라도 전체를 다시 빌드해야 하기 때문에 굉장히 리소스가 낭비된다.
- 따라서 의존성을 관리하고 있는 package.json 만 copy하여 npm install을 진행한 후에 나머지 파일들을 copy해오는 것이 효과적일 것이다.
7. 완성 코드
FROM node:10
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY ./ ./
CMD ["node", "server.js"]
- 6번에서 언급한 COPY를 둘로 나눈 부분을 참고하여 활용하자.
8. volume을 사용하여 실행
# docker run -p 12345:8080 -v <제외할 파일> -v $(pwd):/usr/src/app <이미지 아이디>
- 7번 코드처럼 수정을 했다 하더라도 docker build시에 변경된 파일을 매번 파일을 업로드 해줘야 하는 문제는 여전하다.
- 하지만 volume을 사용하면 직접 파일을 복사해줄 필요 없이 로컬에 있는 경로를 매핑하여 바라보는 상태가 된다.
반응형
'개발 일기라기 보단 메모장 > Docker' 카테고리의 다른 글
09. 도커 컴포즈(Docker Compose)란 무엇일까? (1) | 2021.12.08 |
---|---|
07. 도커(docker) 이미지 만들기 (0) | 2021.11.29 |
06. 도커(docker) 컨테이너의 생명주기 및 사용법 (0) | 2021.11.17 |
05. 도커(docker) 이미지로 컨테이너 만들기 (0) | 2021.11.17 |
04. 도커(Docker) 컨테이너란? (가상화 기술과의 비교) (0) | 2021.11.16 |