問題現(xiàn)象
在制作 docker 鏡像時桥氏,有復制某一個路徑下所有文件和文件夾到鏡像的需求检访,寫下了如下 dockerfile:
FROM alpine
WORKDIR /root/test_docker_proj
COPY * ./
原始目錄結構是這樣的:
/projects/test_docker_proj
├── Dockerfile
├── dir1
│ ├── dir11
│ │ └── file11
│ └── file1
└── file2
然而復制到 docker 鏡像里的目錄結構變成了這樣:
/root/test_docker_proj
├── Dockerfile
├── dir11
│ └── file11
├── file1
└── file2
可以看到 dir1 這個文件夾并沒有被復制到鏡像里畏邢,但是 dir1 中的子文件夾和文件都被復制進來了舒萎,和 dir1 同級的文件也被復制了臂寝。也就是說,在 COPY 執(zhí)行的過程中掏缎,第一層文件夾被「解包」了眷蜈。
COPY/ADD 行為邏輯
為了確定 COPY 和相似的 ADD 命令的行為沈自,做了以下測試:
FROM alpine
WORKDIR /root/test_docker_proj_1
COPY * ./
WORKDIR /root/test_docker_proj_2
ADD * ./
WORKDIR /root/test_docker_proj_3
COPY ./ ./
WORKDIR /root/test_docker_proj_4
ADD ./ ./
WORKDIR /root/test_docker_proj_5
COPY ./dir* ./
WORKDIR /root/test_docker_proj_6
ADD ./dir* ./
通過測試可以發(fā)現(xiàn) COPY/ADD
命令有這么幾個規(guī)則:
-
ADD
命令和COPY
命令在復制文件時行為一致 - 使用
*
作為COPY/ADD
命令的源時候表示的是./*
-
COPY/ADD
命令的源如果是文件夾,復制的是文件夾的內容而不是其本身 -
COPY ./* target
中的*
會被翻譯成如下的邏輯:
COPY ./sub_dir1 target
COPY ./sub_dir2 target
COPY ./file1 target
COPY ./file2 target
文件系統(tǒng)里的文件夾和文件呆躲,本質上都是文件插掂,我們熟悉的操作系統(tǒng)的 cp
命令在執(zhí)行 cp * target
時會把文件夾當成文件一股腦的復制到目標路徑下辅甥,可以認為復制了文件本身,而 docker 的 COPY/ADD
在復制文件夾時復制的是其內容夏块。
docker 的這種「奇怪」的邏輯已經(jīng)被詬病許久了脐供,但是似乎還沒有要改變的意思,最新的進展可以參考下面兩個 issue歇由,在 docker 做出修改之前印蓖,只能在寫 dockerfile 時候注意一下了赦肃。