Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Large Docker context slowing down docker-compose build

I have two images that use a two-stage build to build Scala code and copy the artifacts to a final image. To speed up the build, I copy my local ~/.ivy2 to the context directory and from there to the images (~1GB). Unfortunately this means that even when nothing has changed and the images don't need to be re-built, docker-compose build (or docker build) hangs for quite a while to copy Docker context. This happens twice of course, once for each image.

Is there any cleverer way to do this?

Dockerfile:

FROM openjdk:8

RUN apt-get update &&\
    apt-get install -y apt-transport-https gnupg2 &&\
    echo "deb https://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list &&\
    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823 &&\
    apt-get update &&\
    apt-get install -y sbt=1.1.6

COPY ivy-cache/ /root/.ivy2

COPY app/source/ /app/source

RUN cd /app/source &&\
    sbt assembly &&\
    cp target/scala-2.11/my-app-*.jar /app/my-app.jar

FROM gettyimages/spark:2.3.1-hadoop-3.0

COPY --from=0 /app/my-app.jar /app/my-app.jar

CMD ["spark-submit", "--master", "local", "/app/my-app.jar"]
like image 965
lfk Avatar asked Feb 23 '26 14:02

lfk


1 Answers

With 18.09, docker includes BuildKit. By itself, BuildKit will cache the previous context and only send over the differences with the equivalent of rsync in the background.

For this specific case, you can use some experimental features to mount in your dependency cache as the equivalent of a named volume using the RUN --mount syntax. The cache directory never makes it into the image, but is there for later builds, and when you pull in a new dependency it will behave just like a local build, downloading only the new dependencies.

# syntax=docker/dockerfile:experimental
FROM openjdk:8 as build

RUN apt-get update &&\
    apt-get install -y apt-transport-https gnupg2 &&\
    echo "deb https://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list &&\
    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823 &&\
    apt-get update &&\
    apt-get install -y sbt=1.1.6

COPY app/source/ /app/source

RUN --mount=type=cache,target=/root/.ivy2 \
    cd /app/source &&\
    sbt assembly &&\
    cp target/scala-2.11/my-app-*.jar /app/my-app.jar

FROM gettyimages/spark:2.3.1-hadoop-3.0 as release

COPY --from=build /app/my-app.jar /app/my-app.jar

CMD ["spark-submit", "--master", "local", "/app/my-app.jar"]

To use BuildKit under 18.09, you can either export an environment variable:

export DOCKER_BUILDKIT=1

or update the engine with the new default in /etc/docker/daemon.json:

{ "features": {"buildkit": true} }
like image 184
BMitch Avatar answered Feb 26 '26 04:02

BMitch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!