반응형

2편 (ONBUILD, STOPSIGNAL, HEATHCHECK) : https://nirsa.tistory.com/68?category=868315

3편 (COPY, ADD, ENV, ARG, WORKDIR) https://nirsa.tistory.com/69?category=868315

4편 (USER, LABEL, EXPOSE, VOLUME) : https://nirsa.tistory.com/70?category=868315

 

  • 들어가기전에...

Dockerfile과 같은 디렉터리에 있는 모든 파일들을 컨텍스트(context)라고 합니다. docker build 를 사용하여 이미지를 생성할 때 컨텍스트 모두를 Docker 데몬에 전송하기 때문에 / 디렉토리에 Dockerfile을 생성하던가 하면 시스템 처리 속도가 굉장히 느려질 수 있습니다. 

때문에 Dockerfile은 따로 디렉토리를 새로 생성하는것으로 권장 됩니다.

컨텍스트에서 파일이나 디렉토리를 제외할때 Dockerfile 과 같은 경로에 .dockerignore 파일을 생성하여 제외하고싶은 파일이나 디렉토리를 지정해줄 수 있으며 아래는 예시 입니다.

Hello, world.txt
*.log
.git

 

  • 1. RUN

RUN 명령은 아래 예시처럼 패키지 설치 등에 사용 되는건데, 좀 더 특정지어 말한다면 RUN 명령은 image layer를 만들어냅니다. (image layer는 https://nirsa.tistory.com/63?category=868315 참고)

 

/bin/sh 또는 exec 형식으로 작성할 수 있는데 exec 형식은 JSON배열로 지정 됩니다.

FROM centos:7

# nignx 설치 (/bin/sh 예시)
# RUN yum -y install nginx

# nignx 설치 (exec 형식 예시)
# RUN ["/bin/bash", "-c", "yum -y install nginx"]

 

기본적으로 /bin/sh -c 를 통해 실행되기 때문에 yum -y install nginx만 써도 정상적으로 실행 되었습니다.

이미지에 /bin/sh가 없을 경우 exec 형식을 사용하면 되고, 쉘을 경유하지 않고 직접 실행되기 때문에 환경 변수 등 지정할 수 없습니다.

 

* RUN 명령은 되도록 한줄로 작성하는것이 좋습니다. 위에서 말햇듯이 RUN 명령은 image layer를 생성해나가는 과정이기 때문에 같은 결과를 가져오더라도 RUN을 여러줄로 작성하면 image layer가 여러개 생성되고, RUN을 한줄로 작성하면 image layer가 1개로 생성 됩니다. 

FROM centos:7

RUN yum -y install httpd
RUN yum -y install php
RUN yum -y install mysql

 

FROM centos:7

RUN yum -y install httpd php mysqld

 

  • 2. CMD, ENTRYPOINT

CMD와 ENTRYPOINT 명령은 두 개를 비교 해가며 보는게 좀 더 이해하기 편합니다.

일단 두가지의 명령 모두 이미지를 바탕으로 생성된 컨테이너에서 사용 됩니다. (docker run로 생성/실행 또는 docker start으로 실행 시)

 

centos 7버전을 베이스로 하고 nginx를 설치 하였습니다. 그럼 nginx를 실행 시켜줘야겠죠? 그럴때 쓰는것이 CMD 또는 ENTRYPOINT 입니다.

실서버에 centos 7을 깔고, nginx를 설치 한 후 systemctl start nginx 를 입력해주는것과 같습니다.

FROM centos:7

RUN touch /etc/yum.repos.d/nginx.repo && echo -e '[nginx]\nname=nage repo\nbaseurl=http://nginx.org/packages/centos/7/$basearch/\ngpgcheck=0\nenabled=1' > /etc/yum.repos.d/nginx.repo

RUN yum -y install nginx

# nginx foreground 실행
CMD ["nginx", "-g", "daemon off;"]

 

CMD와 ENTRYPOINT의 차이는 docker run 을 사용하며 새로운 명령을 지정한 경우 이 명령이 실행 되는지, 안되는지의 차이 입니다.

CMD : 컨테이너가 실행될 때 명령어 및 인자값 전달하여 실행, 단 docker run 명령에 쉘 명령어 및 인자값 전달할 경우 CMD에 작성된 명령어와 인자값은 무시 됩니다. (다른 명령어와 인자값을 사용한 예는 아래 이미지 확인)

즉, 우선 순위는 docker run > CMD

FROM centos:7

CMD ["/bin/ls", "-lh", "/root"]

 

ENTRYPOINT : 컨테이너가 실행될 때 명령어 및 인자값 전달하여 실행, 단 docker run 명령에 쉘 명령어 및 인자값 전달할 경우 쉘 명령어는 영향을 받지 않으며, 인자값만 영향을 받습니다.

즉, 우선 순위는 ENTRYPOINT (인자값) < docker run < ENTRYPOINT (명령어)

 

1. docker container run -it ent_hw 를 입력했을 땐 그대로 ls -lh /root 의 결과값이 나옵니다.

2. docker container run -it ent_hw ls -la 를 입력했을 땐 그대로 ls -la /root 의 결과값이 나옵니다. (인자값만 수정한 경우)

3. docker container run -it ent_hw ps -ef 를 입력했을 땐 에러가 발생 합니다. (명령어까지 수정한 경우)

FROM centos:7

ENTRYPOINT ["/bin/ls", "-lh", "/root"]

 

ENTRYPOINT는 conatiner run의 --entrypoint="실행명령" 옵션을 사용하여 Dockerfile에 정의한 ENTRYPOINT를 무시할 수 있습니다.

아래는 --entrypoint 옵션을 사용하여 ent_hw 이미지를 생성 및 실행하며 cat /etc/hosts 를 수행 합니다.

FROM centos:7

ENTRYPOINT ["/bin/ls", "-lh", "/root"]

 

  • 3. CMD, ENTRYPOINT 정리

CMD는 명령과 인자값이 변경될 수 있고, 컨테이너에서 명령 설정하지 않을 시 CMD에 기재된 명령을 기본값으로 실행됩니다. ENTRYPOINT는 명령 수정이 불가능하여 사용자에 의해 변경되지 않고 고정적으로 실행될 명령은 ENTRYPOINT를 사용하는것이 좋습니다.

 

 

 

반응형

+ Recent posts