BuildKit’s buildargs don’t just pass arbitrary strings; they’re a first-class mechanism for injecting configuration into your builds, and that includes network settings like HTTP proxies.

Let’s see this in action. Imagine you’re building an image that needs to download a package from a private repository, and your network requires an HTTP proxy.

# First, set your proxy environment variables locally
export HTTP_PROXY="http://proxy.example.com:8080"
export HTTPS_PROXY="http://proxy.example.com:8080"
export NO_PROXY="localhost,127.0.0.1,.example.internal"

# Now, build your Dockerfile, passing these as build args
DOCKER_BUILDKIT=1 docker build \
  --build-arg HTTP_PROXY \
  --build-arg HTTPS_PROXY \
  --build-arg NO_PROXY \
  -t my-proxied-app .

And in your Dockerfile:

# This will use the HTTP_PROXY build arg if set
RUN apt-get update && apt-get install -y some-package

# Or you can explicitly use the build arg in a RUN command
RUN echo "Proxy is: $HTTP_PROXY"

# You can also use it in other contexts, like downloading files
RUN curl -fSL "https://download.example.com/file.tar.gz" -o file.tar.gz

When docker build runs with DOCKER_BUILDKIT=1, it intercepts the --build-arg flags. If the value for a build argument is not explicitly provided on the command line (e.g., --build-arg HTTP_PROXY=value), BuildKit will look for an environment variable with the same name on the host machine and use its value. This is precisely what we leveraged above by exporting HTTP_PROXY, HTTPS_PROXY, and NO_PROXY.

The RUN instruction within the Dockerfile then consumes these build arguments as environment variables. The apt-get update command, for instance, respects the HTTP_PROXY and HTTPS_PROXY environment variables automatically if they are set within the build container’s environment. Similarly, curl will use these proxy settings if they are available.

The core problem this solves is enabling reproducible builds in environments with restrictive network policies. Without passing proxy settings, your build might fail when trying to download dependencies from external sources, especially if those sources are only accessible via an internal proxy. By making proxy settings a build argument, you externalize this network configuration from the Dockerfile itself, allowing different network environments (e.g., your laptop vs. a CI server) to build the same image successfully by simply adjusting the build-arg values or host environment variables.

BuildKit’s --build-arg mechanism is designed to populate the build-time environment. When you pass --build-arg NAME without a value, it’s a shortcut for --build-arg NAME=$NAME. This means BuildKit reads the environment variable NAME from the shell where you’re running the docker build command and passes its value into the build context as a build argument. These build arguments are then available as environment variables within the RUN instructions of your Dockerfile. This is distinct from runtime environment variables, which are passed using the --env flag during docker run.

The NO_PROXY variable is crucial for ensuring that traffic to internal or explicitly allowed hosts bypasses the proxy, which is often necessary for accessing local services or private networks during a build.

A common pitfall is forgetting to export the proxy variables in the same shell session where you execute the docker build command. If you export them in one terminal and then run docker build in another without re-exporting, BuildKit won’t find the environment variables and thus won’t pass them as build arguments.

You might encounter issues where curl or wget within the build still don’t pick up the proxy settings even when the build arguments are correctly passed. This is often because the specific tool might have its own configuration files (like ~/.curlrc or ~/.wgetrc) that override or ignore environment variables. In such cases, you might need to explicitly configure these tools within the Dockerfile itself, perhaps by creating a temporary configuration file that references the build-arg proxy variables.

The next hurdle you’ll likely face is managing secrets for proxy authentication, which requires a different approach than simple build arguments.

Want structured learning?

Take the full Buildkit course →