..

Adding files to Docker container without COPY

When building a Docker container, it is sometimes required to add additional files to the image that are needed during the build process. One example for this would be a locally built Debian package that should be installed in a Docker container.

The problem with COPY

The easy way to do this would be to just copy the file during the build process:

FROM debian
COPY libutempter0_1.2.1-2_amd64.deb /tmp
RUN dpkg -i /tmp/libutempter0_1.2.1-2_amd64.deb \
    && rm /tmp/*

The problem with this approach is obvious when looking at the layers created (docker history):

RUN /bin/sh -c dpkg -i /tmp/libutempter0_1.2…   213kB
COPY libutempter0_1.2.1-2_amd64.deb /tmp # b…   8.96kB
/bin/sh -c #(nop)  CMD ["bash"]                 0B
/bin/sh -c #(nop) ADD file:c13b430c8699df107…   124MB

Even though the .deb file is no longer visible because we deleted it, it is still part of the previous layer and takes up valuable disk space. (Of course those 8.96kB don’t matter that much, but this is just a placeholder for any large file).

RUN –mount

Luckily, Docker now supports mounting stuff during the build process:

# syntax=docker/dockerfile:1.4

FROM debian as stage1
RUN mkdir /packages
COPY libutempter0_1.2.1-2_amd64.deb /packages

FROM debian
RUN --mount=type=bind,from=stage1,source=/packages,target=/packages \
    dpkg -i /packages/libutempter0_1.2.1-2_amd64.deb

This way, we don’t have to pay for this temporary stage.

RUN /bin/sh -c dpkg -i /packages/libutempter…   213kB
/bin/sh -c #(nop)  CMD ["bash"]                 0B
/bin/sh -c #(nop) ADD file:c13b430c8699df107…   124MB