This question already has an answer here:
How to copy multiple files in different source and destination directories using a single COPY layer in Dockerfile
(1 answer)
Closed last month.
I want to combine 2 COPY in one line with other source and destinations.
My current code:
COPY ./file1.txt /first/path/
COPY ./file2.txt /second/path/
I want combine these lines in one line. I tried with an array, but it's not correct:
COPY ["./file1.txt", "/first/path/", "./file2.txt", "/second/path/"]
you can use a multi-line COPY statement and specify multiple src and dest pairs:
like this
COPY
./file1.txt /first/path/
./file2.txt /second/path/
This will copy file1.txt to /first/path/ and file2.txt to /second/path/.
or
COPY --from=0 ./file1.txt /first/path/ --from=0 ./file2.txt /second/path/
This will also copy file1.txt to /first/path/ and file2.txt to /second/path/.
The COPY and ADD steps can have multiple source arguments, but only a single destination. When that syntax is used, the following requirement applies:
If multiple <src> resources are specified, either directly or due to the use of a wildcard, then <dest> must be a directory, and it must end with a slash /.
For more details, see the Dockerfile documentation: https://docs.docker.com/engine/reference/builder/#copy
This is not possible with COPY command, however you can use ADD command to do it.
ADD ["./file1.txt", "/first/path/", "./file2.txt", "/second/path/"]
for more details
Related
in my current directory I have multiple directories that i want to copy them inside dockerfile but not all of them inside single location, lets sya I have dir1, dir2, file1 and i want to copy dir1 into des1 and dir2 into des2 and file1 into WORKDIR .
I have no problem doing it with three layes using copy command inside dockerfile, but is there another way to do that in single layer using copy or add command ??
I achieved that by doing this:
COPY dir1/ /app/dir1
COPY dir2/ /app/dir2
COYP file1 /app
Target needed is to do all of them in single COPY.
you could create some sort of script or come up with some clever way to copy src1 dst1 && src2 dst2 but that doesn't help with the final image size (like squashing image layers) or with image pull time (unless you have many many layers and then extracting every little one takes a bit more time).
It's better to separate copying the files to multiple stages so when you change one of them only the changed layer is built again, or when pulling a new verion of the same homebrewed image and only some of the layers have changed and have to be pulled.
some of the sources I've used:
https://github.com/moby/moby/issues/33551
How to copy multiple files in one layer using a Dockerfile?
https://linux.die.net/man/1/cp
I saw this post, explaining how it is better to have a combined RUN directive instead of multiple RUNs, (i.e. RUN a && b && c is better than RUN a; RUN b; RUN c;).
I want to do the same for the COPY directive.
In case of the same dst, I can just do COPY /src/a/ /src/b/* /src/*/c dst/. However, when having multiple destinations, I can't do it.
I tried COPY src/a dst/a && src/b dst/b but it failed:
/var/lib/docker/tmp/docker-builder.../&&: no such file or directory
meaning the && wasn't parsed correctly.
Is there a way to have a concise COPY directive?
No, you can't have multiple destinations per COPY directive. If you want to use just a single COPY then, if possible, build your directory structure outside the container so that it matches the expected result inside of the container and just copy the whole structure.
/var/lib/docker/tmp/docker-builder.../&&: no such file or directory
meaning the && wasn't parsed correctly.
&& was parsed correctly. It was parsed as a filename because that is how the underlying function that executes COPY command is implemented.
COPY [--chown=<user>:<group>] <src>... <dest>
Also, note that one of the reasons for having just one (or just a small bunch) of RUN directives is that each of these is executed in its own intermediate container which is immediately removed once the particular RUN directive is executed which obviously produces an additional overhead that can be avoided by simply chaining the commands.
This is not the case with COPY though. Even if you have 100s COPY directives, all of these are executed without creating and removing any intermediate containers. Personally, I am not worried about having additional COPY directive if it makes the Dockerfile more readable. This doesn't affect build speed and/or size of the container in any significant way.
I have a problem with 5th line of my Dockerfile. I couldn't figure out what that means.
FROM python:3.7-alpine
LABEL author= APPLE
LABEL company= PINEAPPLE
ARG HOME_DIR='/schooldata'
ADD . $HOME_DIRECT ##[ this line ]
EXPOSE 5000
WORKDIR $HOME_DIRECT
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "app.py"]
Here :
ADD . $HOME_DIRECT
ADD performs a resource copy from a source to the current built image with the following specificity : if that is recognized as an archive (tar,zip...), it copies its content, otherwise it copies the contained files/directories such as.
The two next arguments are the source resource and the target resource of ADD.
. means that the source is the build context. Build context is the last argument of the docker build command : often we specify . such as docker build FooTag . to represent the current directory where the docker build command is executed but that may be different.
$HOME_DIRECT is the target directory of the copy inside the built image.
As a side note, ADD has a quite complex behavior (it also may accept URL as source, so it should be favored over COPY only for special cases (URL and copy archive's content).
In most of cases that is indeed better :
COPY . $HOME_DIRECT
It will add the content of your working directory (where the build command has been executed) into you image in the location defined in environment variable HOME_DIRECT
More details: here
Is it possible to copy multiple files to different locations in a Dockerfile?
I'm looking to go from:
COPY outputs/output/build/.tools /root/.tools
COPY outputs/output/build/configuration /root/configuration
COPY outputs/output/build/database/postgres /root/database/postgres
I have tried the following, but no joy:
COPY ["outputs/output/build/.tools /root/.tools","outputs/output/build/configuration /root/configuration","outputs/output/build/database/postgres /root/database/postgres"]
Not sure if this is even possible.
Create a file .dockerignore in your docker build context directory. Create a soft link (ln) of the root directory you want to copy and exclude the directories you don't want in your .dockerignore.
In your case, you don't need the soft link as the directory is already in the docker build context. Now, add the directories in the .dockerignore file that you don't want eg. if you don't want bin directory you can do that as,
# this is .dockerignore file
outputs/output/build/bin*
Finally in your Dockerfile,
COPY outputs/output/build/ /root/
Details are here.
it looks like you are trying to do bash style [] brace expansion
RUN command uses sh NOT bash
see this SO article discussing it
Bash brace expansion not working on Dockerfile RUN command
or the docker reference
https://docs.docker.com/engine/reference/builder/#/run
Does ADD command copy my directory files (including sub-directories files) into a new destination?
Yes it will, assuming <src> is a directory in ADD <src> <dest>.
The ADD command is a bit tricky but mostly for the <dest> part. For instance, the ADD command behaves differently depending on when <dest> ends with a slash or not.