Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support bind Build Mounts (RUN --mount=type=bind / RUN --mount) like BuildKit and Buildah do #1568

Open
guillaume-d opened this issue Feb 1, 2021 · 12 comments
Labels
area/dockerfile-command For all bugs related to dockerfile file commands categorized differs-from-docker feat/docker-syntax issue/mount kind/enhancement New feature or request kind/feature-request priority/p0 Highest priority. Break user flow. We are actively looking at delivering it. priority/p1 Basic need feature compatibility with docker build. we should be working on this next. works-with-docker

Comments

@guillaume-d
Copy link

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:

@carnott-snap
Copy link

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

@agowa
Copy link

agowa commented Aug 16, 2021

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.

@alchemistake
Copy link

Congratulations on 1 year anniversary of this issue. Will it be every added?

@kvaps
Copy link
Contributor

kvaps commented Feb 14, 2022

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.

@agowa
Copy link

agowa commented Feb 14, 2022

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.

@hermanbanken
Copy link
Contributor

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.

@guillaume-d
Copy link
Author

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 or ssh, and only fail when required or for other types, like bind, cache or tmpfs.

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 😉): one syntax's parser would have to know about all other syntaxes' parsers or future syntaxes!

@guillaume-d
Copy link
Author

guillaume-d commented Apr 29, 2022

Concerning RUN --mount=type=secret, it should be less difficult to implement than all other types:

  • copying the secrets is no big deal as they ought to be small, especially compared to caches
  • if we copy, we should not need special capabilities and be able to set file permissions on the copies as we please
  • Buildah >= 1.24 (and apparently podman buildfrom Podman >= 3.3) can do secrets already 😍 (and recently docker-compose >= v2.5.0 too), but not necessarily the other mount types

Also now we know the syntax already works, see my previous comment.

@guillaume-d
Copy link
Author

FYI Buildah >= 1.24 (which is shipped with Podman >= 4) also supports RUN --mount=type=bind.

@guillaume-d guillaume-d changed the title Support bind Build Mounts (RUN --mount=type=bind / RUN --mount) like BuildKit does Support bind Build Mounts (RUN --mount=type=bind / RUN --mount) like BuildKit and Buildah do Apr 29, 2022
@aaron-prindle aaron-prindle added kind/enhancement New feature or request differs-from-docker priority/p1 Basic need feature compatibility with docker build. we should be working on this next. area/dockerfile-command For all bugs related to dockerfile file commands labels May 30, 2023
@aaron-prindle aaron-prindle added issue/mount works-with-docker kind/feature-request priority/p0 Highest priority. Break user flow. We are actively looking at delivering it. labels Jun 22, 2023
@NfNitLoop
Copy link

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. 😢

@rd-danny-fleer
Copy link

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.

@agowa
Copy link

agowa commented Jul 9, 2024

@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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/dockerfile-command For all bugs related to dockerfile file commands categorized differs-from-docker feat/docker-syntax issue/mount kind/enhancement New feature or request kind/feature-request priority/p0 Highest priority. Break user flow. We are actively looking at delivering it. priority/p1 Basic need feature compatibility with docker build. we should be working on this next. works-with-docker
Projects
None yet
Development

No branches or pull requests

9 participants