In a Dockerfile, is there a way to avoid copying files to make them accessible to the RUN command? I need to build a Docker image containing a pre-populate a database.
For now, I am using the following commands in our Dockerfile:

COPY db-dump.gz /tmp
RUN zcat /tmp/db-dump.gz | mysql


But is there a way to achieve the same result without copying first the (potentially large) dump into the container?

At shell-level, I could pipe the data into the container using something along the lines of (untested):

zcat db-dump.gz | docker exec -i $CID mysql


But I don't know if there is any similar option available in a Dockerfile.
You can do this with BuildKit and the experimental frontend. As of 18.09, BuildKit can be enabled with either:

export DOCKER_BUILDKIT=1


for a single shell, or to change the default for the host, you can add to /etc/docker/daemon.json:

{
  "features": {"buildkit": true}
}


You'll need to reload the docker engine after changing the above.



With BuildKit enabled, your Dockerfile would look like:

# syntax=docker/dockerfile:experimental

RUN --mount=type=bind,source=db-dump.gz,target=/tmp/db-dump.gz \
    zcat /tmp/db-dump.gz | mysql


You then build with a docker build . command as before, but with BuildKit enabled.

To see more about BuildKit's experimental features, see https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md