Recently I tried to build a new Docker container at work, which restricts internet access and requires web traffic to go through a proxy.

Docker itself supports HTTP proxies. On Windows, the Docker for Windows settings interface has a little place to enter proxy settings, and then docker pull, docker push and so on work as you would expect them to.

But what about docker build? Commands to build up a container are run inside that container, so there's no access to the host configuration or the HTTP_PROXY environment variable. With Linux containers on Windows, that's all even happening inside a Hyper-V Virtual Machine, so there's no way at all to access host OS information.

The easiest way to get the build to access a container would be to slap the following line at the top of a Dockerfile:

ENV HTTP_PROXY http://my.proxy:1234

This would set an environment variable, HTTP_PROXY, and all subsequent commands inside the container would then use this proxy.

Unfortunately, this also means that when running the container, software will also use this environment variable. If I want to push this container outside of the office network, nobody else will be able to connect to the office proxy and the container will be unable to access the internet.

Buried in a comment on GitHub (that I can no longer find), I came across a much better way, docker build --build-arg. This command-line option allows the user to pass an environment variable into the container that is only used when building the container. It does not get saved into the container for runtime.

And, as it turns out, HTTP_PROXY is even the example used in Docker's documentation for this command-line option.

So, to set a proxy inside the container at build-time only, one can use --build-arg like so:

$ docker build . --build-arg HTTP_PROXY=http://my.proxy:1234