I attempt to extract the build artifact from the builder to the local filesystem.
<...>
WORKDIR /src
RUN --mount=type=cache,target=/go \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=bind,source=./,target=/src \
go get
FROM cache AS build
ARG MAKEOPTS
WORKDIR /src
RUN --mount=type=bind,source=./,target=/src,rw \
--mount=type=tmpfs,destination=/src/release \
make ${MAKEOPTS}
FROM scratch AS binaries
COPY --from=build /src/release/telegabber /
But it fails with a failed to compute cache key error, seemingly because the mount does not in fact belong to the build stage. And I see no way to specify it.
In fact, I use the second tmpfs mount as a way to circumvent the issue of files written over the bind mount being discarded, so I’d like to know if there is a way to make the /src/release belong to the image instead, being excluded from the bind mount, or so.
Initially I went with an approach of copying the source files to an image, but it generates too much of intermediate data and clogs the disk space quickly which I’d like to circumvent with a bind mount.
A build stage is practically an image from which you can copy files to a new stage. I have never thought of this, but it is understandable that you can1T mount into an image, only into a container which is the stage to which you want to copy the files.
Either you copy the release file to the image filesystem in any stage or use bind mount in the binaries stage and add a small “copy-release” binary as well which can copy the release file from the mounted folder to its final destination in a RUN instrucion instead of using the COPY instruction.
Sidenote: docker.io is not the official Docker CE package. The supported Docker package can be installed as described in the documentation:
Okay, I changed it so the build is intermediately copied to a cache mount:
FROM cache AS build
ARG MAKEOPTS
WORKDIR /src
RUN --mount=type=bind,source=./,target=/src,rw \
--mount=type=cache,destination=/src/release \
make ${MAKEOPTS}
FROM build AS release
RUN --mount=type=cache,destination=/src/release \
cp /src/release/telegabber /
FROM scratch AS binaries
COPY --from=release /telegabber /
This way no new cache entries should be spawned for every build, at least. Though the cache doesn’t seem to be reused properly there; go get still seems to re-download everything on every run.
And disk usage grows, so after a few rebuilds I have to prune the cache eventually (and I could not figure out the filter syntax yet, so I have to prune everything, including the prolonged TDLib compilation stage which doesn’t really need to be repeated). Pre-BuildKit builder stage artifacts are easier to clean precisely, but it doesn’t support cache mounts