카테고리 없음

[Docker] 도커 공식문서로 배우기 (7): 이미지 레이어 추가와 새 이미지

devracoon 2026. 1. 10. 17:56

 

`docker run --name=base-container -ti ubuntu` 명령으로 새 컨테이너를 시작합니다.

 

이미지가 다운로드되고 컨테이너가 시작되면, 새로운 쉘이 열려있는 것을 볼 수 있습니다.

이 쉘은 방금 시작한 컨테이너 안에서 돌아가고 있는 쉘입니다.

`root@70597e8a4875` 저는 이렇게 생겼네요. @ 뒤의 난수는 컨테이너의 ID입니다.

 

출력은 아래처럼 되겠습니다.

$ docker run --name=base-container-sample -ti ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
20043066d3d5: Download complete
Digest: sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54
Status: Downloaded newer image for ubuntu:latest
root@70597e8a4875:/#

 

이제 컨테이너 안에서 Node.js를 설치하기 위해 쉘에서 `apt update && apt install -y nodejs` 명령어를 입력해줍니다.

도커 데스크탑의 Container 탭 내의 Exec 탭을 이용해서도 쉘에 접근할 수 있습니다.

이번에는 이 방법을 통해 진행해보도록 하겠습니다.

Docker Desktop - Containers - Exec

 

명령어를 입력한대로 컨테이너 내부에 Node.js가 설치됩니다.

베이스 이미지에서 변경 사항이 추가된 것인데요,

이 변경 사항은 유니온 파일 시스템에 의해서, 베이스 이미지가 아닌, 이 컨테이너의 고유한 디렉토리에서 일어납니다.

생소한 이야기라면, 아래 링크의 글에서 알아보실 수 있습니다.

[Docker] 도커 공식문서로 배우기 (6): 이미지 레이어 구조, 유니온 파일 시스템, chroot

 

[Docker] 도커 공식문서로 배우기 (6): 이미지 레이어 구조, 유니온 파일 시스템, chroot

도커를 이해하는 데 있어 가장 중요한 개념 중 하나가 바로 이미지 레이어(Image Layer) 입니다.도커 이미지는 단일 파일이 아니라, 여러 개의 레이어가 쌓인 구조로 만들어집니다.이 레이어 구조

devlog.bombs.kr

 

 

 

이제 `node -e 'console.log("Hello world!")'` 명령어를 입력해서 Node.js가 잘 설치되었는지 확인해봅시다.

"Hello world!" 가 출력됩니다. 잘 설치됐네요.

 

Node.js가 잘 설치된 것을 확인했으니, 이 변경 사항을 이미지의 새 레이어로 저장해봅시다.

`docker container commit` 명령을 실행합니다.

우리는 도커 데스크탑 내의 쉘에서 진행하고 있었지만, 이 쉘은 자신이 도커 컨테이너 내부에 있는지조차 모릅니다.

우리는 호스트의 터미널에서 새 쉘을 열거나, 기존에 열려있던 쉘을 종료하고 다시 진행해야 합니다.

저는 열려있던 쉘을 종료하겠습니다.

Status: Downloaded newer image for ubuntu:latest
root@70597e8a4875:/# exit
exit
$

이제 컨테이너 내부의 쉘을 종료하고, 호스트의 쉘로 돌아온 것입니다.

 

`docker container commit -m "Add node" base-container node-base` 명령을 실행해서 변경 사항을 새 레이어로 저장합니다.

이후 `docker image history node-base` 명령으로 레이어를 확인할 수 있습니다.

$ docker container commit -m "Add node" base-container-sample node-base
sha256:552cb16395e44072dcfcb72e5507881a592d6be31370456c9c3bc002f4e7a40c
$ docker image history node-base
IMAGE          CREATED          CREATED BY                                       SIZE      COMMENT
552cb16395e4   15 seconds ago   /bin/bash                                        156MB     Add node
c35e29c94501   2 months ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]             0B
<missing>      2 months ago     /bin/sh -c #(nop) ADD file:ddf1aa62235de6657…   87.6MB
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH      0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG RELEASE                   0B
$

 

comment가 "Add node"인 맨 위 레이어가 확인됩니다.

 

이제 저 이미지가 진짜로 노드를 포함하고 있는 지 확인하기 위해, 저 새 이미지로 새로운 컨테이너를 시작해보겠습니다.

$ docker run node-base node -e "console.log('Hello again')"
Hello again

Node.js가 잘 설치되어있네요. "Hello again"이 잘 출력됩니다.

이제 새 베이스 이미지 만드는 것을 완료했으니, `docker rm -f base-container` 컨테이너를 삭제하겠습니다.

 


 

베이스 이미지를 기반으로 이미지를 확장해보겠습니다.

먼저, `$ docker run --name=app-container -ti node-base`  명령을 실행해서 베이스 이미지로 새 컨테이너를 시작합니다.

 

그리고 아무 말이나 하는 프로그램을 하나 작성합니다.

root@906dbf07f1be:/# echo 'console.log("Hello from an app")' > app.js
root@906dbf07f1be:/# node app.js
Hello from an app
root@906dbf07f1be:/#

 

아무 말을 잘 하는 것을 확인할 수 있습니다.

이제 이 아무 말 하는 프로그램을 이미지로 만들어보겠습니다.

`docker container commit -c "CMD node app.js" -m "Add app" app-container sample-app` 명령을 실행합니다.

이 명령은 `app-container` 컨테이너의 변경사항을 `sample-app`이라는 이름의 새 이미지로 생성합니다.

`-c "CMD node app.js"`는 이미지가 실행될 때 이 명령어를 실행하도록 설정합니다.

 

그리고 `docker image history sample-app` 명령으로 `sample-app` 이미지의 레이어를 확인할 수 있습니다.

$ docker container commit -c "CMD node app.js" -m "Add app" app-container sample-app
sha256:60ca05abe134aefaec270934f45c7161afde72ec0b20357a278a76568498c536
$ docker image history sample-app
IMAGE          CREATED          CREATED BY                                       SIZE      COMMENT
60ca05abe134   30 seconds ago   /bin/bash                                        8.19kB    Add app
552cb16395e4   6 minutes ago    /bin/bash                                        156MB     Add node
c35e29c94501   2 months ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]             0B
<missing>      2 months ago     /bin/sh -c #(nop) ADD file:ddf1aa62235de6657…   87.6MB
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH      0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG RELEASE                   0B
$

 

이제 마지막으로, `sample-app` 이미지로 새 컨테이너를 시작합니다.

$ docker run sample-app
Hello from an app
$

 

예상한대로의 결과 "Hello from an app"이 잘 출력되는 것을 확인할 수 있습니다.