Open guillaume-d opened 3 years ago
We are looking to use a single Dockerfile
and need to inject credentials for local builds. Our expectation is that koniko would never need these, since it manages things internally, but it looks like even parsing these flags is unsupported:
error building image: parsing dockerfile: Dockerfile parse error line 6: Unknown flag: mount
As a start, we could simply parse and ignore the ones that are not supported, like secret
or ssh
, and only fail when required
or for other types, like bind
, cache
or tmpfs
.
Also the above error is pretty generic, and it would make more sense to do a check of the syntax directive, and fail there:
# syntax = docker/dockerfile:1.2
any update on this?
I currently use RUN --mount=type=bind
to have the working directory accessible within the container without adding it to the layer. I use this to install a very large deb file. Copying the deb file into the container and then installing it would double the size.
Congratulations on 1 year anniversary of this issue. Will it be every added?
The problem of this issue is that mount operation requires extra permissions.
Actually we have two options how we can to implement it without them:
1) Copy layer data into build context during the run
2) Use mv
or ln -s
to "mount" layer data to build context, but in this way the layer content can be modified by the RUN command itself
I think the first option is better, because this will not violate the Dockerfile specification. Or we can make this behavior configurable via executor flag, eg: --bind-mount-method=<copy|symlink|mount>
, where mount
method will require additional CAP_SYS_ADMIN
permissions.
The intend is to have files in a folder, from a previous layer (or a special device from /dev) available while building, but to not include it within the layer. Anything that makes this possible will be appreciated. At the end of the day it's irrelevant if it's a symlink, a mount or (at least for files) a copy. As long as it doesn't get included in the layer.
A cache could typically be a few gigabytes. I think it would be advisable to at least have the option of symlink/mount instead of a plain copy.
We are looking to use a single
Dockerfile
and need to inject credentials for local builds. Our expectation is that koniko would never need these, since it manages things internally, but it looks like even parsing these flags is unsupported:error building image: parsing dockerfile: Dockerfile parse error line 6: Unknown flag: mount
Starting from kaniko 1.8.0, the mere syntax for the credentials is supported, as well as all other syntax added by syntax=docker/dockerfile:1.2.0. Cause (AFAICU): GH-1866 / GH-1885, where for some reason the image builder got bumped from an ancient Docker version to BuildKit v0.8.3, which happens to support that much syntax (but alas not dockerfile >= 1.3 (like for example 1.4+'s heredocs), as requested in #1712 and #1713 (heredocs)). Proof: see some compatibility tests' results for kaniko, especially those for dockerfile:1.2 using kaniko v1.8.0.
As a start, we could simply parse and ignore the ones that are not supported, like
secret
orssh
, and only fail whenrequired
or for other types, likebind
,cache
ortmpfs
.
As said above, parsing those already works, but this does not offer much more, there are few things to be gained for just the syntax being accepted, even WRT compatibility with BuildKit: only few useful things require only syntax and/or are completely backward-compatible:
# syntax=docker/dockerfile:1.2
# purely syntactic, so it indeed works,
# see <https://gitlab.com/iguillaumed/playground/dockerfile-standard/-/jobs/2395435878>:
ARG k1=v1 k2=v2
# purely syntactic, so it indeed works,
# see <https://gitlab.com/iguillaumed/playground/dockerfile-standard/-/jobs/2395435878>:
ADD --chown=$owner:$group ARG...
# when purely syntactic, the key will never be available, so
# required=true will not work as expected / could be insecure:
RUN --mount=type=ssh CMD
# when purely syntactic, the secret will never be available, so
# required=true will not work as expected / could be insecure:
RUN --mount=type=secret CMD
In the future (some kaniko version after 1.8.1):
# syntax=docker/dockerfile:1.3
# the default:
RUN --network=default CMD
# insecure when purely syntactic, but functionally equivalent to no --network:
RUN --network=none CMD
# syntax=docker/dockerfile:1.4
# in most cases functionally equivalent to no --link
# (just make sure by testing with a full implementation like BuildKit that --link may really be used),
# but no performance gain of course when purely syntactic:
COPY --link ARG...
# to be explicit when/if --link cannot be used:
COPY --link=false ARG...
# the same as above but with ADD instead of COPY
# just speculating here, but heredocs should be purely syntactic:
RUN <<EOT
apt-get update
apt-get install -y vim
EOT
Also the above error is pretty generic, and it would make more sense to do a check of the syntax directive, and fail there:
# syntax = docker/dockerfile:1.2
As one can see in my compatibility tests' result for dockerfile:1.3 using kaniko v1.8.1, the error messages have not gotten better (this time for RUN --network=none
):
error building image: parsing dockerfile: dockerfile parse error line 5: Unknown flag: network
However they might come directly from BuildKit, so maybe they could(/must?) be improved there instead, for example as suggested below:
error building image: parsing dockerfile: dockerfile parse error line 5: Unknown flag with syntax = docker/dockerfile:1.2: network
Even more precise error messages WRT the needed syntax would go against BuildKit's syntax modularity idea (and against the flow of time itself :wink:): one syntax's parser would have to know about all other syntaxes' parsers or future syntaxes!
Concerning RUN --mount=type=secret
, it should be less difficult to implement than all other types:
podman build
from Podman >= 3.3) can do secrets already 😍 (and recently docker-compose >= v2.5.0 too), but not necessarily the other mount typesAlso now we know the syntax already works, see my previous comment.
FYI Buildah >= 1.24 (which is shipped with Podman >= 4) also supports RUN --mount=type=bind.
At least if these options aren't supported, they should cause a Kaniko build to fail so the user doesn't think they're getting these advantages (cacheing) or go off on wild goose chases trying to figure out why files are missing when in reality --mount=from=previousStage
just failed silently. 😢
Any news on this topic? Support for build mounts would be very useful. Currently I have to COPY some files to the image to install them. This makes them persist in the final image. Build mounts would be a perfect solution to make the files temporary available without adding them to the image.
@rd-danny-fleer Look at this and the following sections within the docs https://docs.docker.com/reference/dockerfile/#run---mount besides that your options are using a different tool to create the images. By now there are a lot of tools that support the OCI spec.
And if all of these aren't enough you can always opt for a multi stage build to squash all layers into one:
FROM someImage:someTag AS WithManyDirtyLayers
COPY bigFileInto container
RUN dpkg -i bigFileInContainer.deb
RUN do stuff
FROM scratch
COPY --from=WithManyDirtyLayers / /
# ENTRYPOINT
# CMD
HOWEVER instead of this approach that looses all of the layer information I'd suggest first trying to statically link your application and have a container with only your applications binary copied into (aka without any linux user land)
For more details see https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md
That would help avoiding contortions in the Dockerfile due to COPY's silly "partial flattening" of file hierarchies...
Also for performance some of the other types would be nice:
RUN --mount=type=tmpfs
RUN --mount=type=cache
, but this is #969 already (please vote at https://github.com/GoogleContainerTools/kaniko/issues/969#issuecomment-622497153 if you are interested!) but these as a first step may be no-op implementations (just to have better compatibility with BuildKit), whereasRUN --mount=type=bind
cannot be faked