본문 바로가기

개발 일기라기 보단 메모장/Docker

08. 도커(docker) 이미지 빌드 예제

반응형

0. 도커 이미지 빌드 예제 개요 : node.js를 이용하여 간단한 프로그램 만들기

  1. package.json 파일 작성
  2. server.js 파일 작성
  3. Dockerfile 작성
  4. Docker build
  5. 실행
  6. 도커 이미지 빌드 예제 코드의 문제점
  7. 완성 코드
  8. 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을 사용하면 직접 파일을 복사해줄 필요 없이 로컬에 있는 경로를 매핑하여 바라보는 상태가 된다.

 

 

반응형