一段話總結完 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 來獲取遠程文件,然后在不需要它時進行刪除