Problem Description
When using docker build
to package an image, there is a need to access the network via a proxy. The following Dockerfile simulates this scenario:
FROM golang:1.12
RUN curl www.google.com --max-time 3
In a typical network environment in China, curl www.google.com
cannot return normally. The --max-time
option is added to ensure the curl command does not take too long.
Configuring the http_proxy Variable
First, you need to set the http_proxy
and https_proxy
environment variables so that network access commands (represented here by curl) can access www.google.com through the proxy server configured in the environment variables.
Although the docker build
command is executed on the host where Docker is located and seems to directly use the host’s network environment, in reality, docker build
also starts a container for building. Therefore, all commands during the build process are executed within the container, and the http_proxy
and https_proxy
configurations should also be done within the container. You can use ENV
to configure environment variables in the container.
The proxy server is started on port 1087 of the host. Modify the Dockerfile:
FROM golang:1.12
ENV http_proxy "http://127.0.0.1:1087"
ENV HTTP_PROXY "http://127.0.0.1:1087"
ENV https_proxy "http://127.0.0.1:1087"
ENV HTTPS_PROXY "http://127.0.0.1:1087"
RUN curl www.google.com --max-time 3
Re-running docker build
will show that curl still cannot access www.google.com. The error message indicates that there is no service on port 1087 of 127.0.0.1.
Accessing the Host
Since the container uses a bridged network by default, the host and the container are on the same level, placed in a virtual network segment. For the container, accessing the proxy server on the host is essentially accessing a server on another machine, and 127.0.0.1 points to the container itself. In Docker’s default bridged network, the host’s IP is usually 172.17.0.1 (Linux) or 192.168.65.1 (MacOS). You can change the IP in http_proxy
to 172.17.0.1/192.168.65.1 to access the network through the host’s proxy server. Modify the Dockerfile:
FROM golang:1.12
ENV http_proxy "http://172.17.0.1:1087"
ENV HTTP_PROXY "http://172.17.0.1:1087"
ENV https_proxy "http://172.17.0.1:1087"
ENV HTTPS_PROXY "http://172.17.0.1:1087"
RUN curl www.google.com --max-time 3
Although this method achieves the goal, if the build environment changes or the proxy server configuration changes, even if the operating system changes from Linux to MacOS, the Dockerfile needs to be modified, which is not decoupled enough and not convenient.
Configuring Network Mode
Docker also has a host network mode, which allows the container to use the host’s network, effectively not isolating the container from the host at the network layer. Using this network mode to execute docker build
eliminates the need to add http_proxy
environment variables in the Dockerfile, as the container can directly read the environment variables on the host.
First, import the http_proxy
environment variables on the host:
export http_proxy="http://127.0.0.1:1087"
export HTTP_PROXY="http://127.0.0.1:1087"
export https_proxy="http://127.0.0.1:1087"
export HTTPS_PROXY="http://127.0.0.1:1087"
Next, simplify the Dockerfile:
FROM golang:1.12
RUN curl www.google.com --max-time 3
Re-run docker build
with the --network host
parameter to use the host network:
docker build --network host .
After execution, curl can access www.google.com through the proxy just as if it were executed directly on the host.