Docker에서 CMD와 ENTRYPOINT의 차이점 - 2020 - 다른 사람

Isaac Tony 2023년1월30일
  1. Docker의 CMD 명령
  2. Docker의 ENTRYPOINT 명령
  3. 결론
Docker에서 CMD와 ENTRYPOINT의 차이점 - 2020 - 다른 사람

Docker 컨테이너는 다양한 환경에서 소프트웨어 및 종속성을 관리할 때 표준이 되었습니다. 실제 애플리케이션으로 작업할 때 애플리케이션 컨테이너 이미지를 빌드하기 전에 도커 파일을 생성해야 합니다.

도커 파일은 이미지를 어셈블할 때 호출될 일련의 지침이 있는 읽기 전용 텍스트 문서입니다. 이러한 명령에는 RUN, CMDENTRYPOINT가 포함됩니다.

이 기사에서는 이러한 명령의 사용법에 대해 설명합니다. 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

이제 모든 것이 준비되었으므로 도커 이미지를 빌드할 수 있습니다. 그 전에 프로그램이 저장된 동일한 폴더에 있는지 확인해야 합니다.

우리의 경우 아래와 같이 이미지를 빌드하기 전에 cdmy-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
Isaac Tony avatar Isaac Tony avatar

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

관련 문장 - Docker Command