본문 바로가기

About/Docker

[Docker] Dockerfile RUN 사용방법

다음 도서를 참고하여 작성하였습니다.

www.aladin.co.kr/shop/wproduct.aspx?ItemId=166082298

 

완벽한 IT 인프라 구축을 위한 Docker

컨테이너 기술을 사용한 애플리케이션 실행 환경 플랫폼인 ‘Docker’를 사용하여 인프라를 구축하기 위한 입문서. 제2판에서는 Docker의 새로운 기능 및 명령과 더불어, 멀티호스트 환경에서 실행

www.aladin.co.kr

 

Dockerfile에서 명령을 실행할 때는 RUN 명령어를 사용합니다. Dockerfile을 작성할 때는 이 RUN 명령어를 가장 많이 사용합니다.

RUN 명령으로 지정한 명령은 Docker 이미지를 생성할 때 실행됩니다.(RUN은 이미지를 작성하기 위한 명령어!)

 

RUN 명령에는 다음 두 가지 기술 방법이 있습니다.

1. Shell 형식으로 기술

 명령어 지정을 쉘에서 실행하는 형식으로 기술하는 방법입니다. 예를 들어 apt를 사용하여 Nginx를 설치할 때는 다음과 같이 기술합니다.

# Nginx 설치
RUN apt-get install -y nginx

 Docker 컨테이너 안에서 /bin/sh -c를 사용하여 명령을 실행했을 때와 똑같이 작동합니다. Docker 컨테이너에서 실행할 기본 쉘을 변경하고 싶을 때는 SHELL 명령을 사용합니다.

 

2. Exec 형식으로 기술

 Shell 형식으로 명령을 기술하면 /bin/sh에서 실행되지만, Exec 형식으로 기술하면 쉘을 경유하지 않고 직접 실행합니다. 따라서 명령 인수에 $HOME과 같은 환경변수를 지정할 수 없습니다. Exec 형식에서는 실행하고 싶은 명령을 JSON 배열로 지정합니다.

 

 다른 쉘을 이용하고 싶을 때는 RUN 명령에 쉘의 경로를 지정한 후 실행하고 싶은 명령을 지정합니다. /bin/bash에서 apt를 사용하여 Nginx를 설치할 때는 다음과 같이 기술합니다.

 

# Nginx 설치
RUN ["/bin/bash", "-c", "apt-get install -y nginx"]

 

문자열을 인수로 지정할 때는 '(홑따옴표)를 사용합니다.

 


RUN 명령의 실행 예시(Dockerfile)입니다.

#Dockerfile

# 베이스 이미지 설정
FROM ubuntu:latest

# RUN 실행
RUN echo 안녕하세요 Shell 형식 입니다.
RUN ["echo", " 안녕하세요 Exec 형식입니다. "]
RUN ["/bin/bash", "-c", "echo '안녕하세요 Shell 형식에서 /bin/bash를 사용한 형식입니다.' "]

 

RUN 명령은 기술된 내용을 순차적으로 실행합니다. dockerfile을 build하면 다음과 같은 로그가 출력됩니다.

 

docker build -t run-sample .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM ubuntu:latest
latest: Pulling from library/ubuntu
345e3491a907: Pull complete
57671312ef6f: Pull complete
5e9250ddb7d0: Pull complete
Digest: sha256:cf31af331f38d1d7158470e095b132acd126a7180a54f263d386da88eb681d93
Status: Downloaded newer image for ubuntu:latest
 ---> 7e0aa2d69a15
Step 2/4 : RUN echo 안녕하세요 Shell 형식 입니다.
 ---> Running in a5946b7c8dd8
안녕하세요 Shell 형식 입니다.
Removing intermediate container a5946b7c8dd8
 ---> 34e48fe99c3f
Step 3/4 : RUN ["echo", " 안녕하세요 Exec 형식입니다. "]
 ---> Running in 4e829c52cd3b
 안녕하세요 Exec 형식입니다.
Removing intermediate container 4e829c52cd3b
 ---> fee63c7332df
Step 4/4 : RUN ["/bin/bash", "-c", "echo '안녕하세요 Shell 형식에서 /bin/bash를 사용한 형식입니다.' "]
 ---> Running in 9f420cc7ca71
안녕하세요 Shell 형식에서 /bin/bash를 사용한 형식입니다.
Removing intermediate container 9f420cc7ca71
 ---> d512acc9a791
Successfully built d512acc9a791
Successfully tagged run-sample:latest

 

출력 결과를 확인하면 Step이라고 출력되는 부분에서 Dockerfile에 기술한 명령이 한 줄씩 실행되는 것을 알 수 있습니다. 

Dockerfile은 이 명령 한 줄 마다 이미지를  하나 생성합니다.

 

 이미지를 생성할 때 어떤 명령이 실행되는 지를 확인하기 위해 docker history 명령어로 확인해보겠습니다.

 

docker history run-sample
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
d512acc9a791        2 minutes ago       /bin/bash -c echo 안녕하세요 Shell 형식에서…           0B
fee63c7332df        2 minutes ago       echo  안녕하세요 Exec 형식입니다.                         0B
34e48fe99c3f        2 minutes ago       /bin/sh -c echo 안녕하세요 Shell 형식 입니다.             0B
7e0aa2d69a15        12 days ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
~중략~

 

실행결과를 확인하면 Shell 형식으로 기술한 RUN 명령은 /bin/bash, Exec 형식으로 기술한 RUN 명령은 쉘을 통하지 않고 실행되는 것 알 수 있습니다. 또한 쉘을 명시적으로 지정하고 싶을 때는 Exec 형식을 사용하면 /bin/bash를 사용하여 명령이 실행되는 것을 알 수 있습니다.

 

따라서 /bin/sh(/bin/bash)를 경유하여 명령을 실행하고 싶을 때는 Shell 형식으로 기술하고, 그 외의 경우에는 Exec 형식으로 기술하는 것이 좋습니다.


Dockerfile의 RUN 명령어에 대하여 다루어 봤습니다.