Consider the following docker build context:
src/
hi
there
bye
and Dockerfile:
FROM ubuntu
RUN mkdir test
COPY src/hi src/there test/
This works just fine but I would like to make the list of files to copy an ARG
, something like:
FROM ubuntu
ARG files
RUN mkdir test
COPY ${files} test/
Unfortunately calling with docker build --build-arg files='src/hi src/there' some_path
fails because it treats src/hi src/there
as a single item. How can I "expand" the files
argument into multiple files to copy?
On a whim I tried specifying the files arg multiple times: docker build --build-arg files='src/hi' --build-arg files='src/there' some_path
, but this only copies "there".
I have run into this again years later but now found an adequate solution, assuming the files can be grouped into a fixed set of categories.
The answer is basically combining the answers of Docker COPY files using glob pattern? and https://unix.stackexchange.com/questions/59112/preserve-directory-structure-when-moving-files-using-find
Conceptually, the idea is to separate the groups of files in one stage, then copy each group one by one (or ignoring it).
In code:
# Create dummy stage for splitting up files
FROM ubuntu AS src
RUN mkdir /groups
WORKDIR /groups
RUN mkdir group1 group2
# Makes `group2` the de-facto default, can be any though
COPY src group2
RUN rsync --recursive --remove-source-files --prune-empty-dirs \
--include='hi' \
--include='there' \
--exclude='*' \
group2/ group1/
# Create the image we actually care about
FROM ubuntu
COPY --from=src /groups/group1 test/
RUN commands requiring only `group1` files
COPY --from=src /groups/group2 test/
RUN commands requiring all files