0

I want to build a docker image. During this process, a massive package (150 MB) needed to be copied from local file system to the image.

I want check the (local directory) existence of this file firstly. If there is, I can COPY it into the image directly. Otherwise I will let docker-build download it from the Internet by a URL and it will take a lot of time.

I call this conditional COPY.

But I don't know how to implemented this feature.

RUN if command cannot do this.

  • You can of course bind mount in a volume that conditionally contains the file and then use `RUN if` to inspect the contents of that volume. – Charles Duffy Oct 28 '22 at 14:00
  • Docker does not support this. I'd suggest either requiring the file to exist on the host first, or doing the download in the Dockerfile exclusively, but not supporting both paths. (If the file is at all hard to retrieve – maybe it requires authentication or is on a firewalled network – then requiring it to be on the host will avoid some practical problems.) – David Maze Oct 28 '22 at 14:57

2 Answers2

0

You can run if condition in RUN for example

#!/bin/bash -x

if test -z $1 ; then 
    echo "argument empty"
    ........
else 
    echo "Arg not empty: $1"
    ........
fi

Dockerfile:

FROM ...
....
ARG arg
COPY bash.sh /tmp/  
RUN chmod u+x /tmp/bash.sh && /tmp/bash.sh $arg

Or you can try this

FROM centos:7
ARG arg
RUN if [ "x$arg" = "x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi

For Copy you can find this dockerfile helpful

#########
# BUILD #
#########

ARG BASE_IMAGE
FROM maven:3.6.3-jdk-11 AS BUILD
RUN mkdir /opt/trunk
RUN mkdir /opt/tmp
WORKDIR /opt/trunk
RUN --mount=target=/root/.m2,type=cache
RUN --mount=source=.,target=/opt/trunk,type=bind,rw mvn clean package && cp -r /opt/trunk/out/app.ear /opt/tmp

##################
# Dependencies #
##################

FROM $BASE_IMAGE
ARG IMAGE_TYPE
ENV DEPLOYMENT_LOCATION /opt/wildfly/standalone/deployments/app.ear
ENV TMP_LOCATION /opt/tmp/app.ear

ARG BASE_IMAGE
            
COPY if [ "$BASE_IMAGE" = "external" ] ; then COPY --from=BUILD $TMP_LOCATION/*.properties $DEPLOYMENT_LOCATION \
               ; COPY --from=BUILD $TMP_LOCATION/*.xml $DEPLOYMENT_LOCATION \
               ; COPY standalone.conf /opt/wildfly/bin ; fi
muhammad shahan
  • 517
  • 6
  • 17
0

I would personally rely on the built-in caching of docker to do this:

FROM alpine

ADD http://www.example.com/link_to_large_file /some/path

For the first time the build will download the file. After that every subsequent build will use the layer cache, as long as you don't delete the previous images. You can also externalize the build cache with storage backends.

If the instructions before your ADD often change the image you can also use the --link flag for ADD to store this layer independently. See the documentation for ADD --link or better COPY --link.

Garuno
  • 1,935
  • 1
  • 9
  • 20