Docker 명령어 RUN / CMD / Entry Point의 차이점에 대해서

2018. 5. 31. 14:30개발을 파헤치다/서버 인프라

반응형

RUN / CMD / Entry Point 차이점


RUN


  • RUN 명령어를 사용하면 명령을 실행한 결과가 새로운 Layer로 저장됩니다.
    그리고 이 Layer는 베이스 이미지에 추가됩니다.
    RUN 명령어는 주로 새로운 패키지를 설치하거나 소스를 받아서 빌드한 경우 사용됩니다.

Docker는 Container를 실행할 때 Docker Image가 필요합니다.

이 Image는 이미 존재하는 다른 Docker Image나 배포된 OS를 기반으로 만들어집니다.

베이스 이미지에 Docker 명령어를 가지고 자신에게 맞는 환경을 하나 하나 얹어가는 것입니다.

RUN 명령어를 사용하여 새로운 패키지가 설치하거나 새로운 명령을 실행하는 경우

베이스 이미지에 내용이 더해지는데 이것을 Layer가 더해진다고 표현합니다.

Layer는 Docker Image를 만드는 과정을 게임이라고 표현한다는 게임 중간 중간 Save Point를 만드는 것과 비슷합니다.

RUN으로 실행된 내용이 하나의 이미지로 만들어지는 것이죠.

만약, 다른 RUN 명령어에서 오류가 나서 빌드가 중단되어도 성공한 지점까지의 이미지가 빌드 완료된 상태이기 때문에

처음부터 다시 빌드되는 것이 아니라 오류가 난 지점부터 다시 빌드를 수행합니다.

아래의 예시는 Ubuntu 베이스 이미지에 Apache 웹서버를 설치하는 Dockerfile입니다.

FROM ubuntu
RUN apt-get update
RUN apt-get install -y apache2
RUN touch /home/test/config.txt

아래의 명령어로 빌드를 수행합니다.

$ docker build -t test_apache .


빌드가 완료된 뒤 history 명령어를 통해 빌드된 이미지들을 확인할 수 있습니다.

$ docker history test_apache

IMAGE CREATED CREATED BY SIZE COMMENT
e1198abcf6ac 8 seconds ago /bin/sh -c touch /opt/aboullaite.txt 0 B
ea693c852138 10 seconds ago /bin/sh -c apt-get install -y apache2 99.1 MB
c4448790b3b2 About a minute ago /bin/sh -c apt-get update 39.49 MB
2fa927b5cdd3 6 months ago /bin/sh -c #(nop) CMD ["/bin/bash"]

위처럼 RUN 명령을 수행할 때마다 중간 이미지들을 만들어 놓는 것을 확인할 수 있습니다.

이 중간 이미지는 Layer라는 이름으로 베이스 이미지에 한겹 한겹 덧붙여지게 됩니다.

CMD

  • CMD를 활용하면 Docker Container가 실행될 때 명령어 및 인자값들을 전달하여 실행할 수 있습니다.
    하지만 Docker run 명령어에 인자값을 전달하여 실행하면 CMD에 명시된 명령어와 인자값은 무시됩니다.


CMD는 Dockerfile에서 다음과 같이 선언될 수 있습니다.

CMD ["/bin/ls", "-al", "/home"]

그럼 CMD가 어떻게 동작하는지 간단한 예시로 알아보도록 합니다.

CMD ["echo", "Hello World"]

위의 명령어를 Dockerfile에 명시하고 run -it [docker_image]를 실행하면 아래와 같은 결과가 나타납니다.

Hello World

하지만 만약 Docker Container를 실행할 때 run -it [docker_image] /bin/bash를 실행하게 되면 결과는 다르게 나타납니다.

root@98e4bed87725:/# 

위와 같은 프롬프트가 나타나게 될 것입니다.

이유는 Container 실행시 전달된 명령(/bin/bash)가 기존 명령(CMD echo “Hello World”)대신 실행되기 때문입니다.

Entry Point

  • Entry Point는 얼핏 CMD와 비슷해 보일 수 있습니다.
    하지만 CMD와는 달리 Container 실행 시 run을 통해 명령어 및 인자값을 전달해도 기존의 명령이 실행됩니다.
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]

위의 Dockerfile로 Image를 빌드한 뒤, run -it [image]를 실행하면 아래와 같은 결과가 나타납니다.

hello world

하지만 인자값을 넣어서 다음과 같이 실행한다면 다른 결과가 나타나게 됩니다.

docker run -it [image] test_world

hello test_world

Entry Point로 명시한 인자값과 명령은 그대로 실행이 됩니다.

Entry Point를 사용하면 지정한 명령이 언제나 실행되기 때문에 특정 루틴을 실행해야 하는 Docker Container를 실행할 때 유용하게 사용할 수 있습니다.

예를 들면, Container를 시작하면 자동으로 Django Web Server가 특정 포트에 바인딩되어 실행되게 할 수 있습니다.

반응형