Dockerfile ENTRYPOINT 및 CMD 명령 사용하는 방법

만약 이전에 도커 컨테이너에서 시작 시 명령을 실행해야 했다면, 이 튜토리얼이 도움이 될 것입니다. Dockerfile, ENTRYPOINTCMD 지시문을 사용하여 시작 명령을 여러 개 실행할 수 있습니다.

이 튜토리얼에서는 ENTRYPOINTCMD 지시문을 사용하여 Dockerfile에서 시작 명령을 실행하고 그 차이를 이해하는 방법을 배우게 됩니다.

준비 사항

이 튜토리얼은 실습을 포함하므로 다음이 준비되어 있는지 확인하십시오:

  • A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
  • Docker Desktop – 이 튜토리얼은 Docker Desktop v3.3.1을 사용합니다.

Dockerfile 만들기

Docker 컨테이너 시작 명령을 실행하기 전에 먼저 Dockerfile을 만들어야 합니다. Dockerfile은 컨테이너를 빌드하는 데 사용되는 명령 목록과 Docker 이미지를 만드는 방법을 결정하는 텍스트 문서입니다.

1. 먼저 관리자 권한으로 PowerShell을 엽니다.

2. 이 튜토리얼에서 사용할 Dockerfile 및 모든 관련 파일을 저장할 새 폴더를 만들고 해당 디렉터리로 이동하세요. 이 튜토리얼은 ~/docker를 사용합니다.

mkdir ~/docker
cd docker

3. 이제 다음 명령으로 Dockerfile이라는 빈 텍스트 파일을 만듭니다.

cd > Dockerfile

또는 Linux 또는 Mac OS에서이면 다음 명령으로 Dockerfile을 만들 수 있습니다.

touch Dockerfile

4. 마지막으로 Dockerfile에 다음 내용을 추가하세요.

FROM ubuntu:20.04

이제 곧 Dockerfile을 만들었습니다!

Docker 이미지 빌드

Dockerfile을 만들었으므로 Dockerfile ENTRYPOINT 및 CMD 지시문에서 작성된 명령을 실행할 Docker 이미지를 빌드해야합니다. 이미지를 빌드하는 한 가지 방법은 build 명령어를 사용하는 것입니다.

~/docker 디렉토리에서 다음 명령을 실행합니다. 아래 명령은 현재 작업 디렉토리를 지정하여 demo라는 Docker 이미지를 만듭니다 (-t demo), ~/docker의 Dockerfile에서.

docker build -t demo .
Building a Docker Image

Docker 컨테이너 실행

Docker 이미지를 빌드한 후 Docker 이미지를 실행할 컨테이너가 필요합니다. 이 컨테이너는 Dockerfile ENTRYPOINT 및 CMD 지시문에서 명령을 실행할 것입니다.

도커 컨테이너를 실행하려면 run 명령어를 호출하여 도커 이미지(demo) 위에 쓰기 가능한 컨테이너 레이어를 생성합니다. 아래 예제는 -it 매개변수를 사용하여 컨테이너에 대화형으로 연결하여 샘플 출력을 볼 수 있습니다.

docker run -it demo
Running a Docker Container

Exec vs. Shell Form

도커 파일(Dockerfile)을 작성하고 시작 업무 명령어를 실행하는 방법을 알아볼 때 두 가지 다른 방법을 만날 수 있습니다. 각 방법은 명령어를 호출하지만 약간 다른 방식으로 수행합니다.

도커가 명령어를 실행할 때, exec로 직접 호출하거나 컨테이너의 셸(/bin/sh -c 리눅스 또는 cmd /S /C 윈도우즈에서)을 통해 호출할 수 있습니다. 이를 shell이라고 합니다.

exec를 통해 실행되는 명령어는 아래에 나와 있는 것처럼 명령 후 실행 파일 다음에 하나 이상의 명령행 인수가 따릅니다.

ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]

반면 shell 형식으로 명령어를 작성할 때는 명령어를 대괄호로 묶는 것이 필요하지 않습니다. 아래에 나와 있습니다.

ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"

CMD에 매개변수를 지정하지 않으면 도커는 항상 exec 형식으로 명령을 실행합니다. 예: CMD <command>.

처음 시작할 때는 이 두 명령 호출을 구별하는 것이 큰 차이를 만들지 않겠지만, 더 많은 경험을 쌓게 되면 각각의 장단점을 빨리 깨닫게 될 것입니다.

시작 업무 명령어 실행

이제 튜토리얼의 본질에 대해 들어가서 Dockerfile ENTRYPOINT와 CMD 명령어를 실행하는 몇 가지 예시를 통해 실습해 봅시다.

1. 이전에 생성한 Dockerfile을 원하는 텍스트 편집기에서 엽니다.

2. 아래에 표시된 대로 예시 Dockerfile 내용을 Dockerfile에 복사하여 붙여넣고 저장합니다.

