CMD, ENTRYPOINT, RUN에 대해 질문드립니다.

미해결질문
초록잎 프로필

안녕하세요.

도커를 활용하면서 궁금한 점이 생겨 질문드립니다.

이따금 간단히 코드를 실행하는 dockerfile을 보면,

어떤 경우는 CMD, 다른 경우는 RUN을 쓰고 ENTRYPOINT를 쓰는 곳도 있었습니다.

예를 들어 gcc 도커 이미지의 경우,

FROM gcc:7

COPY . /app

WORKDIR /app

RUN gcc -o app main.c

CMD ["./app"]

이런 식으로 RUN 다음 CMD를 적어 두는 경우도 있고,

파이선의 경우

FROM python:3

WORKDIR /app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD [ "python", "./your-daemon-or-script.py" ]

이렇게 CMD 구문만으로 실행하기도 합니다.

위 코드들 대신

CMD [ "gcc", "./main.c" ]

RUN python ./your-daemon-or-script.py

이런 식으로 써도 되는지, 어떤 경우에서는 CMD와 RUN은 구분되어 쓰여야 하는지 질문드리고 싶습니다.

* 도커는 쓰면 쓸수록 유용함을 느낍니다. 강의를 만들어주셔서 다시 한 번 감사드립니다.

손당근 프로필
손당근 3달 전

도커의 유용함을 느끼고 계신다니 축하드립니다. 😀

저 또한 CMD 와 RUN 의 쓰임새가 궁금한적이 있었는데요.

먼저 RUN 은 명령어를 실행하고 이미지에 새로운 레이어를 생성합니다. 이는 도커 이미지 용량 & 빌드 시간 최적화에 유용합니다.

강의에서 말씀드린대로 도커는 이미지는 레이어를 층층히 쌓아 올린 개념입니다. 이때 자주 사용되는 패키지를 RUN 명령어로 Dockerfile 에 선언 해두면 해당 패키지까지 설치한 레이어가 생기겠죠. 덕분에 같은 라이브러리를 사용하지만 다른 이미지를 빌드할때 해당 레이어를 가져와 이미지를 빌드할겁니다. 이는 레이어의 재사용성을 높여 이미지 사이즈와 빌드 시간을 줄여주겠죠.

반면 CMD 는 레이어와 아무 상관이 없습니다. 이는 도커가 실행(run) 될때 컨테이너 내부에서 기본적으로 실행하는 명령어를 선언 해두는 역할을 합니다. 질문에 작성해주신것 처럼 파이썬을 실행하거나, gcc 로 빌드한 바이너리 파일을 실행하는 일을 할 수 있겠죠.

여기서 중요한점은 우리가 CMD 명령어를 덮어쓰기(override) 가능 하다는 점인데요. 이를 위해서 docker run 명령어 인자 중에서 [command] 가 존재합니다.

docker run -d busybox echo hello world 이런 식으로 말이죠 :)

따라서 마지막에 RUN 과 CMD 명령어를 바꿔서 사용해도 괜찮냐고 하셨는데, 그건 우리가 작성할 Dockerfile 이 어떻게 작동하길 원하냐에 따라 달라질것 같습니다. 😀

가령 RUN python ./your-daemon-or-script.py 라는 명령어의 결과가 레이어로 캐시가 되고, 이미지를 빌드할때 "언제나" 실행되길 원한다면 RUN 명령어로 사용 하는식으로요.

제 답변이 도움이 됐으면 좋겠습니다.

지식공유자 되기
많은 사람들에게 배움의 기회를 주고,
경제적 보상을 받아보세요.
지식공유참여
기업 교육을 위한 인프런
“인프런 비즈니스” 를 통해 모든 팀원이 인프런의 강의들을
자유롭게 학습하는 환경을 제공하세요.
인프런 비즈니스