Docker에서 CMD와 ENTRYPOINT의 차이점 - 2020 - 다른 사람
Docker 컨테이너는 다양한 환경에서 소프트웨어 및 종속성을 관리할 때 표준이 되었습니다. 실제 애플리케이션으로 작업할 때 애플리케이션 컨테이너 이미지를 빌드하기 전에 도커 파일을 생성해야 합니다.
도커 파일은 이미지를 어셈블할 때 호출될 일련의 지침이 있는 읽기 전용 텍스트 문서입니다. 이러한 명령에는 RUN
, CMD
및 ENTRYPOINT
가 포함됩니다.
이 기사에서는 이러한 명령의 사용법에 대해 설명합니다. docker 학습의 초기 단계에 있는 대부분의 개발자는 이러한 명령을 서로 바꿔서 사용하는 경향이 있어 몇 가지 문제가 발생할 수 있습니다.
Docker의 CMD
명령
이 명령은 docker RUN
명령이 실행될 때마다 실행되는 명령을 지정합니다. 그러나 이를 위해서는 인수를 지정하지 않고 docker RUN
명령을 실행해야 합니다.
인수가 지정되면 이 명령이 무시됩니다. 반면에 명령줄 인수가 지정되지 않은 경우 CMD
명령이 실행됩니다.
ECHO
명령은 런타임에 동일한 용도로 사용될 수 있으므로 CMD
명령은 도커 컨테이너가 제대로 작동하는 데 필수가 아닙니다. 그러나 CMD
명령은 컨테이너가 시작될 때마다 실행 파일을 실행할 때 편리할 수 있습니다.
CMD
명령을 사용하여 런타임에 실행 파일을 실행하는 방법을 보여주기 위해 메시지를 출력하는 간단한 플라스크 프로그램으로 간단한 도커 컨테이너를 만듭니다. 이것은 Python이 아닌 모든 언어로 복제할 수 있습니다.
아래와 같이 간단해야 하는 기본 응용 프로그램을 만드는 것으로 시작하겠습니다.
from flask import Flask
app = Flask(__name__)
def hello():
print("Hello, this is a simple Flask application")
hello()
동일한 폴더 내에서 touch Dockerfile
명령을 사용하여 Dockerfile을 생성합니다.
Dockerfile은 기본 이미지, 작업 디렉터리 및 설치해야 하는 패키지만 지정합니다.
마지막 줄에서 CMD
명령을 확인해야 합니다. 이 경우 컨테이너가 시작될 때 CMD
명령을 사용하여 app.py
파일을 실행합니다.
# base image
FROM python
# Set your working directory
WORKDIR /var/www/
# Copy the necessary files
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt
# Install the necessary packages
RUN pip install -r /var/www/requirements.txt
# Run the app
CMD python3 app.py
requirements.txt
는 아래와 같이 표시되어야 합니다.
click==8.0.4
Flask==2.0.3
gunicorn==20.1.0
itsdangerous==2.1.0
Jinja2==3.0.3
MarkupSafe==2.1.0
Werkzeug==2.0.3
이제 모든 것이 준비되었으므로 도커 이미지를 빌드할 수 있습니다. 그 전에 프로그램이 저장된 동일한 폴더에 있는지 확인해야 합니다.
우리의 경우 아래와 같이 이미지를 빌드하기 전에 cd
를 my-app
폴더로 이동합니다.
~/my-app$ docker build -t isaactonyloi_image .
출력:
=> [internal] load build context 0.9s
=> => transferring context: 320B 0.1s
=> [2/5] WORKDIR /var/www/ 5.1s
=> [3/5] COPY ./app.py /var/www/app.py 3.2s
=> [4/5] COPY ./requirements.txt /var/www/requirements.txt 3.2s
=> [5/5] RUN pip install -r /var/www/requirements.txt 53.9s
=> exporting to image 6.9s
=> => exporting layers 5.8s
=> => writing image sha256:5847e4777754d9d576accd929076bfbee633ca71f049ebe1af6e9bae161f3e96 0.1s
=> => naming to docker.io/library/isaactonyloi_image 0.2s
isaac@DESKTOP-HV44HT6:~/my-app$
이전 도커 파일을 기반으로 이미지를 성공적으로 빌드했습니다. 아래에서 확인할 수 있습니다.
~/my-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
isaactonyloi_image latest 5847e4777754 7 minutes ago 929MB
이 이미지를 기반으로 docker run
명령을 사용하여 마침내 도커 컨테이너를 만들 수 있습니다. 또한 CMD
명령을 실행하기 위해 인수를 전달하지 않고 이 작업을 수행합니다.
~/my-app$ docker run isaactonyloi_image
Hello, this is a simple Flask application
이 외에도 CMD
명령을 사용하면 런타임에 쉽게 무시할 수 있는 인수를 만들 수도 있습니다.
아래 예에서 CMD
명령을 변경했습니다. 다른 파일은 그대로 유지되며 새 이미지를 다시 작성했습니다.
# base image
FROM python
# Set your working directory
WORKDIR /var/www/
# Copy the necessary filesls
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt
# Install the necessary packages
RUN pip install -r /var/www/requirements.txt
# Run the app
CMD ["echo", "Hello, Developer"]
다음은 Dockerfile에 대한 변경 사항에서 다시 빌드한 새 이미지입니다.
~/my-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
new_image latest 73f323be0d2f 25 minutes ago 929MB
인수를 전달하지 않고 새 도커 컨테이너를 다시 만들 때 CMD
명령 아래에 메시지가 표시되어야 합니다.
isaac@DESKTOP-HV44HT6:~/my-app$ docker run new_image
Hello, Developer
그러나 CMD
명령은 런타임에 인수를 전달할 때 자동으로 무시되며 새 인수가 우선해야 합니다. 따라서 아래와 같이 런타임에 새 인수를 추가할 수 있는 유연성을 제공합니다.
~/my-app$ docker run new_image hostname
da0a832888cb
위의 출력은 CMD
명령이 실행되지 않고 새 호스트 이름 인수로 재정의되었음을 보여줍니다.
Docker의 ENTRYPOINT
명령
docker ENTRYPOINT
명령은 CMD
명령과 유사하지만 완전히 동일하지는 않습니다.
CMD
명령을 사용할 때 런타임에 인수를 전달하여 이를 쉽게 무시할 수 있지만 ENTRYPOINT
명령의 경우는 그렇지 않습니다.
따라서 ENTRYPOINT
를 사용하여 런타임에 진입점 명령을 무시하지 않을 수 있습니다.
아래와 같이 Dockerfile에서 CMD
명령을 ENTRYPOINT
명령으로 간단히 교체하여 이 명령의 작동 방식을 탐색할 수 있습니다. 도커 파일에 대한 변경 사항을 기반으로 새 이미지를 빌드합니다.
isaac@DESKTOP-HV44HT6:~/my-app$ docker build -t tonyloi_newimage .
[+] Building 42.7s (10/10) FINISHED
출력:
=> [internal] load build definition from Dockerfile 2.0s
=> => transferring dockerfile: 365B 0.7s
=> [internal] load .dockerignore 1.6s
=> => transferring context: 2B 0.4s
=> [internal] load metadata for docker.io/library/python:latest 35.4s
=> [1/5] FROM docker.io/library/python@sha256:c90e15c86e2ebe71244a2a51bc7f094554422c159ce309a6faadb6debd5a6df0 0.3s
=> [internal] load build context 1.2s
=> => transferring context: 63B 0.1s
=> CACHED [2/5] WORKDIR /var/www/ 0.0s
=> CACHED [3/5] COPY ./app.py /var/www/app.py 0.0s
=> CACHED [4/5] COPY ./requirements.txt /var/www/requirements.txt 0.0s
=> CACHED [5/5] RUN pip install -r /var/www/requirements.txt 0.0s
=> exporting to image 2.1s
=> => exporting layers 0.0s
=> => writing image sha256:15fb8e4e3ff58ed529b11342bba75b029fd4323beb24aac70ca36b178d04cb34 0.2s
=> => naming to docker.io/library/tonyloi_newimage 0.1s
isaac@DESKTOP-HV44HT6:~/my-app$
이 출력은 새 이미지를 성공적으로 구축했다는 증거입니다. 이제 이 이미지를 기반으로 새 도커 컨테이너를 만들 수 있습니다.
docker images
명령을 사용하여 액세스할 수 있는 이미지 이름 또는 이미지 ID를 사용하여 컨테이너를 생성하도록 선택할 수 있습니다. 이것은 또한 우리가 이전에 만든 이미지를 표시합니다.
~/my-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tonyloi_newimage latest 15fb8e4e3ff5 48 minutes ago 929MB
new_image latest 73f323be0d2f 48 minutes ago 929MB
isaactonyloi_image latest 5847e4777754 48 minutes ago 929MB
인수를 추가하지 않고 도커 컨테이너를 빌드하면 아래와 같은 출력이 표시되어야 합니다.
isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage
Hello, Developer
이 이미지를 기반으로 다른 컨테이너를 생성할 때 인수를 전달하려고 하면 CMD
명령의 경우와 달리 이러한 새 인수는 ENTRYPOINT
명령을 무시하지 않습니다.
아래에서 확인할 수 있습니다.
isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage Welcome to ADC
Hello, Developer Welcome to ADC
결론
우리는 이 두 명령이 매우 유사하다고 말할 수 있습니다. 그러나 차이점은 CMD
명령은 런타임에 재정의될 수 있지만 ENTRYPOINT
명령은 재정의할 수 없다는 것입니다.
또한 상황에 따라 두 명령을 동시에 사용해야 할 수도 있습니다.
Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.
LinkedIn