Skip to content
Tutorials

How to Use a Proxy With Docker (2026)

Set up Docker proxy settings for the daemon, containers, builds, and Compose, plus authenticated proxies and NO_PROXY rules.

Rectangle Zenezen
August 23, 2026 5 min read
How to Use a Proxy With Docker (2026)
Click Here to Add Proxyon as a Trusted Source Add as a preferred source

Don't want to read?

Time is a precious resource, get the insights you need using your favorite AI chat.


How to Configure the Docker Daemon Proxy

How to Configure the Docker Daemon Proxy

The Docker daemon (dockerd) is what runs docker pull, so start here when pulls fail. On Docker Engine 23.0 and later, put a proxies block in /etc/docker/daemon.json. The keys are case-sensitive, so a typo like http-Proxy stops the daemon from starting.

ABAP
{
  "proxies": {
    "http-proxy": "http://proxy.example.com:3128",
    "https-proxy": "http://proxy.example.com:3128",
    "no-proxy": "localhost,127.0.0.0/8,registry.internal.example.com"
  }
}

Restart with sudo systemctl restart docker. Both entries normally point at the same address, since HTTPS_PROXY means the proxy for HTTPS destinations, not a proxy on port 443. On older engines, use a systemd drop-in, as the daemon proxy configuration reference shows:

  1. Run sudo mkdir -p /etc/systemd/system/docker.service.d.
  2. Save the following as http-proxy.conf in that directory. [Service]
    Environment="HTTP_PROXY=http://proxy.example.com:3128"
    Environment="HTTPS_PROXY=http://proxy.example.com:3128"
    Environment="NO_PROXY=localhost,127.0.0.1,registry.internal.example.com"
  3. Run sudo systemctl daemon-reload && sudo systemctl restart docker.
  4. Verify with sudo systemctl show --property=Environment docker.

One thing worth knowing: Docker Desktop ignores daemon.json proxies. Set them under Settings, Resources, Proxies instead, and remember that only covers pulls.


How to Pass Proxy Settings to Containers

How to Pass Proxy Settings to Containers

Nothing the daemon knows reaches the inside of a container. To inject proxy variables into every new container, add a proxies block to ~/.docker/config.json on the machine running the Docker CLI.

ABAP
{
  "proxies": {
    "default": {
      "httpProxy": "http://proxy.example.com:3128",
      "httpsProxy": "http://proxy.example.com:3128",
      "noProxy": "localhost,127.0.0.1,.internal.example.com"
    }
  }
}

It applies to new containers and builds immediately, with no restart, and does nothing for existing ones. Docker sets each variable in both uppercase and lowercase because tools disagree on which one they read. curl, for example, only reads lowercase http_proxy while accepting either case for the others. For a one-off container, pass the values with --env:

ABAP
docker run --rm \
  -e HTTP_PROXY=http://proxy.example.com:3128 \
  -e HTTPS_PROXY=http://proxy.example.com:3128 \
  -e NO_PROXY=localhost,127.0.0.1 \
  alpine sh -c 'env | grep -i _proxy'

Also Read: How to Use a Proxy Server on Any Device


Using a Proxy During Docker Build

How to Use a Proxy During Docker Build

Pass the proxy as a build argument. HTTP_PROXY, HTTPS_PROXY, NO_PROXY, and ALL_PROXY are predefined, so you do not declare them with ARG, and their values stay out of the final image and docker history.

ABAP
docker build \
  --build-arg HTTP_PROXY=http://proxy.example.com:3128 \
  --build-arg HTTPS_PROXY=http://proxy.example.com:3128 \
  -t my-app .

Older guides still tell you to write ENV http_proxy into the Dockerfile. Do not. That hardcodes the proxy into every container built from the image, breaks it on any other network, and exposes the credentials to anyone who can run docker inspect.


Docker Compose Proxy Configuration

Docker Compose Proxy Configuration

