Skip to content

Load just file(s) needed in build context rather than full directory tree #1765

Open
moby/buildkit
#4161
@berney

Description

Contributing guidelines

I've found a bug and checked that ...

  • ... the documentation does not mention anything about my problem
  • ... there are no open or closed issues that are related to my problem

Description

Setting an additional context that is from another directory to where the Dockerfile is, will copy the whole directory, rather than just the files referenced in the COPY commands.

I logged this regarding the docs, docker/docs#17214.

Expected behaviour

docker buildx build --build-arg stage3_file=stage3-amd64-hardened-nomultilib-openrc-20230423T164653Z.tar.xz --build-context tarball=$HOME/.kubler/downloads -t berne/stage3 .

Will copy only the 247MiB stage3-amd64-hardened-nomultilib-openrc-20230423T164653Z.tar.xz from $HOME/.kubler/downloads as the context.

In the docs https://github.com/docker/docs/blob/4d4a7352d1a60df0af09d74683ae16f2de84a5a6/build/building/context.md?plain=1#L62

It says:

The legacy builder sends the entire directory to the daemon, including bar
and node_modules directories, even though the Dockerfile does not use
them. When using BuildKit, the client only sends the
files required by the COPY instructions, in this case foo.

Actual behaviour

Buildx copies the entire 9.5GiB directory.

Buildx version

github.com/docker/buildx v0.10.4 c513d34

Docker info

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.10.4)
  compose: Docker Compose (Docker Inc., v2.17.2)
  dev: Docker Dev Environments (Docker Inc., v0.1.0)
  extension: Manages Docker extensions (Docker Inc., v0.2.19)
  init: Creates Docker-related starter files for your project (Docker Inc., v0.1.0-beta.2)
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan: Docker Scan (Docker Inc., v0.25.0)
  scout: Command line tool for Docker Scout (Docker Inc., v0.9.0)

Server:
 Containers: 3
  Running: 1
  Paused: 0
  Stopped: 2
 Images: 94
 Server Version: 20.10.24
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 2456e983eb9e37e47538f59ea18f2043c9a73640
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 5.10.102.1-microsoft-standard-WSL2
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 8
 Total Memory: 7.763GiB
 Name: docker-desktop
 ID: ZOWA:TFVA:ET24:T2FX:6V5H:65BG:IMK5:STLD:PTXH:LKKL:HYLH:PSSI
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5555
  127.0.0.0/8
 Live Restore Enabled: false

Builders list

NAME/NODE     DRIVER/ENDPOINT             STATUS  BUILDKIT PLATFORMS
berney *      docker-container                             
  berney0     unix:///var/run/docker.sock running v0.11.5  linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default       docker                                       
  default     default                     running 20.10.24 linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
desktop-linux                             error

Configuration

# syntax=docker/dockerfile:1
FROM scratch AS tarball
ARG stage3_file
COPY ${stage3_file} /

Build logs

docker buildx build --build-arg stage3_file=stage3-amd64-hardened-nomultilib-openrc-20230423T164653Z.tar.xz --build-context tarball=$HOME/.kubler/downloads -t berne/stage3 .
WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
[+] Building 148.7s (6/6) FINISHED
 => [internal] load .dockerignore                                                                                  0.1s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load build definition from Dockerfile                                                               0.1s
 => => transferring dockerfile: 128B                                                                               0.0s
 => resolve image config for docker.io/docker/dockerfile:1                                                         2.1s
 => CACHED docker-image://docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4  0.0s
 => => resolve docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409  0.0s
 => [context tarball] load .dockerignore                                                                           0.0s
 => => transferring tarball: 2B                                                                                    0.0s
 => [context tarball] load from client                                                                           145.7s
 => => transferring tarball: 10.19GB                                                                             145.4s

Additional info

I read https://www.docker.com/blog/dockerfiles-now-support-multiple-build-contexts/ where Example #3: Override a Remote Dependency with a Local One shows overriding a context, which is what I want to do to allow copying the file from elsewhere, but I don't want to copy a huge directory when I just want a single file.

I want to avoiding having to create a directory, link the file, run docker buildx, and then clean up the tmp directory.

If the Dockerfile is in the 9.5GiB ~/.kubler/downloads directory, then docker buildx build --build-arg stage3_file=stage3-amd64-hardened-nomultilib-openrc-20230423T164653Z.tar.xz -t berne/stage3 . will copy just the 247MiB file.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions