dockerfile簡述

做用

Dockerfile的內容是一坨能夠執行的代碼(或者說是指令)(docker的DSL),這些代碼使得建立鏡像的操做能夠複用以及自動化。git

指令格式

Dockerfile的指令格式很簡單:
INSTRUCTION argumentsgithub

指令是不區分大小寫的,可是約定爲所有大寫。
Dockerfile中指令的書寫順序就是它們的執行順序。docker

指令

FROM

Dockerfile必須以FROM指令開始,FROM指令指定了基礎鏡像是什麼。也就是基於哪一個鏡像來製做本身的鏡像。
FROM <image name>
image name的格式通常爲"image:tag"shell

MAINTAINER

指定鏡像的做者信息:
MAINTAINER <author name>segmentfault

RUN

在shell或者exec的環境下執行的命令。RUN指令會在新建立的鏡像上添加新的層面,接下來提交的結果用在Dockerfile的下一條指令中。
RUN <command>學習

ADD和COPY

複製文件指令。
ADD <source> <destination>
source能夠是URL或者是啓動配置上下文中的一個文件。
將文件拷貝到container的文件系統對應的路徑
全部拷貝到container中的文件和文件夾權限爲0755,uid和gid爲0
若是文件是可識別的壓縮格式,則docker會幫忙解壓縮。
ui

  • 若是要ADD本地文件,則本地文件必須在 docker build ,指定的 目錄下
  • 若是要ADD遠程文件,則遠程文件必須在 docker build ,指定的 目錄下。好比:
    docker build github.com/creack/docker-firefox
    docker-firefox目錄下必須有Dockerfile和要ADD的文件。

COPY指令功能相似,可是COPY不容許source是URL,同時也不會進行解壓。this

CMD和ENTRYPOINT

提供了容器默認的執行命令。 Dockerfile只容許使用一次CMD/ENTRYPOINT指令。 使用多個CMD/ENTRYPOINT會抵消以前全部的指令,只有最後一個指令生效。 CMD有三種形式:.net

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD command param1 param2 (shell form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)

區別:
第二種方式會以"/bin/sh -c"形式調用。第三種方式是爲ENTRYPOINT指定參數,也就是使用第三種形式時,要有一個ENTRYPOINT指令。firefox

若是在執行docker run時提供了command,且command和CMD中相同(參數能夠不一樣),則會執行command,不執行CMD中的命令(實際含義就是把CMD中傳遞param覆蓋了)。

ENTRYPOINT(An ENTRYPOINT allows you to configure a container that will run as an executable)有兩種格式:

ENTRYPOINT ["executable", "param1","param2"] (exec form)
ENTRYPOINT command param1 param2 (shell form)

區別:
第二種(shell form)會屏蔽掉docker run時後面加的命令和CMD裏的參數;第一種會把docker run後面的參數或CMD裏的參數追加給ENTRYPOINT,docker run後面的參數會覆蓋掉CMD裏的參數。

例如:

...
ENTRYPOINT ["echo", "param1"]

執行
docker run -it test param2
顯示param1 param2
若是是shell form形式,docker run提供的參數就無效。

二者區別

ENTRYPOINT和CMD的不一樣點在於執行docker run時參數傳遞方式,CMD指定的命令能夠被docker run傳遞的命令覆蓋,例如,若是用CMD指定:

...
CMD ["echo"]

而後運行
docker run CONTAINER_NAME echo foo
那麼CMD裏指定的echo會被新指定的echo覆蓋,因此最終至關於運行echo foo,因此最終打印出的結果就是:
foo
而ENTRYPOINT會把容器名後面的全部內容都當成參數傳遞給其指定的命令(不會對命令覆蓋),好比:

...
ENTRYPOINT ["echo"]

而後運行
docker run CONTAINER_NAME echo foo
則CONTAINER_NAME後面的echo foo都做爲參數傳遞給ENTRYPOING裏指定的echo命令了,因此至關於執行了
echo "echo foo"
最終打印出的結果就是:
echo foo
另外,在Dockerfile中,ENTRYPOINT指定的參數比運行docker run時指定的參數更靠前,好比:

...
ENTRYPOINT ["echo", "foo"]

執行
docker run CONTAINER_NAME bar
至關於執行了:
echo foo bar
打印出的結果就是:
foo bar

EXPOSE

指定容器在運行時監聽的端口。
EXPOSE <port> [<port>...]
該指令會將容器中的端口映射成宿主機器中的某個端口。當你須要訪問容器的時候,能夠不使用容器的IP地址而是使用宿主機器的IP地址和映射後的端口。要完成整個操做須要兩個步驟:

  • 首先在Dockerfile使用EXPOSE設置須要映射的容器端口;
  • 而後在運行容器的時候指定-p選項加上EXPOSE設置的端口,這樣EXPOSE設置的端口號會被隨機映射成宿主機器中的一個端口號。也能夠指定須要映射到宿主機器的那個端口,這時要確保宿主機器上的端口號沒有被使用。
    EXPOSE指令能夠一次設置多個端口號,相應的運行容器的時候,能夠配套的屢次使用-p選項。

WORKDIR

切換目錄用,能夠屢次切換(至關於cd命令),對RUN,CMD,ENTRYPOINT生效。
WORKDIR /path/to/workdir

ENV

設置環境變量。
ENV <key> <value>
若是不指定value,表示清除key環境變量。

USER

使用哪一個用戶跑container:
USER <uid>

VOLUME

受權訪問從容器內到主機上的目錄。語法以下:
VOLUME ["/data"]

參考文檔

Dockerfile reference
Docker入門教程(三)Dockerfile
Docker Dockerfile詳解
Docker學習筆記(3)-- 如何使用Dockerfile構建鏡像
Dockerfile裏指定執行命令用ENTRYPOING和用CMD有何不一樣?
What is the difference between the COPY and ADD commands in a Dockerfile?

相關文章
相關標籤/搜索