DevOps/Docker

[Docker] Docker Tutorial (2) : 직접 이미지 만들기

ooeunz 2019. 12. 9. 00:06
반응형

앞선 포스팅에서는 docker hub에서 이미지를 pull 하고 그 이미지를 이용해서 대략적인 사용방법에 관하여 알아보았다. 하지만 docker hub에서 이미지를 pull 하는 경우는 DB 이미지를 제외하면 거의 없다. 보통은 Dockerfile에 개인적인 이미지를 작성해서 사용한다.

 

이번 포스팅에서는 간단한 Node.js 서버를 만들고 직접 이미지를 만드는 것까지 진행해보도록 하겠다.

 


sample project 생성하기

※아래의 예시는 express가 설치 되어있다는 가정하에 진행되며 express로 만든 애플리케이션의 root로 접근하면 확인할 수 있는 "Welcome to Express"라는 메시지를 도커를 이용해 EC2에 배포하여 확인하는 것을 목표로 한다.

 

// express로 프로젝트 생성
express sample-project

// sample-project로 이동
cd sample-project

// dependencies 설치
npm install

// 서버가 실행되는지 확인
npm start

 

localhost:3000으로 접속 하였을 때 아래의 이미지와 같은 화면이 나왔다면 성공이다. 이제 sample-project를 도커를 이용해 EC2에 배포해보도록 하겠다.


Dockerfile 작성하기

Dockerfile은 이미지 생성을 위한 일종의 배치 파일로써, 기본 베이스 이미지를 통해 다양한 명령어 과정을 표현한 파일이라고 생각하면 된다. 배포할 프로젝트 디렉터리에 가서 Dockerfile과 .dockerignore을 만들어준다.

 

먼저 node_modules이 직접 복사되지 않도록 .dockerignore 파일을 아래와 같이 작성한다. 작성법은 .gitignore과 같다.

 

.dockerignore

node_modules/

 

Dockerfile

그런 다음 해야 할 일은 어떤 이미지를 베이스로 빌드할 것인지를 정의하는 일이다. 이 예제에서는 Docker Hub에 있는 LTS 버전 중 가장 최신 버전인 12 버전을 사용하도록 하겠다. 아래의 코드에서 알 수 있듯이 이미지의 이름은 node이고 태그명은 12로써, node.js 12 버전이 설치된 linux 이미지를 기반으로 docker 이미지가 생성된다.

FROM node:12

 

※ 참고: Docker Hub - node

https://hub.docker.com/_/node

 

node - Docker Hub

Supported tags and respective Dockerfile links 8.16.2-jessie, 8.16-jessie, 8-jessie, carbon-jessie 8.16.2-jessie-slim, 8.16-jessie-slim, 8-jessie-slim, carbon-jessie-slim 8.16.2-stretch, 8.16-stretch, 8-stretch, carbon-stretch, 8.16.2, 8.16, 8, carbon 8.16

hub.docker.com

 

다음은 메인테이너(Dockerfile을 생성/관리하는 사람)의 정보를 기입해준다.

MAINTAINER Lucas Shin <yuns994@gmail.com>

 

이제 CMD에서 설정한 실행 파일이 실행될 디렉터리를 지정해주어야 한다.

WORKDIR /usr/src/app

 

베이스 이미지에 이미 Node.js와 npm이 설치되어 있으므로 npm 바이너리로 앱의 dependencies만 설치하면 된다. npm4 버전 이하에서는 package-lock.json 파일을 생성하지 않지만 그 이상의 경우에는 package.json과 package-lock.json을 모두 생성하기 위해 와일드카드를 사용한다.

COPY package*.json ./

RUN npm install

 

앱의 소스파일을 추가한다.

COPY . .

 

가상 머신에 오픈할 포트번호를 도커 데몬에 매핑한다.

(express는 기본적으로 3000번 포트를 바인딩하고 있으므로 3000번 포트를 매핑하도록 하겠다.)

※ 도커 데몬 : docker API 요청을 수신하고 이미지, 컨테이너, 네트워크 및 볼륨 같은 도커 객체를 관리한다.

EXPOSE 3000

 

마지막으로 런타임을 정의하는 CMD로 앱을 실행하는 명령어를 작성한다.

CMD ["npm", "start"]

 

 

모든 소스를 작성하면 아마 아래와 같은 이미지의 형태가 될 것이다.

 

 


Image build

터미널로 작성한 Dockerfile이 있는 디렉터리로 이동해서 아래의 명령어로 이미지를 빌드한다. 나중에 docker images 명령어로 해당 이미지를 찾기 쉽게 하기 위해 --tag 플래그로 이미지에 태그를 추가하도록 하겠다.

// docker build --tag <username>/<repository명>:<태그명> .

docker build --tag ooeunz/sample:node .

 

실제로 명령어를 실행하기 때문에 빌드 시간이 꽤 걸릴 수 있다.

최종적으로 Sucessfully built xxxx와 같은 메시지가 보이면 메시지가 정상적으로 생성된 것이다.

docker images 명령어로 입력해보면 image가 잘 생성된 것을 확인할 수 있다.

 

Image run

이제 만들어준 이미지를 run 해서 빌드해보도록 하겠다. 우리가 예제로 만든 이미지에는 포트번호를 지정해줄 필요가 있기 때문에 -p 옵션을 추가적으로 실행해야 한다.

 

-d 옵션은 -i 옵션의 반대로 컨테이너가 백그라운드에서 실행된다. 또 앞서 이야기한 대로 -p 포트 포워딩 옵션을 통해 컨테이너 외부에서 다양한 포트로 3000번에 외부와 내부 포트를 연결할 수 있다.

// docker run -d -p <포워딩할 포트>:<이미지 포트> <username>/<생성한 이미지>:<태그 명>

docker run -d -p 8080:3000 ooeunz/sample:node

 

실제로 아래와 같이 8080, 8081, 8082 포트로 3000번 포트에 접근하면 같은 결과물을 볼 수 있다.

 


logs

이제 Dockfile로 이미지가 컨테이너로 실행되었으므로 컨테이너 상의 로그를 확인해보도록 하겠다.

// docker logs --follow <컨테이너 ID>

docker logs --follow 94a135c96ad9

 

docker ps를 통해 실행 중인 도커의 컨테이너 중 첫 번째 컨테이너의 로그를 출력해보았다.


이제 직접 이미지를 생성해보았다. 다음 포스팅에서는 이러한 이미지를 docker hub에 push 하고 직접 AWS서버에 배포해보도록 하겠다.

반응형