The answer from @ISanych is correct but incomplete. I spent almost an entire day trying to achieve what I know now is not possible using the Docker COPY
command. I read many issues similar - but not quite the same - as mine on the internet. I hope the explanation below will prevent another user from making the same mistake.
COPY will copy the contents of each arg dir into the destination dir. Not the arg dir itself, but the contents. https://github.com/moby/moby/issues/15858#issuecomment-136552399
I don't know this user but this is the most authoritative and clear description of the difference in behavior that I have found (the emphasis is mine)
The OP has the following structure and would like to recursively copy the contents of the files
directory into a similarly named files
directory already existing on the image file-system.
files/
folder1/
file1
file2
folder2/
file1
file2
The OP used the following command
COPY files/* /files/
and was surprised to learn that rather than copying the two folders folder1
and folder2
and their contents into the files
directory the command actually copied the contents of folder1
and of folder2
into the files
directory. As explained by the moby developer above in the full response in the Github issue, the shell glob (*) will expand to pass in folder1
and folder2
to the COPY command which will then copy the contents of each of folder1
and folder2
into the destination folder.
If you use the approach suggested by @ISanych - COPY files/ /files/
- then the contents of the files
directory - that is the directories named folder1
and folder2
- will be copied into the destination /files/
directory as indicated.
Importantly, there does not seem to be any way to avoid this behavior of the COPY
command. This behavior is highlighted (as it was for me) in the situation where there are multiple source file structures similar to that described by the OP and the user wishes to copy several top-level directories recursively into the root directory on the target - in one go:
files1/
folder1/
file1
file2
folder2/
file1
file2
files2/
folder1/
file1
file2
folder2/
file1
file2
Using the docker COPY
command as you would the *nix cp
command will yield unexpected results. That is, writing the command COPY files1 files2 .
will not behave in the same way as a similar GNU cp command. Instead the COPY command shown will yield the result in which you have the contents of files1/folder1
and files2/folder1
merged into a single folder1
on the destination and you are left with something like this and wondering what happened to the second (or first) directory?
folder1/
file1
file2
folder2/
file1
file2
If you wish to recursively copy the directories and their contents to a destination directory from the build context, the work-around is to create the destination directories first with the desired name and then issue a COPY for each of the top-level directories. E.g. for the files1 directory:
RUN mkdir ./files1
COPY files1 ./files1
RUN mkdir ./files2
COPY files2 ./files2