Conditional COPY/ADD in Dockerfile?

2019-01-17 05:43发布

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

4条回答
女痞
2楼-- · 2019-01-17 06:07

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
查看更多
Anthone
3楼-- · 2019-01-17 05:57

Maybe you just don't need! Let's see your code again:

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

Maybe you can just switch to:

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

Now you have this:

  • If the file exists, it will be copied by COPY and processed by PIP within RUN
  • If the file does not exists, COPY would fail (silently, I suppose) and PIP will not RUN because of the condition
查看更多
虎瘦雄心在
4楼-- · 2019-01-17 05:58

Work around Solution

I had requirement on copy FOLDER to server based on ENV Variables. I took the empty server image. created required deployment folder structure at in local folder. then added below line to DockerFile copy the folder to container. In last line added entry point to execute init file.sh before docker start the server.

#below lines added to integrate testing framework
RUN mkdir /mnt/conf_folder
ADD install /mnt/conf_folder/install
ADD install_test /mnt/conf_folder/install_test
ADD custom-init.sh /usr/local/bin/custom-init.sh
ENTRYPOINT ["/usr/local/bin/custom-init.sh"]

Then create the custom-init.sh file in local with script something like below

#!/bin/bash
if [ "${BUILD_EVN}" = "TEST" ]; then
    cp -avr /mnt/conf_folder/install_test/* /mnt/wso2das-3.1.0/
else
    cp -avr /mnt/conf_folder/install/* /mnt/wso2das-3.1.0/
fi;

In docker-compose file below lines.

environment: - BUILD_EVN=TEST

These changes copy folder to container during docker build. when we execute docker-compose up it copy or deploy the actual required folder to server before server starts.

查看更多
劳资没心,怎么记你
5楼-- · 2019-01-17 06:03

This isn't currently supported (as I suspect it would lead to non-reproducible image, since the same Dockerfile would copy or not the file, depending on its existence).

This is still requested, in issue 13045, using wildcards: "COPY foo/* bar/" not work if no file in foo" (May 2015).
It won't be implemented for now (July 2015) in Docker, but another build tool like bocker could support this.

查看更多
登录 后发表回答