Define runtime values under environment and build-time values under build.args, interpolated from a .env file so credentials stay out of version control. Declaring them in the Compose file keeps the behavior identical on every machine and in CI.

YAML
services:
  scraper:
    build:
      context: .
      args:
        HTTP_PROXY: ${HTTP_PROXY}
        HTTPS_PROXY: ${HTTPS_PROXY}
    environment:
      HTTP_PROXY: ${HTTP_PROXY}
      HTTPS_PROXY: ${HTTPS_PROXY}
      NO_PROXY: localhost,127.0.0.1,db,redis
  db:
    image: postgres:16
  redis:
    image: redis:7

Put your service names in NO_PROXY. Otherwise a request from scraper to db goes to the proxy, which has no idea what db is, and the failure looks nothing like a proxy problem.


Using Authenticated Proxies With Docker

Using Authenticated Proxies With Docker

Commercial proxies, including residential proxies and datacenter proxies from Proxyon, authenticate with credentials in the proxy URL as user:pass@host:port, and Docker passes that string through unchanged at every layer above. Special characters in the password must be percent-encoded, so @ becomes %40 and # becomes %23, and inside a systemd drop-in every % is doubled to %% because systemd treats it as a specifier. The proxy formatter handles that conversion.

Credentials in environment variables are readable through docker inspect. On a server with a fixed IP, IP whitelisting on the proxy side removes them entirely, and the container only needs the host and port. Then confirm the route:

ABAP
docker run --rm \
  -e HTTPS_PROXY=http://user:pass@gateway.proxyon.io:8000 \
  curlimages/curl -s https://api.ipify.org

The response should show the proxy's IP, not your server's.

Also Read: How to Set Up Rotating Proxies for Web Scraping


FAQ Section

FAQ

Why does docker pull work but apt-get fails during the build?

The daemon has a proxy and the build container does not. Pulling the base image is daemon traffic, while apt-get runs inside a temporary container that only knows about HTTP_PROXY if you pass it as a build argument or set it in ~/.docker/config.json.

Do I need to restart Docker after changing the proxy settings?

Only for the daemon. Changes to daemon.json or a systemd drop-in need systemctl restart docker, while changes to ~/.docker/config.json apply to the next container or build you start.

What is the docker-proxy process I see on my host?

It is Docker's userland proxy, a small binary that forwards published ports (-p 8080:80) to containers. It has nothing to do with outbound HTTP proxies, and it can be disabled with "userland-proxy": false in daemon.json, though that changes how published ports behave on localhost.

Does Docker support SOCKS5 proxies?

The daemon does. Its proxy handling accepts socks5:// URLs in daemon.json or the systemd drop-in, although socks5h:// is not recognized. Inside a container it comes down to the client: curl handles socks5://, Python requests needs the PySocks extra, and many tools ignore SOCKS URLs in the proxy variables entirely, so an HTTP proxy is the safer default for containers.

What should go in NO_PROXY?

localhost, 127.0.0.1, any internal registry, your Compose service names, and your internal domain suffix. Docker matches example.com against its subdomains as well, and a leading dot limits the match to subdomains only. Keep the list identical in both cases, because tools that read no_proxy and tools that read NO_PROXY will otherwise behave differently.

Is a registry mirror the same as a proxy?

No. A registry mirror ("registry-mirrors" in daemon.json) is a pull-through cache that keeps copies of images closer to you. It does not route container traffic anywhere, and it can be combined with a proxy, but it does not replace one.


Final Thoughts

The right Docker proxy setup comes down to which traffic you need to move. If only image pulls are blocked, configure the daemon and stop there. If the application inside the container needs to reach the outside world through a proxy, set the variables at the container or Compose level and keep credentials out of the image. For scraping and automation workloads, Proxyon's residential and datacenter proxies accept the same authenticated URL at every one of these layers, with IP whitelisting available when you would rather not store credentials at all.

Get back to building.

We'll handle the proxies.