이 Dockerfile은 ubuntu:20.04를 기본 이미지로 사용하여 레이어를 만듭니다. 그런 다음 Docker에게 execshell 형식을 사용하여 Dockerfile CMDENTRYPOINT 명령어에 각각 Hello world 인수를 전달하도록 지시합니다.

FROM ubuntu:20.04
# CMD 명령어
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world"      # Shell Form
# ENTRYPOINT 명령어
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world"      # Shell Form

3. ~/docker 디렉토리에서 docker build 명령어를 실행하여 새 이미지를 빌드하고 demo라고 이름을 지정합니다. 아래 명령어는 이미지를 demo로 태그하고 현재 작업 디렉토리(.)에서 Dockerfile을 찾습니다.

docker build -t demo .
Building a Docker image with docker build

4. 이제 이미지를 사용하여 컨테이너를 실행한 다음 이전에 생성한 Docker 이미지를 기반으로 Docker 컨테이너를 실행합니다. 이제 컨테이너가 Dockerfile에서 제공된 CMD 명령어에서 가져온 Hello world를 반환하는 것을 볼 수 있습니다.

docker run -it demo
Running a Docker container with docker run

Dockerfile에서 변수 사용

가끔은 명령어를 미리 알지 못할 수도 있습니다. 명령에 전달해야 할 인수는 실행 시에만 노출됩니다. 명령 인수를 정적으로 할당하는 대신에 변수를 사용하여 해당 인수를 캡처하고 명령에 전달할 수 있습니다.

도커 파일 변수는 shell 형식에서만 사용할 수 있습니다. 도커는 exec 형식을 통해 호출된 명령에서 변수를 지원하지 않습니다.

선호하는 텍스트 편집기에서 도커 파일을 열고, 내용을 다음 명령어 시리즈로 대체한 후 저장하세요.

이번에는 환경 변수를 사용하고 ENV를 통해 표시됨을 알 수 있습니다. 아래 예시에서는 도커 파일이 name이라는 환경 변수를 값 friend로 정의하고 있습니다. 이 환경 변수는 $name을 통해 참조됩니다.

이 Dockerfile을 기반으로 컨테이너를 실행할 때, Docker는 echo 명령을 호출하고 Welcome, friend라는 인수를 전달할 것입니다.

FROM ubuntu:20.04
ENV name friend

CMD echo "Welcome, $name"
# 또는
## ENTRYPOINT echo "Welcome, $name"

이제 도커 이미지를 만들고 컨테이너를 다시 실행하고 선택적으로 shellform 태그 이름을 제공하세요. Docker가 echo 명령을 호출하고 예상 출력을 반환하는 것을 알 수 있을 것입니다.

Building a Docker Image (shellform) and Running a Docker Container

도커 파일 ENTRYPOINT 및 CMD 지시문 결합

많은 경우에는 CMD 또는 ENTRYPOINT 명령을 호출하게 될 것입니다. 결국 각 방법을 사용하여 원하는 만큼 많은 명령을 호출할 수 있습니다. 그러나 단일 명령을 호출하고 양쪽 지침을 사용하여 “추가 작성”할 수도 있습니다.

이전 예시를 기반으로 하면 아래 예시처럼 보이는 Dockerfile이 있을 수 있습니다. 현재로서 이미지를 만들고 해당 이미지에서 컨테이너를 실행하면 Docker는 echo 명령을 호출하고 Hello를 반환할 것입니다.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]

아마도 echo 명령에 전달하고 싶지만 즉시 전달하고 싶지는 않은 다른 인수가 있을 수 있습니다. 아마도 Dockerfile의 뒷부분에서 그렇게 하고 싶을 것입니다. 명령이없이 CMD 지침을 호출하면 그렇게 할 수 있습니다.

ENTRYPOINT 지침을 통해 실행할 명령을 지정할 때 CMD 지침을 사용하면 Docker는 자동으로 CMD에 전달된 값을 명령이 아닌 인수로 간주합니다.

이제 다음과 같이 명령이 아닌 인수인 world라는 이름의 CMD 지침 참조를 추가합니다.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]

지침을 결합할 때는 항상 exec 형태로 작성해야 하며 이는 값이 쉼표로 구분된 배열처럼 개별적으로 지정되는 “배열과 유사한” 동작을 하기 때문입니다.

이미지를 빌드하고 해당 이미지에서 컨테이너를 실행한 후 두 줄의 출력(Helloworld) 대신 Docker는 하나의 출력만 반환하는 것을 볼 수 있습니다. 즉, 단일 echo 명령 호출만이 있습니다.

Building a Docker Image (demo3) and Running a Docker Container

결론

당신은 이제 Docker 컨테이너 시작 명령어를 CMDENTRYPOINT Dockerfile 지시문을 통해 잘 이해했을 것입니다. 각 지시문은 약간 다르지만 동일한 작업을 수행하며 때로는 함께 사용될 수도 있습니다.

CMD 대신 ENTRYPOINT를 사용하여 시작 명령을 실행하는 상황을 고려할 수 있는 예시가 있을까요?

Source:
https://adamtheautomator.com/dockerfile-entrypoint/