Dockerfile(11) - COPY 指令詳解

一段話總結完 COPY

  • 作用:複製內容到鏡像
  • 格式: COPY <src> <dest>  
  • 詳解:複製本地主機的 <src>下內容到鏡像中的 <dest>,目標路徑不存在時,會自動創建。
  • <src>:可以是 Dockerfile 所在目錄的一個相對路徑(文件或目錄)
  • <dest>:可以是鏡像內絕對路徑,或者相對於工作目錄(WORKDIR)的相對路徑
  • 路徑:支持正則表達式, COPY test* /tmp 

 

兩種格式

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

  

--chown

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

 

COPY 作用

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

 

簡單栗子

* 通配符

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

COPY hom* /mydir/

 

? 通配符

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

COPY hom?.txt /mydir/

  

重點

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

 

使用相對路徑的栗子

COPY test.txt relativeDir/

等價於

COPY test.txt <WORKDIR>/relativeDir/

 

使用絕對路徑的栗子

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

COPY test.txt /absoluteDir/

 

包含特殊字符的文件

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

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

  

標誌 --from=<name>

將從 from 指定的構建階段中尋找源文件 <src>

# 第一構建階段:將僅用於生成 requirements.txt 文件
FROM tiangolo/uvicorn-gunicorn:python3.9 as requirements-stage

# 將當前工作目錄設置爲 /tmp
WORKDIR /tmp

# 生成 requirements.txt
RUN touch requirements.txt

# 第二構建階段,在這往後的任何內容都將保留在最終容器映像中
FROM python:3.9

# 將當前工作目錄設置爲 /code
WORKDIR /code

# 從第一個階段複製 requirements.txt;這個文件只存在於前一個 Docker 階段,這就是使用 --from-requirements-stage 複製它的原因
COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt

# 運行命令
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

 

COPY 遵循的規則

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

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

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

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

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

 

<src> 是目錄

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

 

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

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

 

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

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

COPY test1.txt test2.txt /mydir/

  

<dest> 不以斜槓結尾

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

COPY test.txt /mytext

 

<dest> 不存在

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

COPY test.txt /dir/test/my/

 

注意事項

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

 

完整練習的 dockerfile

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

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

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

# 添加目錄
COPY TeamFile /

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

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

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

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

WORKDIR /data

# 相對路徑
COPY test.txt test/

 

ADD 和 COPY 的區別和使用場景

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

 

注意

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

 

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