Dockerfile
은 Container를 생성하고, 생성하며 진행되어야 하는 일련의 작업들을 사전에 선언함으로써 등록된 작업이 실행된 후 Container를 배포 할 수 있는 파일입니다. Dockerfile은 Application 개발 외에도 Dockerfile을 이용한 Docker Hub 배포에도 사용 할 수 있습니다.
FROM
FROM 지시어로 베이스 이미지를 지정하여 레이어를 생성합니다. 지정된 이미지가 도커 호스트로 자동으로 pull down
됩니다.
Host or Docker Registry에 저장되어 있는 이미지만 지정이 가능합니다. FROM
지시어는 세가지 형식으로 사용됩니다.
- FROM IMAGE
- FROM IMAGE:TAG
- FROM IMAGE@DIGEST
RUN
베이스 이미지를 기반으로 패키지를 설치하거나 환경을 구성할 때 사용합니다. 두가지 사용 형식이 있지만, 결과적으로 보면 큰 차이는 없습니다.
/bin/sh -c 으로 실행하는 것과 동일하게 작동합니다.
RUN yum -y install httpd
쉘을 거치지 않고 바로 실행합니다. 따라서 환경 변수를 입력할 수 없고, JSON 형식으로 입력해야만 합니다.
RUN [ "/bin/bash", "-c", "yum -y install httpd" ]
CMD
빌드한 이미지로부터 컨테이너가 실행될 때 특정 프로세스나 데몬을 실행하기 위해 사용됩니다.
CMD 지시어를 여러번 사용할 경우, 마지막 지시어만 적용되므로 한번만 사용해야 합니다.
RUN과 마찬가지로 쉘 명령과 Exec 명령 두가지 형식으로 사용할 수 있습니다.
FROM centos RUN yum -y install httpd CMD /usr/sbin/httpd -D FOREGROUND
$ docker build -t centos:cmd . $ docker inspect centos-web:cmd [ { ... "ContainerConfig": { ... "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/bin/sh\" \"-c\" \"/usr/sbin/httpd -D FOREGROUND\"]" ], "Entrypoint": null }, "Config": { ... "Cmd": [ "/bin/sh", "-c", "/usr/sbin/httpd -D FOREGROUND" ], "Entrypoint": null } ...
ENTRYPOINT
빌드한 이미지로부터 컨테이너가 실행 될 때 프로세스나 데몬을 실행하기 위해 사용됩니다.
docker RUN 명령으로 실행되므로 CMD 지시어보다 우선순위가 높습니다. 쉘 명령과 Exec 명령 두가지 형식으로 사용할 수 있습니다.
./Dockerfile FROM centos:latest RUN yum -y install httpd ENTRYPOINT /usr/sbin/httpd -D FOREGROUND
$ docker build -t centos:entrypoint . $ docker inspect centos-web:entrypoint [ { ... "ContainerConfig": { ... "Cmd": [ "/bin/sh", "-c", "#(nop) ", "ENTRYPOINT [\"/bin/sh\" \"-c\" \"/usr/sbin/httpd -D FOREGROUND\"]" ], "Entrypoint": [ "/bin/sh", "-c", "/usr/sbin/httpd -D FOREGROUND" ] }, "Config": { ... "Cmd": null, "Entrypoint": [ "/bin/sh", "-c", "/usr/sbin/httpd -D FOREGROUND" ] }, ...
Entrypoint
설정이 추가된 것을 확인할 수 있습니다.
CMD 와는 달리 docker run에 지정한 명령어는 무시되고 ENTRYPOINT 지시어가 실행됩니다. 쉘로 접속하려면 docker exec 명령을 사용해야 합니다.
mysql 이미지의 경우 ENTRYPOINT docker-entrypoint.sh 지시어가 포함되어 이 스크립트에서 특정 환경변수를 검사하여 컨테이너를 실행합니다.
ONBUILD
베이스 이미지를 생성할 때 사용하는 지시어로 이미지를 빌드한 후 해당 이미지를 기반으로 다른 이미지를 빌드할 때 적용되는 지시어 입니다.
ONBUILD
명령어가 적용된 이미지로 컨테이너를 생성해도 컨테이너는 해당 명령어를 실행하지 않습니다.
해당 이미지를 베이스 이미지로 해서 다른 이미지를 빌드할때 명령어가 실행됩니다.
ONBUILD ADD
명령어는 도커 호스트의 파일을 컨테이너의 특정 디렉토리에 적용할 때 사용합니다.
FROM centos RUN yum -y install httpd ONBUILD ADD index.html /var/www/html CMD /usr/sbin/httpd -D FOREGROUND
FROM 지시어로 생성된 centos 레이어와 RUN 지시어로 생성된 레이어 두개만 나타납니다.
ONBUILD
로 지정된 ADD index.html /var/www/html 명령은 실행되지 않고 OnBuild 필드로 업데이트 된 것을 확인할 수 있습니다.
$ docker build -t centos:pre-onbuild . $ docker inspect centos-web:pre-onbuild [ { ... "ContainerConfig": { ... "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/bin/sh\" \"-c\" \"/usr/sbin/httpd -D FOREGROUND\"]" ], "OnBuild": [ "ADD index.html /var/www/html" ] }, "Config": { ... "Cmd": [ "/bin/sh", "-c", "/usr/sbin/httpd -D FOREGROUND" ], "OnBuild": [ "ADD index.html /var/www/html" ] }, "RootFS": { "Type": "layers", "Layers": [ "sha256:d69483a6face4499acb974449d1303591fcbb5cdce5420f36f8a6607bda11854", "sha256:f58e0e778d84a914c02385be57b7f0247b181f37b299579dd4d2e2fac9d9fa07" ] }, ... } ]
이번엔 ADD 명령어가 수행되어야 하므로 도커 호스트에 index.html 파일이 존재하여야 합니다.
OnBuild 필드가 null로 생성되고, ADD index.html /var/www/html 지시어가 적용된 레이어가 추가되었기 때문에 총 3개의 레이어가 나타나게 됩니다.
FROM centos:pre-onbuild RUN echo Test CMD /usr/sbin/httpd -D FOREGROUND
$ docker build -t centos-web:onbuild . $ docker inspect centos-web:onbuild [ { ... "ContainerConfig": { ... "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/bin/sh\" \"-c\" \"/usr/sbin/httpd -D FOREGROUND\"]" ], "OnBuild": null, ... }, "Config": { ... "Cmd": [ "/bin/sh", "-c", "/usr/sbin/httpd -D FOREGROUND" ], "OnBuild": null, ... }, "RootFS": { "Type": "layers", "Layers": [ "sha256:d69483a6face4499acb974449d1303591fcbb5cdce5420f36f8a6607bda11854", "sha256:f58e0e778d84a914c02385be57b7f0247b181f37b299579dd4d2e2fac9d9fa07", "sha256:d44e7018ea29cc14dedaf309240f573ae182c7141827478b0ab806e99697d339" ] }, ... } ]
VOLUME
도커 볼륨을 생성합니다.
VOLUME
지시어를 설정하면 해당 컨테이너 패스에 연결되는 디렉토리를 생성하고 마운트합니다.
FROM centos RUN mkdir -p /tmp/share VOLUME /tmp/share
$ docker build -t centos:volume . $ docker inspect centos:volume [ { ... "ContainerConfig": { ... "Volumes": { "/tmp/share": {} } }, "Config": { ... "Volumes": { "/tmp/share": {} } }, ... } ]
$ docker run -itd --name centos-volume centos:volume
$ docker inspect centos-volume [ { ... "Mounts": [ { "Type": "volume", "Name": "8fadb85943d78e953a16e643bc6ae1e5733419c8f8bb2d178cd0d45ba39f5217", "Source": "/var/lib/docker/volumes/8fadb85943d78e953a16e643bc6ae1e5733419c8f8bb2d178cd0d45ba39f5217/_data", "Destination": "/tmp/share", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], "Config": { ... "Volumes": { "/tmp/share": {} } }, ... } ]
$ docker volume ls DRIVER VOLUME NAME local 8fadb85943d78e953a16e643bc6ae1e5733419c8f8bb2d178cd0d45ba39f5217
EXPOSE
EXPOSE 지시어를 사용하여 컨테이너가 사용할 포트를 지정합니다. 컨테이너를 실행할 때 반드시 포트 매핑 설정을 넣어주어야 합니다.
만일 호스트 네트워크 드라이버를 사용합니다면 포트 매핑을 설정하지 않고 자동으로 호스트 포트로 노출됩니다.
FROM centos RUN yum -y install httpd RUN echo 'Hello nasa1515!' > /var/www/html/index.html CMD /usr/sbin/httpd -D FOREGROUND EXPOSE 80
$ docker build -t centos:expose . $ docker run -itd --name centos-expose -p 80:80 centos:expose 이미지 정보에서 포트 노출을 확인할 수 있습니다. $ docker inspect centos:expose [ { ... "ContainerConfig": { ... "ExposedPorts": { "80/tcp": {} }, ... }, "Config": { ... "ExposedPorts": { "80/tcp": {} }, ... }, ...
$ netstat -nltp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name ... tcp6 0 0 :::80 :::* LISTEN -
MAINTAINER
MAINTAINER 지시어는 이미지의 관리자 정보를 기록합니다.
MAINTAINER nasa1515
[ { ... "Author": "nasa1515", ...
ENTRYPOINT와
CMD
는 둘 다 어플리케이션을 지정하는 지시어입니다.
ENTRYPOINT 와 CMD 의 차이점은 바로 컨테이너 시작 시 실행 명령에 대한 Default 지정 여부입니다.
만약 ENTRYPOINT
를 사용하여 컨테이너 명령을 정의하면 반드시 ENTRYPOINT 에서 지정한 명령을 수행되도록 지정 됩니다.
CMD
를 사용하는 경우컨테이너를 실행할때 인자값을 주게 되면 Dockerfile 에 지정된 CMD 값을 대신 하여 지정한 인자값으로 변경하여 실행되게 됩니다.
# Dockerfile FROM ubuntu CMD ["/bin/df", "-h"]
$ docker build -t nasa/df . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM ubuntu ---> 94e814e2efa8 Step 2/2 : CMD ["/bin/df", "-h"] ---> Running in c5f57fca1068 Removing intermediate container c5f57fca1068 ---> 80eeec0ef7c0 Successfully built 80eeec0ef7c0 Successfully tagged nasa/df:latest