docker (3) dockerfile 指令

dockerfile 是建立docker鏡像的文本,可使用docker build -t name . 命令建立對應的docker鏡像。docker在建立鏡像的過程當中會首先建立容器,而後根據每個命令,構建容器的每一層,最終構建整個鏡像的文件。鏡像文件使用的時候,也是將每層分別overlay到下層之上。docker

1. ADD 與COPY命令

Dockerfile中的COPY指令和ADD指令,將主機上的資源複製或添加到容器鏡像中,每一行命令都構建容器鏡像的一層。shell

COPY指令和ADD指令的區別:ubuntu

  1. ADD命令支持從遠程URL獲取資源並複製到鏡像中,COPY指令只能從執行docker build所在的主機上讀取資源並複製到鏡像中。
  1. ADD命令能夠將整個tar包,拷貝到鏡像文件中,並進行解壓縮。
    知足同等功能的狀況下,推薦使用COPY指令。ADD指令更擅長讀取本地tar文件並解壓縮。

COPY指令

COPY指令可以將構建命令所在的主機本地的文件或目錄,複製到鏡像文件系統。
exec格式用法(推薦):
COPY [" ",... " "],推薦,特別適合路徑中帶有空格的狀況
shell格式用法:
COPY ...
數組

ADD指令

exec格式用法(推薦):
ADD [" ",... " "],特別適合路徑中帶有空格的狀況
shell格式用法:
ADD ...
說明,對於從遠程URL獲取資源的狀況,因爲ADD指令不支持認證,若是從遠程獲取資源須要認證,則只能使用RUN wget或RUN curl替代。
另外,若是源路徑的資源發生變化,則該ADD指令將使Docker Cache失效,Dockerfile中後續的全部指令都不能使用緩存。所以儘可能將ADD指令放在Dockerfile的後面。
緩存

注意事項:

  1. 原路徑
    源路徑能夠有多個
    源路徑是相對於執行build的相對路徑
    源路徑若是是本地路徑,必須是build上下文中的路徑
    源路徑若是是一個目錄,則該目錄下的全部內容都將被加入到容器,可是該目錄自己不會
  2. 目標路徑
    目標路徑必須是絕對路徑,或相對於WORKDIR的相對路徑
    目標路徑若是不存在,則會建立相應的完整路徑
    目標路徑若是不是一個文件,則必須使用/結束
    路徑中可使用通配符

讀取URL遠程資源

當要讀取URL遠程資源的時候,並不推薦使用ADD指令,而是使用RUN指令,在RUN指令中執行wget或curl命令。tomcat

RUN mkdir -p /usr/src/things \
    && curl -SL http://example.com/big.tar.xz \
    | tar -xJC /usr/src/things \
    && make -C /usr/src/things all

CMD與ENTRYPOINT

CMD指令能夠指定容器啓動時要執行的命令,但它能夠被docker run命令的參數覆蓋掉。
ENTRYPOINT 指令和CMD相似,它也可用戶指定容器啓動時要執行的命令。dockerfile中能夠有多條cmd命令,但只是最後一條有效。
若是dockerfile中也有CMD指令,CMD中的參數會被附加到ENTRYPOINT 指令的後面。
若是這時docker run命令帶了參數,這個參數會覆蓋掉CMD指令的參數,並也會附加到ENTRYPOINT 指令的後面。
這樣當容器啓動後,會執行ENTRYPOINT 指令的參數部分。能夠看出,相對來講ENTRYPOINT指令優先級更高。
CMD命令的參數格式,通常寫成 字符串數組的方式,如上面的例子。如:服務器

CMD  ["echo","hello world"]

雖然也可寫成CMD echo hello word 方式,但這樣docker會在指定的命令前加 /bin/sh -c 執行,有時有可能會出問題。 因此推薦採用數據結構的方式來存放命令。數據結構

#test
FROM ubuntu
MAINTAINER hello
RUN echo hello1 > test1.txt
RUN echo hello2 > /test2.txt
EXPOSE 80
ENTRYPOINT ["echo"]
CMD ["defaultvalue"]

當運行 docker run image 輸出的內容是 defaultvalue,能夠看出CMD指令的參數得確是被添加到ENTRYPOINT指令的後面,而後被執行。
當運行docker run myimage hello world 輸出的內容是 hello world ,能夠看出docker run命令的參數得確是被添加到ENTRYPOINT指令的後面,而後被執行,這時CMD指令被覆蓋了。
另外咱們能夠在docker run命令中經過 --entrypoint 覆蓋dockerfile文件中的ENTRYPOINT設置,如:運維

docker run --entrypoint="echo" myimage good  結果輸出good

注意,無論是哪一種方式,建立容器後,經過 dokcer ps查看容器信息時,COMMOND列會顯示最終生效的啓動命令。curl

EXPOSE  命令

EXPOSE port [port2,port3,...],例如EXPOSE 80這條指令告訴Docker服務器暴露80端口,供容器外部鏈接使用。
在啓動容器的使用使用-P,Docker會自動分配一個端口和轉發指定的端口,使用-p能夠具體指定使用哪一個本地的端口來映射對外開放的端口。
EXPOSE命令只是聲明瞭容器應該打開的端口,並無實際上將它打開!
若是不用-p或者-P中指定要映射的端口,容器不會映射端口出去。不能在Dockerfile裏面進行端口映射,只能在容器啓動的時候或者在docker-compose文件中使用ports來指定將要映射的端口。

EXPOSE命令的做用

  1. 寫在Dockerfile中進行聲明,能讓運維人員或者後來者知道咱們開啓了容器的哪些端口。
  2. 當咱們聲明瞭EXPOSE端口以後,咱們使用-P命令進行隨機映射的時候,是會對這個端口進行映射的。
    好比說咱們如今對一個tomcat容器進行EXPOSE 9999聲明,那麼咱們進行-P隨機映射的時候是會對9999端口進行映射的。

WORKDIR命令

格式: WORKDIR /path 爲RUN CMD ENTRYPOINT指定配置工做目錄,可使用多個WORKDIR指令,若後續指令用得是相對路徑,則會基於以前的命令指定路徑。 當最後指定workdir時,容器啓動時運行在指定的workdir下。 好比,cmd 指定的指令要訪問,同目錄下的配置文件,就須要指定workdir,把相應的工做目錄切換到workdir下。

相關文章
相關標籤/搜索