docker / docker/buildx

If the context is defined in the bake file, ARGs are not propagated as environment variables

Open
#1,709 4 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind/bug status/triage
Dominant language
Go
Stars
4.5k
Forks
682
Avg merge
2d 14h
Merged PRs (30d)
29

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

I don't know whether this a buildx or buildkit issue. Consider the following Dockerfile:

FROM alpine as stage1
ARG MYARG=foo
RUN env | grep "MYARG"

FROM stage1 as stage2
RUN env | grep "MYARG"

If I run docker-build directly MYARG is also available as an environment variable in stage2:

$ docker buildx build --progress=plain --output=type=cacheonly --no-cache --target stage2 .
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 145B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.6s

#4 [stage1 1/2] FROM docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126
#4 resolve docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126 done
#4 CACHED

#5 [stage1 2/2] RUN env | grep "MYARG"
#0 0.052 MYARG=foo
#5 DONE 0.1s

#6 [stage2 1/1] RUN env | grep "MYARG"
#0 0.027 MYARG=foo
#6 DONE 0.0s

It is also possible to set MYARG in the CLI args:

$ docker buildx build --progress=plain --output=type=cacheonly --no-cache --target stage2 --build-arg MYARG=bar .
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 145B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.6s

#4 [stage1 1/2] FROM docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126
#4 resolve docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126 done
#4 CACHED

#5 [stage1 2/2] RUN env | grep "MYARG"
#0 0.049 MYARG=bar
#5 DONE 0.1s

#6 [stage2 1/1] RUN env | grep "MYARG"
#0 0.046 MYARG=bar
#6 DONE 0.1s

Not let's take the following docker-bake.hcl:

target "stage1" {
    target = "stage1"
    args = {
        MYARG = "bar"
    }
    output = ["type=cacheonly"]
}

target "stage2" {
    target = "stage2"
    output = ["type=cacheonly"]
}
$ docker buildx bake --progress=plain --no-cache stage2
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 145B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.6s

#4 [stage1 1/2] FROM docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126
#4 resolve docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126 done
#4 CACHED

#5 [stage1 2/2] RUN env | grep "MYARG"
#0 0.049 MYARG=foo
#5 DONE 0.1s

#6 [stage2 1/1] RUN env | grep "MYARG"
#0 0.027 MYARG=foo
#6 DONE 0.0s

I guess MYARG equals foo as its context is resolved from buildkit internally and not from the docker-bake file. If I now add the context:

target "stage1" {
    target = "stage1"
    args = {
        MYARG = "bar"
    }
    output = ["type=cacheonly"]
}

target "stage2" {
    target = "stage2"
    contexts = {
        stage1 = "target:stage1"
    }
    output = ["type=cacheonly"]
}
$ docker buildx bake --progress=plain --no-cache stage2
#1 [stage1 internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#2 [stage1 internal] load build definition from Dockerfile
#2 transferring dockerfile: 145B done
#2 DONE 0.0s

#3 [stage1 internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.6s

#4 [stage2 internal] load .dockerignore
#4 transferring context: 2B done
#4 DONE 0.0s

#5 [stage2 internal] load build definition from Dockerfile
#5 transferring dockerfile: 145B done
#5 DONE 0.0s

#6 [stage2 stage1 1/2] FROM docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126
#6 resolve docker.io/library/alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126 done
#6 CACHED

#7 [stage2 stage1 2/2] RUN env | grep "MYARG"
#0 0.742 MYARG=bar
#7 DONE 0.2s

#8 [stage2 stage2 1/1] RUN env | grep "MYARG"
#8 ERROR: process "/bin/sh -c env | grep \"MYARG\"" did not complete successfully: exit code: 1
------
 > [stage2 stage2 1/1] RUN env | grep "MYARG":
------
Dockerfile:9
--------------------
   7 |     FROM stage1 as stage2
   8 |     
   9 | >>> RUN env | grep "MYARG"
  10 |     
--------------------
ERROR: failed to solve: process "/bin/sh -c env | grep \"MYARG\"" did not complete successfully: exit code: 1

I guess MYARG is set to bar in stage1, however it's not available as a environment variable in stage2 anymore.

The use case for this is that I have a builder stage where a set a couple of ARGs once and then use them as environment variables in subsequent stages.

Expected behaviour

I would expect ARGs to be available as environment variables in stages set as context targets.

Actual behaviour

ARGs are not available as environment variables in stages set as context targets. This feels inconsistent. Basically, the same thing works when using the docker-build CLI arguments.

Buildx version

github.com/docker/buildx v0.10.4 c513d34049e499c53468deac6c4267ee72948f02

Docker info
Client:
 Context:    desktop-linux
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.10.4)
  compose: Docker Compose (Docker Inc., v2.15.1)
  dev: Docker Dev Environments (Docker Inc., v0.1.0)
  extension: Manages Docker extensions (Docker Inc., v0.2.18)
  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.6.0)

Server:
 Containers: 3
  Running: 1
  Paused: 0
  Stopped: 2
 Images: 28
 Server Version: 20.10.23
 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: 2
 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
  cgroupns
 Kernel Version: 5.15.49-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: aarch64
 CPUs: 8
 Total Memory: 15.61GiB
 Name: docker-desktop
 ID: [redacted]
 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:5000
  127.0.0.0/8
 Live Restore Enabled: false
Builders list
NAME/NODE           DRIVER/ENDPOINT  STATUS  BUILDKIT PLATFORMS
docker-container *  docker-container
  docker-container0 desktop-linux    running v0.11.4  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.23 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
desktop-linux       docker
  desktop-linux     desktop-linux    running 20.10.23 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Configuration

See above.

Build logs
See above.
Additional info

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Dockerfile and docker-bake.hcl examples in the issue, then run the shown docker buildx bake command with the stage1 context target. Compare the ARG environment behavior with direct buildx CLI arguments. Done means the context-target build preserves the expected ARG environment variable in stage2, with a regression test covering the example.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go
Domain
build-system, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.