I was following the "Build with Docker" guide from the official documentation (https://docs.docker.com/build/guide/test/), which suggests that one can utilize bind mounts to generate files during the build of a Docker image and export them to the filesystem.
However, I am running into the following error:
[lint-base 2/2] RUN --mount=type=bind,target=. echo "test" > lint-result:
0.258 /bin/sh: 1: cannot create lint-result: Read-only file system
...
ERROR: failed to solve: process "/bin/sh -c echo \"test\" > lint-result" did not complete successfully: exit code: 2
Here is the relevant part of the Dockerfile:
FROM scratch as lint-base
RUN --mount=type=bind,target=. \
echo "test" > lint-result
And this was the command for building this layer:
docker build --output=. --target=lint-base -t lint-debug --progress=plain .
I'm using Debian, and Docker was installed using apt. The Docker version is 25.0.4
.
Is this permission issue stemming from the way I installed Docker, or is it normal that during docker builds, it is not allowed to write changes to the filesystem mounted by bind?
Even if you use a bind mount in a Dockerfile, it still can't write out files to the host.
The Dockerfile RUN --mount=type=bind
documentation notes
A bind mount is read-only by default.
which is consistent with the "read-only filesystem" error you're getting. There is an additional option to make it read-write, but (emphasis mine)
rw
,readwrite
: Allow writes on the mount. Written data will be discarded.
The documentation page you link to does say you can export test results
...no different[ly from] exporting binaries, as shown in the previous section of this guide
More specifically the Export binaries documentation suggests a docker build --output=.
option that can use the Docker image builder but produce artifacts on the host by exporting the container filesystem. If the image is built FROM scratch
then "the container filesystem" will only include specific files you choose. That also means the image doesn't contain any tools at all, so you have to construct the files in an earlier build stage and COPY
them into the final image.
For your example this might look like:
FROM ubuntu AS build
WORKDIR /app
RUN echo test > lint-result
FROM scratch AS export
COPY --from=build /app/lint-result /
docker build --output=. --target=export .
I probably wouldn't use Docker here, but instead a shell script or Makefile to work with code and create files on the host.