1. 程式人生 > >Dockerfile COPY指令和ADD指令的區別

Dockerfile COPY指令和ADD指令的區別

COPY 複製檔案

格式:

  • COPY <源路徑>... <目標路徑>
  • COPY ["<源路徑1>",... "<目標路徑>"]

COPY 指令將從構建上下文目錄中 <源路徑> 的檔案/目錄複製到新的一層的映象內的 <目標路徑> 位置。比如:

COPY package.json /usr/src/app/

<源路徑> 可以是多個,甚至可以是萬用字元,其萬用字元規則要滿足 Go 的 filepath.Match 規則,如:

COPY hom* /mydir/
COPY hom?.txt /mydir/

<目標路徑> 可以是容器內的絕對路徑,也可以是相對於工作目錄的相對路徑(工作目錄可以用 WORKDIR

 指令來指定)。目標路徑不需要事先建立,如果目錄不存在會在複製檔案前先行建立缺失目錄。

此外,還需要注意一點,使用 COPY 指令,原始檔的各種元資料都會保留。比如讀、寫、執行許可權、檔案變更時間等。這個特性對於映象定製很有用。特別是構建相關檔案都在使用 Git 進行管理的時候。

ADD 更高階的複製檔案

ADD 指令和 COPY 的格式和性質基本一致。但是在 COPY 基礎上增加了一些功能。

比如 <源路徑> 可以是一個 URL,這種情況下,Docker 引擎會試圖去下載這個連結的檔案放到 <目標路徑> 去。下載後的檔案許可權自動設定為 600,如果這並不是想要的許可權,那麼還需要增加額外的一層 RUN

進行許可權調整,另外,如果下載的是個壓縮包,需要解壓縮,也一樣還需要額外的一層 RUN 指令進行解壓縮。所以不如直接使用 RUN 指令,然後使用 wget 或者 curl 工具下載,處理許可權、解壓縮、然後清理無用檔案更合理。因此,這個功能其實並不實用,而且不推薦使用。

如果 <源路徑> 為一個 tar 壓縮檔案的話,壓縮格式為 gzipbzip2 以及 xz 的情況下,ADD 指令將會自動解壓縮這個壓縮檔案到 <目標路徑> 去。

在某些情況下,這個自動解壓縮的功能非常有用,比如官方映象 ubuntu 中:

FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
...

但在某些情況下,如果我們真的是希望複製個壓縮檔案進去,而不解壓縮,這時就不可以使用 ADD 命令了。

在 Docker 官方的最佳實踐文件中要求,儘可能的使用 COPY,因為 COPY 的語義很明確,就是複製檔案而已,而 ADD 則包含了更復雜的功能,其行為也不一定很清晰。最適合使用 ADD 的場合,就是所提及的需要自動解壓縮的場合。

另外需要注意的是,ADD 指令會令映象構建快取失效,從而可能會令映象構建變得比較緩慢。

因此在 COPY 和 ADD 指令中選擇的時候,可以遵循這樣的原則,所有的檔案複製均使用 COPY 指令,僅在需要自動解壓縮的場合使用 ADD


參考地址(https://yeasy.gitbooks.io/docker_practice