ChatGPT解决这个技术问题 Extra ChatGPT

How to copy multiple files in one layer using a Dockerfile?

The following Dockerfile contains four COPY layers:

COPY README.md ./
COPY package.json ./
COPY gulpfile.js ./
COPY __BUILD_NUMBER ./

How to copy these files using one layer instead? The following was tried:

COPY [
    "__BUILD_NUMBER ./",
    "README.md ./",
    "gulpfile ./",
    "another_file ./",
]

s
silkfire
COPY README.md package.json gulpfile.js __BUILD_NUMBER ./

or

COPY ["__BUILD_NUMBER", "README.md", "gulpfile", "another_file", "./"]

You can also use wildcard characters in the sourcefile specification. See the docs for a little more detail.

Directories are special! If you write

COPY dir1 dir2 ./

that actually works like

COPY dir1/* dir2/* ./

If you want to copy multiple directories (not their contents) under a destination directory in a single command, you'll need to set up the build context so that your source directories are under a common parent and then COPY that parent.


Note that if the sources are directories, this copies the directory contents, not the directories themselves.
Note also that the destination directory is the same. If you do alot of different files with different destinations, then you may want to consider constructing an overlay filesystem (like a chroot), then turning that into a tar archive, and adding it with ADD.
@Claudiu How to copy the folders themselves?
@k0pernikus you can say COPY myDir1 ./MyDir1/
@manuel-manhart Is there anyone who knows if we can parameterize the list of files using a Build Parameter? github.com/moby/moby/issues/38532?
s
swapsCAPS
COPY <all> <the> <things> <last-arg-is-destination>

But here is an important excerpt from the docs:

If you have multiple Dockerfile steps that use different files from your context, COPY them individually, rather than all at once. This ensures that each step’s build cache is only invalidated (forcing the step to be re-run) if the specifically required files change.

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy


do you know if we can parameterize "all the things"??? Using build parameters? github.com/moby/moby/issues/38532???
@MarcellodeSales not sure why you would need that. Why dont you create a base image without these files and then the child images have the copy instruction in them - if they need to define the path anyways it does not make much of a difference. Or you could just leave it out ot the image(s) completely and mount it into the container - there you have the .env files to have this configurable.
Also you can always copy over an existing path anyways, since the file system is layered, it will overlap / shadow the pre existing content.
@ManuelManhart, I'm building a Dynamic Parameterized Image with ONBUILD COPY... As part of a Platform, I'm hiding the complexity of what needs to be done in the image, so, that's why I need the values to be provided as a parameter.
@MarcellodeSales I dont think that this is supported right now / yet. But you could use build arguments to have it encapsulated, see stackoverflow.com/questions/43654656/…
A
Aaron

It might be worth mentioning that you can also create a .dockerignore file, to exclude the files and directories that you don't want to copy:

https://docs.docker.com/engine/reference/builder/#dockerignore-file

Before the docker CLI sends the context to the docker daemon, it looks for a file named .dockerignore in the root directory of the context. If this file exists, the CLI modifies the context to exclude files and directories that match patterns in it. This helps to avoid unnecessarily sending large or sensitive files and directories to the daemon and potentially adding them to images using ADD or COPY.


E
Edwin O.

simple

COPY README.md  package.json gulpfile.js __BUILD_NUMBER ./

from the doc

If multiple resources are specified, either directly or due to the use of a wildcard, then must be a directory, and it must end with a slash /.


r
robSE13

The original answer warns about an exception handling directories. https://stackoverflow.com/a/30316600/3257491

If you want to achieve this with directories where you just want to include one or more directories and zero or more specific files you can use .dockerignore:

.dockerignore file to ignore everything except src directory, test directory package.json file and package-lock.json file:

*
!src
!test
!package.json
!package-lock.json

Then Dockerfile:

COPY . ./

This will include just the files included in exceptions in the .dockerignore file.


m
moudrick

To make it review friendly, you may need a multiline COPY command. E.g. if the list of files to copy is very long.

Backslash escaping end of lines treats this like this:

COPY __BUILD_NUMBER    \
     README.md         \
     gulpfile          \
     another_file      \
     ./

I could find an example with backslash for RUN command, but not for COPY. It works though for COPY as well.