Dockerfilejava
一. Dockerfile是什麼linux
Dockerfile是docker中鏡像文件的的描述文件,說的直白點就是鏡像文件究竟是由什麼東西一步步構成的。例如咱們在淘寶上買了一件商品,可是這個商品須要組裝才能使用,因而賣家就給了你一張圖紙,你就按照圖紙一步一步的組裝起來,而後就成了你所須要的樣子。那麼Dockerfile就是這張圖紙,鏡像文件就是你須要的商品。Dockerfile名字能夠隨便命名,可是不建議你這作,仍是按照規範來使用,首字母要大寫。下面給出咱們前幾個章節使用到的centos爲例,來看看它的Dockerfile是怎麼樣的,以下圖所示: docker
二. Dockerfile、鏡像、容器vim
Dockerfile:是鏡像的構建文件,描述的鏡像是一步步怎麼來的。centos
鏡像:是經過Dockerfile作出來的,包含操做系統基礎文件和軟件運行環境,它使用分層的存儲方式。bash
容器:是運行起來的鏡像,簡單理解,Docker鏡像至關於程序,容器至關於進程。工具
三. Dockerfile的基本語法及執行流程ui
3.1 Dockerfile的基本語法spa
a.每一個保留字必須放在每一行的開頭,能夠大寫也能夠小寫,可是建議大寫;操作系統
b.指令按照順序,從上往下依次執行;
c.#表示註解;
d.每條執行指令都會建立一個新的鏡像,而且執行提交。
3.2 Dockerfile的執行流程
a.docker從基礎鏡像中執行一個容器;
b.執行一條指令對鏡像進行修改;
c.執行docker commit命令,提交新的鏡像;
d.在基於剛剛提交的鏡像運行一個新的容器;
e.執行Dockerfile中的下一條指令,按照b、c、d依次循環下去,知道全部的指令執行完畢。
3.3 演示講解
FROM centos #指定要生成的鏡像的基礎鏡像,開頭第一句話必須也只能是FROM MAINTAINER zhengjingmao@163.com #指定做者是誰 RUN yum install -y vim #執行 yum install -y vim 命令,安裝vim RUN yum install -y net-tools #執行 yum install -y net-tools, 安裝net-tools工具
WORKDIR /dev/ #啓動容器後,若是啓動交互模式,直接進入到哪一個目錄 CMD ["/bin/bash"] #啓動容器的時候,進入到/bin/bash這種命令行
如上代碼所示,FROM、MAINTAINER、RUN、WORKDIR、CMD均爲關鍵字,按照標準的規範須要大寫;FROM centos表示咱們的基礎鏡像是centos,而後會啓動centos這個容器,執行第二行代碼又會生成新的鏡像文件,而後提交,周而復始。
四. Dockerfile關鍵字
關鍵字 | 做用 |
FROM | 指定基礎鏡像 |
MAINTAINER | 做者的信息 |
RUN | 執行什麼命令 |
EXPOSE | 容器對外暴露的端口 |
WORKDIR | 進入到容器後進入到哪一個目錄 |
ENV | 配置環境變量 |
ADD | 將文件拷貝到鏡像中並解壓 |
COPY | 將文件拷貝到鏡像中 |
VOLUME | 配置數據卷 |
CMD | 容器啓動時候執行的命令 |
ENTRYPOINT | 容器啓動時候執行的命令 |
a.ADD指令,咱們如今定義這樣一個Dockerfile,代碼以下所示:
FROM centos MAINTAINER zhengjingmao@163.com RUN mkdir /datas ADD jdk-8u60-linux-x64.tar.gz /datas/ WORKDIR /datas/ CMD ["/bin/bash"]
首先必須將jdk-8u60-linux-x64.tar.gz文件拷貝到Dockerfile同級目錄下,以下圖所示:
執行命令:docker build -t mycentos . 構建mycentos鏡像,以下圖所示:
而後啓動容器,進入到 /datas/目錄下,會發現 jdk1.8.0_60 目錄,表示add命令還執行了解壓命令,以下圖所示:
b.COPY命令,咱們定義一個Dockerfile, 代碼以下:
FROM centos MAINTAINER zhengjingmao@163.com RUN mkdir /datas ADD jdk-8u60-linux-x64.tar.gz /datas/ WORKDIR /datas/ CMD ["/bin/bash"]
執行命令:docker build -t mycentos . 構建mycentos鏡像。
而後啓動容器,進入到 /datas/目錄下,會看到jdk-8u60-linux-x64.tar.gz文件,並無解壓,以下圖所示:
c.ENV命令,配置環境變量,咱們仍是用上面提到的jdk爲例,作過Java開發的朋友都知道,jdk須要配置環境變量,Dockerfile的內容以下所示:
FROM centos MAINTAINER zhengjingmao@163.com RUN mkdir -p /datas/ ADD jdk-8u60-linux-x64.tar.gz /datas/ ENV JAVA_HOME=/datas/jdk1.8.0_60 #配置JAVA_HOME ENV PATH=$JAVA_HOME/bin:$PATH #配置PATH CMD ["/bin/bash"]
由於內容的重複性,在這裏就不贅述了。當咱們容器啓動後,咱們輸入:java -version命令,就能看到咱們熟悉的內容了。
d.CMD關鍵字,在鏡像構建階段不執行,在容器啓動階段執行(而咱們的RUN關鍵字定義的指令在容器構建階段就會執行,請記住它與CMD的區別)。若是一個Dockerfile中有多個CMD命令,後面的會覆蓋前面的,說白了只有最後一個生效,以下代碼和註釋:
............省略............ CMD echo "<<<<<<<<<<<nice to meet you>>>>>>>>>>" CMD /bin/bash CMD echo "==========How are you?=============" #當容器啓動的時候只有該行代碼會執行,會將前兩行代碼覆蓋
CMD還有一個問題,就是當咱們使用 docker run命令的時候,咱們能夠在整個docker命令的最後加上其餘額外的命令,那麼額外的命令會覆蓋Dockerfile中全部的CMD命令,例如咱們執行以下命令:docker run -it centos ls / -l,最終的結果以下圖所示:
e. ENTRYPOINT指令,和CMD命令差很少,若是一個Dockerfile中有多個ENTRYPOINT,只有最後一個生效。可是他們仍是有區別的,若是ENTRYPOINT後面有CMD,當以exec的方式運行的時候,CMD的值會做爲參數給ENTRYPOINT,可能不少人看到這句話不大理解,那麼咱們來兩個例子:
例一:
FROM centos MAINTAINER zhengjingmao@163.com RUN mkdir -p /datas/ ENTRYPOINT ["echo", "hello"] CMD ["world"] #會將world做爲echo hello的參數,最後的命令其實爲echo hello world
例二:
FROM centos MAINTAINER zhengjingmao@163.com RUN mkdir -p /datas/ ENTRYPOINT ["echo", "hello"]
總結:當咱們理解了CMD和ENTRYPOINT兩個命令的區別後,之後在使用的過程當中就不會出現各類問題了。