도커 파일을 만들어서 빌드까지 해보는 실습
1) Dockerfile 생성
cat > Dockerfile <<EOF
# Use an official Node runtime as the parent image
FROM node:lts
# Set the working directory in the container to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Make the container's port 80 available to the outside world
EXPOSE 80
# Run app.js using node when the container launches
CMD ["node", "app.js"]
EOF
위 도커파일을 첫번째 줄 부터 하나씩 보면,
FROM node:lts
1. 도커 이미지의 부모 이미지를 선언하고 있다. 지금 만드는 도커파일은 가장 최신 버전의 노드 이미지를 바탕으로 하고 있다.
WORKDIR /app
2. 컨테이너의 현재 디렉토리를 설정한다.
ADD . /app
3. 현재 디렉토리의 컨텐트를 컨테이너로 추가해준다.
EXPOSE 80
4. 컨테이너의 외부 연결 포트를 80으로 지정해준다. 이렇게 외부 포트를 지정해줌으로서 애플리케이션을 실행할 노드 커맨드를 실행시키고 커넥션을 받는다.
2) app.js 파일 생성 (애플리케이션)
도커 이미지로 만들어 실행할 간단한 파일을 만든다.
cat > app.js <<EOF
const http = require('http');
const hostname = '0.0.0.0';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log('Server running at http://%s:%s/', hostname, port);
});
process.on('SIGINT', function() {
console.log('Caught interrupt signal and will exit');
process.exit();
});
EOF
80 포트를 연 http 서버이고, hello world를 찍는 애플리케이션이다.
3) docker build
docker build -t node-app:0.1 .
현재 폴더 안에 있는 도커 파일을 이용해 이미지로 빌드하는 명령어이다.
[+] Building 24.8s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 398B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:lts 2.9s
=> [internal] load build context 0.0s
=> => transferring context: 889B 0.0s
=> [1/3] FROM docker.io/library/node:lts@sha256:671ee8d49ce2a691fc3082203c5deb9522e0c80042aa0ff40c07f4a25e63668a 21.5s
=> => resolve docker.io/library/node:lts@sha256:671ee8d49ce2a691fc3082203c5deb9522e0c80042aa0ff40c07f4a25e63668a 0.0s
=> => sha256:4672913f7ad129a34409e7d040621df203218b1cfa91fa0fee3377b065fa0feb 2.21kB / 2.21kB 0.0s
=> => sha256:9280a10caf40b31effb3fd770e9eeef6ef656dd7ccd7b8bb93005a589dc55369 7.58kB / 7.58kB 0.0s
=> => sha256:dc80b8cdbfd36cb20231d807a50d704945d1df4da8f6e23197ccfcb629970491 53.71MB / 53.71MB 4.4s
=> => sha256:671ee8d49ce2a691fc3082203c5deb9522e0c80042aa0ff40c07f4a25e63668a 1.21kB / 1.21kB 0.0s
=> => sha256:5884e7f2c8c61aa845de4902fc29639b58861ae6c2d80bafe82082c0456c0740 5.15MB / 5.15MB 1.0s
=> => sha256:1b792b01ed3c8dc1488cd8aac41ab7d49bb17f3fa22b2e6c846078cec81a1c00 10.87MB / 10.87MB 3.0s
=> => sha256:8f993d5b17f32f4b8a535c25e182e5d8412625beee450e513ca57036e8fdd6dc 54.68MB / 54.68MB 5.4s
=> => sha256:c26edf98ece5babdb6b65e76738cef2c2d05e7075161753d3ba95cd84480d211 189.73MB / 189.73MB 15.1s
=> => sha256:ef4553a29827be949323a49bbe126aac00893203a3234abe3a2915aa4b0b768a 4.20kB / 4.20kB 4.7s
=> => extracting sha256:dc80b8cdbfd36cb20231d807a50d704945d1df4da8f6e23197ccfcb629970491 1.5s
=> => sha256:f12d0fbf1676444f72f7a86719bd3c8a5ef70c77eaee331304d13da832785a54 45.58MB / 45.58MB 8.7s
=> => sha256:14531ce9f0a46be86d89363abbf533499226c7734e56c3fbb7d70a8da9562be7 2.28MB / 2.28MB 5.8s
=> => sha256:5f64eb351b344b535e5676014358c3045349fae2d10e4d45048067a26b17229c 452B / 452B 6.1s
=> => extracting sha256:5884e7f2c8c61aa845de4902fc29639b58861ae6c2d80bafe82082c0456c0740 0.2s
=> => extracting sha256:1b792b01ed3c8dc1488cd8aac41ab7d49bb17f3fa22b2e6c846078cec81a1c00 0.2s
=> => extracting sha256:8f993d5b17f32f4b8a535c25e182e5d8412625beee450e513ca57036e8fdd6dc 1.8s
=> => extracting sha256:c26edf98ece5babdb6b65e76738cef2c2d05e7075161753d3ba95cd84480d211 4.3s
=> => extracting sha256:ef4553a29827be949323a49bbe126aac00893203a3234abe3a2915aa4b0b768a 0.0s
=> => extracting sha256:f12d0fbf1676444f72f7a86719bd3c8a5ef70c77eaee331304d13da832785a54 1.4s
=> => extracting sha256:14531ce9f0a46be86d89363abbf533499226c7734e56c3fbb7d70a8da9562be7 0.1s
=> => extracting sha256:5f64eb351b344b535e5676014358c3045349fae2d10e4d45048067a26b17229c 0.0s
=> [2/3] WORKDIR /app 0.3s
=> [3/3] ADD . /app 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:8407049c1ef0527c06459d7ef98f9df537bd895974ae954ee7aa0910a8ce0524 0.0s
=> => naming to docker.io/library/node-app:0.1 0.0s
위 도커파일에서 작성한 명령어대로 이미지를 만드는 작업을 실행한다.
빌드 커맨드를 자세히 보면,
docker build -t node-app:0.1 .
-t 는 이미지의 이름과 버전을 명시하기 위한 옵션으로 위 명령어에서는 해당 도커파일로 만드는 이미지의 이름을 node-app, 버전은 0.1로 지정하여 이미지를 빌드하고 있다.
그리고 태그는 명시하는 것이 추천되어지는데, 새로운 이미지와 오래된 이미지의 구분이 어렵기 때문이다.
도커파일이 실행되어 이미지를 만드는 빌드 프로세스에서는, 도커파일 명령어 한 줄 한 줄 마다 새로운 이미지를 생성한다. 이전 레이어와 계속 결합되어 최종 이미지가 생성되는 형식으로 작업이 이루어진다.
요약하면 도커파일의 각 줄은 이미지 빌드 중에 중간 컨테이너 레이어를 만들고, 그 레이어들은 이후에 최종 이미지를 형성하는 데 사용된다. 이러한 중간 레이어들은 이미지 빌드 과정에서 캐싱되어 다음 빌드에서 재사용될 수 있으므로, 도커 이미지 빌드 프로세스를 더욱 빠르고 효율적으로 만든다.
4) 빌드 완료 확인
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
node-app 0.1 f166cd2a9f10 25 seconds ago 656.2 MB
node lts 5a767079e3df 15 hours ago 656.2 MB
hello-world latest 1815c82652c0 6 days ago 1.84 kB
빌드를 마치고 다시 docker images 명령어를 실행해보면 방금 만든 node-app image가 생성된 것을 알 수 있다.
또 알아두어야 할 것은 node-app의 base image로 node:lts를 지정해줬기 때문에, node-app을 지우지 않고서는 node 이미지 역시 지울 수 없다.
'kubernetes' 카테고리의 다른 글
구글 스터디잼 쿠버네티스 입문반 스터디 - 04 (0) | 2023.04.16 |
---|---|
구글 스터디잼 쿠버네티스 입문반 스터디 - 03 (1) | 2023.04.16 |
구글 스터디잼 쿠버네티스 입문반 스터디 - 01 (0) | 2023.04.16 |