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