Running Docker inside a large corporate network often means that direct internet access is blocked and all outbound traffic must pass through an HTTP proxy. Docker’s default behavior assumes unrestricted internet access, so you will hit connectivity errors when trying to pull images or install packages inside a container. This article walks through every layer of proxy configuration you need to address: the Docker daemon, the container build environment, and the container runtime.
The Problem: Two Separate Network Contexts
A proxy misconfiguration with Docker almost always comes down to one misunderstood fact: there are two separate network contexts that each need independent proxy settings.
- The Docker daemon — responsible for pulling base images from registries such as Docker Hub.
- The container build/run environment — the isolated environment in which your
RUNinstructions execute. Tools likeapt-get,yum,curl, andpiprun here and have no knowledge of the host’s proxy settings.
Configuring one without the other will leave you with partial failures. The sections below address each context in turn.
A Simple Example Dockerfile
Throughout this article we will use a minimal Ubuntu-based image that installs curl via apt-get. This is intentionally simple, but it exercises both proxy contexts.
FROM ubuntu
RUN apt-get update && apt-get install -y curlCode language: JavaScript (javascript)
Attempting to build this image on a network with no direct internet access produces an error immediately at the FROM step:
$ sudo docker build -t curl .
Sending build context to Docker daemon 12.29 kB
Step 0 : FROM ubuntu
Pulling repository ubuntu
INFO[0002] Get https://index.docker.io/v1/repositories/library/ubuntu/images: dial tcp 52.22.146.88:443: connection refusedCode language: JavaScript (javascript)
The daemon cannot reach Docker Hub because outbound TCP connections are blocked. Fix this first.
Step 1 — Configuring the Docker Daemon to Use a Proxy (Ubuntu host)
On Ubuntu hosts that use the older SysV init system, Docker’s environment is sourced from /etc/default/docker. That file includes a commented-out proxy line:
# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"Code language: PHP (php)
Uncomment the line and replace the placeholder with your actual proxy address:
# If you need Docker to use an HTTP proxy, it can also be specified here.
export http_proxy="http://192.168.33.10:3128/"Code language: PHP (php)
If your proxy requires authentication, embed the credentials in the URL:
export http_proxy="http://username:password@192.168.33.10:3128/"Code language: JavaScript (javascript)
systemd-based hosts
Most modern Ubuntu and Debian installations (16.04 and later) manage Docker with systemd, which does not read /etc/default/docker for environment variables. For systemd, create a drop-in override file instead:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://192.168.33.10:3128/"
Environment="HTTPS_PROXY=http://192.168.33.10:3128/"
Environment="NO_PROXY=localhost,127.0.0.1"
EOF
sudo systemctl daemon-reload
sudo systemctl restart dockerCode language: JavaScript (javascript)
For the SysV approach, restart Docker with the service command:
# service docker restart
docker stop/waiting
docker start/running, process 32703Code language: PHP (php)
After restarting, docker pull and the FROM step of a build will route through your proxy. However, RUN instructions that use apt-get or other network tools will still fail because the container environment has no proxy configured.
Step 2 — Configuring the Proxy Inside the Container
After configuring the daemon proxy, re-running the build pulls the Ubuntu base image successfully — but apt-get update immediately fails:
Step 1 : RUN apt-get update && apt-get install -y curl
---> Running in 39b964be90bc
Err:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Cannot initiate the connection to archive.ubuntu.com:80. - connect (101: Network is unreachable)
E: Unable to locate package curlCode language: JavaScript (javascript)
This happens because the container’s network environment is isolated from the host. The http_proxy variable set on the host is not inherited inside the container’s build shell.
Option A — Pass proxy settings as build arguments
Use --build-arg to inject the proxy at build time without hardcoding it in the Dockerfile:
$ sudo docker build -t curl \
--build-arg http_proxy=http://192.168.33.10:3128 \
--build-arg https_proxy=http://192.168.33.10:3128 \
.Code language: JavaScript (javascript)
This approach is preferred when you want to keep the Dockerfile portable — colleagues on networks without a proxy can build the same file without modification.
Option B — Set proxy variables in the Dockerfile with ENV
Alternatively, declare the proxy variables directly in the Dockerfile using ENV instructions:
FROM ubuntu
ENV http_proxy "http://192.168.33.10:3128"
ENV https_proxy "http://192.168.33.10:3128"
RUN apt-get update && apt-get install -y curlCode language: JavaScript (javascript)
Both apt-get and curl respect the standard http_proxy / https_proxy environment variables, so this is sufficient for most Linux package managers and command-line HTTP tools.
Step 3 — Verifying the Build and Runtime Behaviour
With proxy variables set, the build completes successfully:
$ sudo docker build -t curl .
...
Step 1 : ENV http_proxy "http://192.168.33.10:3128"
Step 2 : ENV https_proxy "http://192.168.33.10:3128"
Step 3 : RUN apt-get update && apt-get install -y curl
Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
...Code language: JavaScript (javascript)
Running the container and making an outbound request with curl shows that traffic is also routed through the proxy at runtime:
$ sudo docker run curl curl -v http://example.com
* Trying 192.168.33.10...
> GET http://example.com/ HTTP/1.1
> Proxy-Connection: Keep-Alive
< HTTP/1.1 200 OKCode language: JavaScript (javascript)
Notice the Proxy-Connection header — the request was forwarded via the proxy.
Unsetting Proxy Variables After the Build Step
Because ENV instructions persist into the running container, any process that respects http_proxy will automatically use the proxy at runtime — which may not be what you want if the proxy is only reachable from the build network. To scope proxy settings to the build phase only, unset them after your package installation step:
FROM ubuntu
ENV http_proxy "http://192.168.33.10:3128"
ENV https_proxy "http://192.168.33.10:3128"
RUN apt-get update && apt-get install -y curl
ENV http_proxy ""
ENV https_proxy ""Code language: JavaScript (javascript)
When the container is launched with docker run, the proxy variables will be empty and outbound connections from application code will go directly to the network (or fail gracefully if the runtime network also requires a proxy).
Alternatively, you can override environment variables at runtime without modifying the Dockerfile:
$ sudo docker run -e http_proxy="" -e https_proxy="" curl curl http://example.comCode language: JavaScript (javascript)
Docker Desktop (Mac and Windows)
Docker Desktop on macOS and Windows exposes proxy settings through the application’s graphical preferences panel. Navigate to Settings → Resources → Proxies and enable Manual proxy configuration to specify HTTP and HTTPS proxy addresses.
This configures the Docker Desktop daemon’s outbound proxy for image pulls. It does not automatically inject proxy variables into container build or run environments — you still need to use ENV instructions or --build-arg for that.
Quick Reference: Which Setting Does What
| Configuration | What it affects | Required for image pulls | Required for in-container network access |
|---|---|---|---|
/etc/default/docker or systemd drop-in | Docker daemon process | Yes | No |
--build-arg http_proxy=… | Build-time environment only | No | Yes (build only) |
ENV http_proxy in Dockerfile | Build-time and runtime environment | No | Yes (build and run) |
docker run -e http_proxy=… | Runtime environment only | No | Yes (run only) |
| Docker Desktop Proxies UI | Docker daemon process on Mac/Windows | Yes | No |
Summary
Getting Docker to work behind a corporate proxy requires addressing two independent layers:
- The Docker daemon — configure
HTTP_PROXY/HTTPS_PROXYvia the systemd drop-in file (modern systems) or/etc/default/docker(older SysV systems), then restart the service. - The container environment — pass proxy settings via
--build-argorENVinstructions in the Dockerfile so that package managers and other tools inside the container can reach external repositories.
Remember that ENV-declared proxy variables persist into the running container. Unset them after your installation steps, or override them with docker run -e, if you do not want runtime traffic to traverse the proxy.