Conditional COPY/ADD in Dockerfile?

Inside of my Dockerfiles I would like to COPY a file into my image if it exists, the requirements.txt file for pip seems like a good candidate but how would this be achieved?

COPY (requirements.txt if test -e requirements.txt; fi) /destination
...
RUN  if test -e requirements.txt; then pip install -r requirements.txt; fi

or

if test -e requirements.txt; then
    COPY requiements.txt /destination;
fi
RUN  if test -e requirements.txt; then pip install -r requirements.txt; fi

Solution 1:

Here is a simple workaround:

COPY foo file-which-may-exist* /target

Make sure foo exists, since COPY needs at least one valid source.

If file-which-may-exist is present, it will also be copied.

NOTE: You should take care to ensure that your wildcard doesn't pick up other files which you don't intend to copy. To be more careful, you could use file-which-may-exist? instead (? matches just a single character).

Or even better, use a character class like this to ensure that only one file can be matched:

COPY foo file-which-may-exis[t] /target

Solution 2:

As stated by this comment, Santhosh Hirekerur's answer still copies the file, to archive a true conditional copy, you can use this method.

ARG BUILD_ENV=copy

FROM alpine as build_copy
ONBUILD COPY file /file

FROM alpine as build_no_copy
ONBUILD RUN echo "I don't copy"

FROM build_${BUILD_ENV}
# other stuff

The ONBUILD instructions ensures that the file is only copied if the "branch" is selected by the BUILD_ENV. Set this var using a little script before calling docker build