본문 바로가기

Linux/Docker

Dockerfile의 CMD와 ENTRYPOINT 차이. docker-compose.yml의 command

인트로

Docker를 처음 배우면서 Dockerfile을 작성할 때 CMDENTRYPOINT의 차이점을 잘 몰랐다. 사실은 Entry가 참가자 명단 뭐 그런 뜻이라는데 나는 뭔가 입구같은 느낌을 받아서, ContainerWorking Directory를 지정하는 WORKDIR과 혼동을 했다. 그래서 학교 시험문제도 틀렸었다.

근데 이번에 아는 분의 README.md를 읽어보다가 docker-compose.ymlcommand 와 관련해서도 한 번 개념을 집고 넘어가면 좋을 것 같아 정리해본다.

 

간단하게 봤을 때 CMDENTRYPOINT의 차이 ( Dockerfile에서 )

공통점은 우선 CMDENTRYPOINT 모두 해당 Dockerfile을 이용해 생성된 Image를 바탕으로 Containerrun할 때 실행되는 명령어쪽에 속한다.

하지만 차이점

ENTRYPOINT는 어떤 경우에든 Container가 run될 때 해당 값을 인자로서 실행하고

CMD는 만약 Container run 시에 다른 인자가 전달된다면 CMD의 인자는 생략된다. 쉽게 말해 Default Arguments같은 느낌.

 

CMD 예시

좀 더 눈에 보이는 예시로 통해 쉽게 정리해보겠다.

나는 아래의 Dockerfile을 가지고 cmd_entry라는 이미지를 빌드했고 run시켰다

(   도커파일이 속한 위치에서 그 Dockerfile을 바탕으로 Image를 build하는 Command는

 docker build . -t {tag_name}    )

 

# test.py - Dockerfile에서 사용됨. 전달받은 인자를 출력하는 python file

1
2
3
4
5
6
7
import sys
 
if len(sys.argv) == 1:
    print("No Args!")
else:
    for i in range(1len(sys.argv)):
        print(i, ":", sys.argv[i])
cs

 

그럼 위와 같이 container가 run 될 때 일반적으로 터미널에서  python test.py thisiscmd  라고 입력한 것과 같은 결과를 얻을 수 있다.

 

ENTRYPOINT와 CMD 를 섞어서

위와 같이 ENTRYPOINTCMD를 섞어서 써도 마찬가지로 두 녀석 모두 Container가 run 될 때 전달되는 인자이므로 정상적으로 작동한다. ( 내가 run 시에 추가로 인자를 전달하지 않는다면!)

 

docker-compose란?

Docker Compose는 한 번에 여러 개의 container을 실행할 수 있도록 해주는 소프트웨어입니다. 여러개의 컨테이너를 바탕으로 실행되는 앱의 경우 docker-compose를 이용할 수 있습니다. 예를 들어 DB Container, Web Container, Backend Container 등등 이 필요할 때 하나 하나를 run 시키는 게 아니라 docker-compose 를 이용함으로써 하나의 앱처럼 일괄적으로 run하고 stop이 가능하죠.

 

그러기 위해선 어떠한 식으로 container들을 설정할 지에 대한 설정이 필요하고 이를 기본적으로는 docker-compose.yml에 담습니다. 쉽게 생각하자면 docker run 어쩌구 저쩌구 하면서 전달시킬 설정들을 한 번에 docker-compose.yml에 적는 겁니다.

그리고 docker-compose up 하나면 끝! ( stop은 docker-compose down )

이 때에는 python에 python file name 말고 추가로 전달된 인자가 "thisisdocker-compose" 하나라고 Ouput이 프린트되었는데요.

전 방금 전 소스와 같은 아래의 Dockerfile을 이용했었습니다.

결론, 정리

따라서 docker-compose.yml 에서의 commandDockerfileCMD의 내용이 없다면 DockerfileCMD 로서의 역할을 하기도 하고, 만약 원래 DockerfileCMD 의 내용이 존재했다면, 그것을 Override한다는 것을 알 수 있습니다.

그리고 ENTRYPOINTCMDcommand든 관련없이 인자가 주어지던 어쩌든 무조건 실행되는 인자라고 정리할 수 있겠습니다.