이번 실습은 node.js를 활용해서 간단한 어플리케이션을 만들고, 이미지를 만든 후에, Container Registry에 Push하고, 해당 이미지를 가져와서 Container 내에서 어플리케이션을 구동시키는 실습을 진행해보겠습니다.
1. Docker / VSCODE extension 설치
https://www.docker.com/products/docker-desktop/
먼저 Docker를 설치해줍니다. 맞는 OS로 설치해주시면 됩니다.
다음으로는 VSCODE에서 Docker Extension을 설치해줍니다. 여기까지가 Docker Container를 만들기 위한 Software 설치입니다.
2. Node.js 프로젝트 생성
(1) 터미널에서 먼저 project를 초기화하고, 생성해줍니다.
npm init -y
npm i express
(2) node_modules가 다운로드 된 페이지에 index.js라는 파일을 생성하고, 해당 코드를 적습니다.
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Ⓜ️ Dream coding in Docker! Ⓜ️');
});
app.listen(8080, () => console.log('Server is running'));
요청이 오면 특정 문구를 띄우는 간단한 어플리케이션입니다. 8080 포트에서 구동합니다. 터미널에서 해당 명령어를 통해 서버를 구동합니다.
node index.js
서버가 잘 구동 중인 것을 확인합니다.
3. Image 생성
(1) Dockerfile 생성
폴더에 Dockerfile을 만들어주고, 안에 해당 코드를 적어줍니다.
FROM node:16-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY index.js .
ENTRYPOINT [ "node", "index.js" ]
- FROM ~
- base image를 적어줍니다. 순수한 리눅스 이미지를 사용하는 경우도 있으나, 이번 실습에서는 node에서 미리 만들어둔 이미지가 있기 때문에 이를 base image로 사용합니다.
- WORKDIR /app
- Docker 이미지 안에서, 컨테이너 안에서 어떤 경로의 우리가 이 것을 실행할 것인지 결정합니다.
- 이 명령은 Work 디렉토리 안에 루트 경로의 app이라는 폴더 안에 프로젝트에 관련된 모든 파일들을 카피해오겠다는 것 명령입니다. WORKDIR는 리눅스로 cd와 비슷한 명령어 입니다.
- COPY package.json package-lock.json ./
- app이라는 경로에 들어와서, 해당 파일을 복사해옵니다.
- 이는 Layer와 관련된 개념이 들어가야하는데, 뒤에서 설명하겠습니다.
- RUN npm ci
- 해당 명령어를 사용하면 package.json package-lock.json에 있는 모든 파일들을 설치합니다.
- 이 때 npm install을 사용할 수도 있으나, npm ci를 사용하는 이유는 install을 하면 특정 라이브러리의 최신 버전을 설치합니다. 이 때 이미지를 컨테이너에서 구동시킬 때 버전이 달라 꼬이는 경우가 발생합니다.
- 이 때 install 대신 CI를 사용하면 이미지를 빌드할 때 사용했던 정확한 버전을 설치해서, 버전이 달라지는 문제를 해결할 수 있습니다.
- COPY index.js
- 소스파일을 복사합니다.
- ENTRYPOINT [ "node", "index.js" ]
- node라는 걸 실행할 거고, index.js를 실행한다는 명령어를 사용합니다.
(*) Layer 관련 개념
Docker를 통해서, Layer를 쌓을 때는 빈번히 수정해야하는 Layer를 가장 위로 올립니다. 그래야 나중에 Image를 다시 만들 때, 변경되지 않은 Layer는 cash로 재사용하고 변경된 것만 업데이트를 하기 때문에 이미지를 만드는 시간을 단축시키고 효율성을 높일 수 있습니다.
(2) Docker Build
터미널에 다음 명령어를 입력합니다.
docker build -f Dockerfile -t fun-docker .
- . 은 build context로 현재 경로로 지정해줍니다.
- -f Dockerfile은 도커 파일로 쓸 이름을 작성해줍니다.
- -t fun-docker -> fun-docker라는 태그를 붙여서 이미지의 이름을 붙여줍니다.
실행이 전부 되면, 만들어진 이미지를 확인합니다.
docker images
REPOSIOTRY는 fun-docker라고 되어있는데, 나중에 Container-repository에 올릴 때 이 이미지 이름이 재사용 될 예정입니다. 그리고 TAG는 따로 버전을 명시해주지 않았기 때문에 lateset로 설정되었습니다.
(3) Image 실행
이미지를 도커로 실행해봅니다.
docker run -d -p 8080:8080 fun-docker
- d 옵션은 detach를 의미합니다.
- 계속 돌아가기 때문에 그러면 터미널이 계속 대기하는 상황이 됩니다.
- 따라서 이를 분리해줍니다. background에서 동작하게합니다.
- p 옵션은 port를 의미합니다.
- 호스트 머신의 8080 포트와, 컨테이너의 포트 8080을 연결합니다.
해당 명령어를 실행하면 container의 id가 출력됩니다.
그리고 다시 localhost:8080을 이용해서 서버를 확인해봅니다.
docker logs 1938fcbc7121
컨테이너 아이디를 활용해서 컨테이너에서 발생하고 있는 로그 메세지를 볼 수 있습니다.
docker_desktop을 통해서 gui를 통해 확인할 수도 있습니다. 물론 컨테이너에 대한 터미널을 자체적으로 따로 사용할 수 있습니다.
4. Image Container registry에 업로드하기
(1) Docker Hub에 가입합니다.
(2) 새로운 레퍼지토리를 생성합니다.
(3) 레퍼지토리 이름을 설정하고 생성 합니다.
(4) 레퍼지토리의 Docker commands 부분을 참고합니다.
이미지의 이름이 레퍼지토리의 이름과 매칭되어야합니다. 해당 명령어를 사용해서 이미지와 레퍼지토리를 매핑해줍니다.
docker tag fun-docker:latest sangwook1224/docker-example1:latest
도커에 로그인합니다.
login
이미지를 push 합니다.
docker push sangwook1224/docker-example1:latest
레퍼지토리에 잘 업로드 된 것을 확인합니다.
여기까지 DOCKER 이미지를 BUILD하고, Registry에 업로드하는 과정까지 다뤄봤습니다. 감사합니다:)
'데이터 엔지니어링 > Docker' 카테고리의 다른 글
[DOCKER] DOCKER 개념 정리 (1) | 2023.06.11 |
---|