天天看點

dockerfile 幾組易混指令找茬

dockerfile容易弄混的幾組指令

  • ​​背景​​
  • ​​1.COPY vs ADD​​
  • ​​2.ARG vs ENV​​
  • ​​3.RUN vs ENTRYPOINT vs CMD​​
  • ​​4.-p 和-P​​
  • ​​-P的使用​​
  • ​​-p的使用​​
  • ​​檢視端口映射配置​​
  • ​​5.dockerfile中的volume和 docker run -v​​

背景

在docker在使用中,發現其指令中有幾組有趣的指令,總是成對出現的,功能看似差不多,但是又有一絲絲差别,今天介紹幾種,來波找茬!

1.COPY vs ADD

COPY、ADD主體功能類似:從指定位置src拷貝檔案到Docker鏡像dest。

​COPY <src>... <dest>​

​ADD <src>... <dest>​

COPY隻允許從Docker Engine主機上拷貝檔案到Docker鏡像檔案;

ADD也能完成以上工作,但是ADD支援另外兩種src:

檔案源可以是URL

可以從src直接解壓tar檔案到目的地

​ADD http://foo.com/bar.go /tmp/main.go​

從指定位址下載下傳檔案,添加到鏡像檔案系統的/tmp/main.go位置

​ADD http://foo.com/bar.go /tmp/​

因為以/結尾,将會引用url中的檔案名添加到指定的目錄下

​ADD /foo.tar.gz /tmp/​

自動解壓主機檔案到指定目錄

*​

​特别注意​

URL下載下傳和自動解壓功能不能同時生效:​

​任何通過URL下載下傳的壓縮封包件不會自動解壓​

​​。

如果​​

​拷貝本地檔案到鏡像,通常使用COPY​

​​,因為含義更明确

​​

​ ADD支援URL檔案、自動解壓到指定目錄​

​,這2個特性也很棒

2.ARG vs ENV

ARG、ENV也讓人很疑惑的,都是Dockerfile中定義變量的指令。

dockerfile 幾組易混指令找茬

ARG用于鏡像建構階段,ENV用于将來運作的容器。

生成鏡像後,ARG值不可用,正在運作的容器将無法通路ARG變量值。

ARG  VAR_NAME 5      

建構鏡像時,可提供​

​--build-arg VAR_NAME=6 ​

​修改ARG值。

ENV主要是為容器環境變量提供預設值,正在運作的容器可通路環境變量(這是将配置傳遞給應用的好方法):

6      

啟動容器時,可通過​

​docker run -e "VAR_NAME_2=7"或docker-compose.yml​

​提供新的環境變量值來覆寫Dockerfile中設定的ENV值。

​一個小技巧​

​:建構鏡像時不能使用指令行參數重寫ENV,但是你可以使用ARG動态為ENV設定預設值:

You can set VAR_A while building the image or leave it at the default

ARG VAR_A 5      

VAR_B gets the (overridden) value of VAR_A

ENV VAR_B $VAR_A      

3.RUN vs ENTRYPOINT vs CMD

RUN 在新層中執行指令并産生新鏡像,主要用于安裝新軟體包。

ENTRYPOINT 執行程式的啟動指令,當您想将容器作為可執行檔案運作時使用。

CMD和ENTRYPOINT 都可以提供程式的啟動指令;CMD另一個作用是為執行中的容器提供預設值

CMD ["executable","param1","param2"] (可執行形式,最常見)      
command param1 param2 (腳本形式)      
echo "Hello world"      
<image>      

但是當容器以指令啟動,​

​docker run -it <image> /bin/bash​

​, CMD會被忽略,bash解析器将會運作:

root@98e4bed87725:/#
["param1","param2"] 
 (作為ENTRYPOINT指令預設值,此時必須提供ENTRYPOINT指令,且ENTRYPOINT也必須以Json Array形式)      

ENTRYPOINT [“/bin/echo”, “Hello”]

CMD [“world”]

​ run -it <image>​

​​ 将會輸出 Hello world

​​

​run -it <image> earth​

​​将會輸出 Hello earth

打算建構一個可執行的且常駐的鏡像,最好選用ENTRYPOINT;

如果需要提供預設指令參數(可在容器運作時從指令行覆寫),請選擇CMD。

總結:

cmd和entripoint的差別就是 ​​

​cmd不可以覆寫,entripoiint可以被覆寫和追加.​

​ 這個覆寫是 docker run時後面加的 指令 和 cmd/entripoint的shell指令是否覆寫

4.-p 和-P

這2個指令不是在dockerfile中的,是在運作程式的時候,都可以做docker端口映射,在docker run啟動一個容器時,有時候用-p 8080:8080 或者直接-P 不加端口号,這裡有什麼差別?

-P的使用

-P将容器内部開放的網絡端口随機映射到主控端的一個端口上;、

-p的使用

-p指定要映射的端口,一個指定端口上隻可以綁定一個容器。

使用方式有以下幾種:

​​

​1) IP:HOSTPORT:CONTAINERPORT:指定ip、指定主控端port、指定容器port​

  • 适用于映射到指定位址的指定端口,例如将容器的5000端口映射到指定位址127.0.0.1的5000端口上:
-p 8081:8080 是把容器的8080和映射到主控端的8081上
docker run -it -d -p 127.0.0.1:8081:8080 tomat /bin/bash      

​2) IP::CONTAINERPORT:指定ip、未指定主控端port(随機)、指定容器port​

适用于映射到指定位址的任意端口

将容器的9000端口映射到127.0.0.1的任意端口上:

docker run -it -d -p 127.0.0.1::9000  tomcat   /bin/bash      

​3)HOSTPORT:CONTAINERPORT :未指定ip、指定主控端port、指定容器port​

适用于将容器指定端口指定映射到主控端的一個端口上(映射所有接口位址),将容器的80端口映射到主控端的8000端口上:
docker run -itd -p 8000:80 nginx /bin/bash      

​特别說明​

檢視端口映射配置

可以使用

docker      

5.dockerfile中的volume和 docker run -v

dockerfile中的volumn隻是容器中的對外映射目錄,會在主控端上随機生成一個目錄。

docker run -v 可以指定 主機目錄:容器目錄

開通了個微信公衆号:

搜尋: ​​

​怒放de每一天​

​ 後續可能不定時推送相關文章,期待和大家一起成長!!