A Docker proxy is three separate settings that people often mix up: the daemon proxy that dockerd uses to pull images, the build proxy passed to docker build as --build-arg HTTPS_PROXY=..., and the container proxy passed to running containers as environment variables. Setting one never sets the others. For most scraping jobs you want the third:

docker run --rm -e HTTPS_PROXY="http://USERNAME:PASSWORD@HOST:PORT" \
  curlimages/curl -sS "https://api.ipify.org?format=json"

We ran the build and container commands on this page on 2026-09-30 with Docker Engine 29.8, BuildKit 0.33 and Compose 5.5 against a local proxy that enforces a username and password. The daemon settings were checked against the Docker daemon proxy docs the same day but not applied.

Before you start

  1. Open your order in the dashboard at https://app.proxyhive.io.
  2. Copy HOST, PORT (the HTTP port), USERNAME and PASSWORD. Every datacenter or ISP IP is its own endpoint.
  3. Keep them in a file outside the repository, readable only by you:
printf 'HTTPS_PROXY=http://USERNAME:PASSWORD@HOST:PORT\nNO_PROXY=localhost,127.0.0.1\n' > ~/proxy.env
chmod 600 ~/proxy.env

An IP allowlist on the order removes the password from the URL entirely, which is the cleanest option for a fixed build server. Username and password vs IP allowlist weighs the two.

The three Docker proxies at a glance

What goes through the proxyWhere you set itUsed by
Image pulls and registry loginssystemd drop-in, daemon.json, or Docker Desktop settingsdockerd
RUN steps during a build--build-arg, Compose build.args, or ~/.docker/config.jsonthe build container
Traffic from your running app-e, --env-file, Compose environment, or ~/.docker/config.jsonthe container

Docker container proxy environment variables

Pass the variables at run time. The env file from above keeps the password off the command line and out of shell history:

docker run --rm --env-file ~/proxy.env curlimages/curl -sS "https://api.ipify.org?format=json"

Three details that bit us in testing:

  • HTTP_PROXY covers http:// URLs only. With only HTTP_PROXY set, curl sent an https request straight out. Set HTTPS_PROXY for https targets.
  • Many tools read the lowercase names, and curl reads http_proxy in lowercase only. Setting both cases is harmless.
  • Anything passed with -e is stored in the container config. docker inspect printed our full proxy URL, password included, so treat access to the Docker socket as access to the credentials.

Docker Compose proxy

Compose reads a .env file next to compose.yaml for substitution. Keep .env in .gitignore:

services:
  scraper:
    image: curlimages/curl
    environment:
      HTTPS_PROXY: ${PROXY_URL}
      NO_PROXY: localhost,127.0.0.1
    command: ["-sS", "https://api.ipify.org?format=json"]
PROXY_URL=http://USERNAME:PASSWORD@HOST:PORT

Docker build proxy: --build-arg and what leaks

HTTP_PROXY, HTTPS_PROXY, NO_PROXY, ALL_PROXY (and their lowercase forms) are predefined build args: every RUN step sees them without an ARG line.

docker build --build-arg HTTPS_PROXY="http://USERNAME:PASSWORD@HOST:PORT" -t myimage .

The Dockerfile reference says these are left out of docker history. Here is what we found when we checked each place a password could end up:

Where we lookedPredefined arg, no ARG lineARG HTTPS_PROXY declared in the DockerfileCustom ARG PROXY_URLSecret mount
docker history --no-truncnot presentfull URLfull URLnot present
docker image inspect, container envnot presentnot presentnot presentnot present
Image provenance attestationnot presentnot checkednot checkednot checked
Builder record, docker buildx history inspectfull URLfull URLfull URLnot present

Two conclusions. Do not write ARG HTTPS_PROXY in the Dockerfile: declaring it turns off the protection. And the build record lives on the builder, not in the image, but anyone with access to that builder can read it. For a shared CI builder, use a secret mount (Dockerfile syntax 1.10 or later), which exposes the value to one RUN step only:

# syntax=docker/dockerfile:1
FROM curlimages/curl
RUN --mount=type=secret,id=proxy,env=HTTPS_PROXY \
    curl -sS "https://api.ipify.org?format=json"
export PROXY_URL="http://USERNAME:PASSWORD@HOST:PORT"
docker build --secret id=proxy,env=PROXY_URL -t myimage .

Never put the proxy in an ENV line: that stores it in the image config for everyone who pulls the image. In Compose, the same predefined args go under build.args.

Docker daemon proxy for image pulls

If docker pull itself must go through the proxy, configure dockerd. The container settings above do not affect pulls.

Linux with systemd

Create /etc/systemd/system/docker.service.d/http-proxy.conf:

[Service]
Environment="HTTP_PROXY=http://USERNAME:PASSWORD@HOST:PORT"
Environment="HTTPS_PROXY=http://USERNAME:PASSWORD@HOST:PORT"
Environment="NO_PROXY=localhost,127.0.0.1"
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker

daemon.json (Docker Engine 23.0 and later)

{
  "proxies": {
    "http-proxy": "http://USERNAME:PASSWORD@HOST:PORT",
    "https-proxy": "http://USERNAME:PASSWORD@HOST:PORT",
    "no-proxy": "localhost,127.0.0.1"
  }
}

Put it in /etc/docker/daemon.json and restart Docker. These fields take precedence over the environment variables. Add any internal registry to the no-proxy list.

Docker Desktop

Open Settings, then Resources, then Proxies, choose manual configuration and enter the proxy under Web Server (HTTP) and Secure Web Server (HTTPS). Docker Desktop has separate proxy settings for its own traffic and for containers, and image pulls follow the containers proxy.

Set a default for every container with ~/.docker/config.json

The Docker CLI proxy docs describe a proxies block that injects the variables into every new container and build started by that client, with no restart:

{
  "proxies": {
    "default": {
      "httpProxy": "http://USERNAME:PASSWORD@HOST:PORT",
      "httpsProxy": "http://USERNAME:PASSWORD@HOST:PORT",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}

It is convenient and global: every container you start, including ones that should not use the proxy, gets the password in its environment. Prefer per-project env files unless the whole machine should egress through one IP.

Verify the exit IP

docker run --rm curlimages/curl -sS "https://api.ipify.org?format=json"
docker run --rm --env-file ~/proxy.env curlimages/curl -sS "https://api.ipify.org?format=json"

The second IP should be the one on your order. To give several containers different static IPs, keep one env file per IP and start each container with its own file. The cURL proxy guide covers the flags used here.

Troubleshooting

SymptomCauseFix
CONNECT tunnel failed, response 407 (curl exit 56)Wrong credentialsRe-copy them; percent-encode @ or : in the password
docker pull times out, containers are fineDaemon has no proxyConfigure dockerd as above
Build RUN step goes directNo build arg passedAdd --build-arg HTTPS_PROXY=... or the proxies block
Proxy on localhost unreachable from a containerlocalhost is the containerUse the host's address, or --network host on Linux
Internal service now failsTraffic sent to the proxyAdd it to NO_PROXY

More status codes are decoded in proxy error codes. Pricing for a single static IP is on the datacenter pricing page, from $3.20/IP.