Dockerfile(10) - ADD 指令詳解

一段話總結完 ADD

  • 作用:添加內容到鏡像
  • 格式: ADD <src> <dest> 
  • 詳解:該命令將複製指定的 <src> 路徑下內容到鏡像中的 <dest> 路徑下
  • <src>:可以是 Dockerfile 所在目錄的一個相對路徑(文件或目錄);也可以是一個 URL;還可以是一個 tar 文件(自動解壓爲目錄)
  • <dest>:可以是鏡像內絕對路徑,或者相對於工作目錄(WORKDIR)的相對路徑
  • 路徑:支持正則表達式, ADD *.c /code/ 

 

兩種格式

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

  

--chown

僅適用於 linux 上的 dockerfile,在 window 上沒有用戶、組的概念

 

ADD 作用

  • ADD 指令 <src> 複製新文件、目錄或遠程文件 URL,並將它們添加到路徑 <dest> 
  • 可以指定多個 <src> 資源,但如果它們是文件或目錄,則它們的路徑被解析爲相對於構建上下文的源
  • 每個 <src> 可能包含通配符,匹配將使用 Go 的 filepath.Match 規則完成

 

簡單栗子

* 通配符

把所有 hom 開頭的文件添加到鏡像文件系統的 /mydir/ 目錄下

ADD hom* /mydir/

 

? 通配符

? 匹配 0 或 1 個字符,比如會把 home.txt 文件添加到 /mydir/ 目錄下

ADD hom?.txt /mydir/

  

重點

<dest> 是絕對路徑,或相對於 WORKDIR 的路徑,源將在目標容器內複製到該路徑中

 

使用相對路徑的栗子

ADD test.txt relativeDir/

等價於

ADD test.txt <WORKDIR>/relativeDir/

 

使用絕對路徑的栗子

將 test.txt 添加到 /absoluteDir/ 目錄下

ADD test.txt /absoluteDir/

 

包含特殊字符的文件

添加名爲 arr[0].txt 的文件

ADD arr[[]0].txt /mydir/

  

ADD 遵循的規則

<src> 路徑必須在構建的上下文中

不能添加  ../something 、 /something ,因爲 docker 構建的第一步是將上下文目錄(和子目錄)發送到 docker 守護進程

# test.txt 是相對路徑,相對於構建上下文
ADD test.txt /mkdir/

# 錯誤寫法,文件均不在上下文目錄中,並不會被找到
# 這個找的就是構建上下文的上級目錄的 test.txt
ADD ../test.txt /mkdir/

# 這個找的是本機根目錄下的 test.txt
ADD /test.txt /mkdir/

 

<src> 是一個 URL

  • <dest> 不以斜槓結尾,那麼文件將從 URL 下載並複製到 <dest>
  • <dest> 斜槓結尾,則從 URL 推斷文件名並將文件下載到 <dest>/<filename>
ADD http://example.com/foobar/
  • 這將創建文件 /foobar
  • URL 必須有一個重要的路徑,以便在這種情況下可以 找到文件名(http://example.com 將不起作用)

 

<src> 是目錄

  • 則複製目錄的全部內容,包括文件系統元數據
  • 不會複製目錄本身,只會複製其內容
ADD dir /mydir/

 

<src> 是壓縮格式(gzip、bzip2、identity、xz)的本地 tar 文件

  • 會將它自動解壓爲目錄
  • 但來自遠程 URL 資源不會被解壓縮
  • 當一個目錄被複制或解壓時,它的行爲與 tar -x 相同
  • 注意:文件是否被識別爲可識別的壓縮格式完全取決於文件的內容,而不是文件的名稱;例如,如果一個空文件恰好以 .tar.gz 結尾,黃不會被識別爲壓縮文件,也不會生成任何類型的解壓縮錯誤消息,而只會將該文件複製到目標位置

 

<src> 是任何其他類型的文件

  • 則將其與其元數據一起單獨複製
  • <dest> 以斜槓 / 結尾,它將被視爲一個目錄,並且 <src> 的內容將寫入  <dest>/base(<src>) 

 

指定了多個 <src> 資源,或者由於使用了通配符

<dest> 必須是一個目錄,並且必須以斜槓 / 結尾

ADD test1.txt test2.txt /mydir/

  

<dest> 不以斜槓結尾

它將被視爲常規文件,並且 <src> 的內容將寫入 <dest>

ADD test.txt /mytext

 

<dest> 不存在

路徑中所有缺失的目錄都會自動創建

ADD test.txt /dir/test/my/

 

注意事項

<src> 的內容發生變化,第一個遇到的 ADD 指令將使來自 Dockerfile 的所有後續指令的緩存無效,這包括使 RUN 指令的緩存無效

 

完整練習的 dockerfile

FROM centos
# 添加文件到目錄下
ADD test.txt /mydir/

# 將文件內容寫入 mytest
ADD test.txt /mytest

# 壓縮文件,自動解壓
ADD jmeter.log.zip /myzipdir/

# 添加目錄
ADD TeamFile /

# 其他文件
ADD jmeter.log /mydir/

# 多個文件
ADD test1.txt test2.txt /mydir/

# 通配符,dest 不存在自動創建
ADD test*.txt /mydir/test/

# 特殊字符串
ADD add[[]0].txt /mydir/

WORKDIR /data

# 相對路徑
ADD test.txt test/

 

ADD 和 COPY 的區別和使用場景

  • ADD 支持添加遠程 url 和自動提取壓縮格式的文件,COPY 只允許從本機中複製文件
  • COPY 支持從其他構建階段中複製源文件(--from)
  • 根據官方 Dockerfile 最佳實踐,除非真的需要從遠程 url 添加文件或自動提取壓縮文件才用 ADD,其他情況一律使用 COPY

 

注意

  • ADD 從遠程 url 獲取文件和複製的效果並不理想,因爲該文件會增加 Docker Image 最終的大小
  • 相反,應該使用 curl huo wget 來獲取遠程文件,然後在不需要它時進行刪除

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章