Problem Description
When creating a Docker image, there is a need to copy all files and directories from a certain path into the image. The following Dockerfile was written:
FROM alpine
WORKDIR /root/test_docker_proj
COPY * ./
The original directory structure is as follows:
/projects/test_docker_proj
├── Dockerfile
├── dir1
│ ├── dir11
│ │ └── file11
│ └── file1
└── file2
However, the directory structure copied into the Docker image turns out like this:
/root/test_docker_proj
├── Dockerfile
├── dir11
│ └── file11
├── file1
└── file2
As you can see, the dir1
folder was not copied into the image, but the subdirectories and files within dir1
were copied, along with files at the same level as dir1
. In other words, during the execution of the COPY command, the top-level directory was “unpacked.”
COPY/ADD Behavior Logic
To determine the behavior of the COPY command and the similar ADD command, the following tests were conducted:
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* ./
The tests revealed several rules about the COPY/ADD
commands:
- The
ADD
command behaves the same as theCOPY
command when copying files. - Using
*
as the source inCOPY/ADD
commands represents./*
. - If the source of
COPY/ADD
is a directory, the contents of the directory are copied, not the directory itself. - In
COPY ./* target
, the*
is translated into the following logic:
COPY ./sub_dir1 target
COPY ./sub_dir2 target
COPY ./file1 target
COPY ./file2 target
In file systems, both directories and files are essentially files. The cp
command in operating systems, when executing cp * target
, treats directories as files and copies them to the target path, effectively copying the files themselves. However, Docker’s COPY/ADD
copies the contents of directories, not the directories themselves.
This “strange” logic of Docker has been criticized for a long time, but there seems to be no intention to change it. The latest developments can be referenced in the two issues below. Until Docker makes changes, it’s important to pay attention when writing Dockerfiles.