Skip to content
intermediate

How to Route Docker Containers Through ProxyScrape Proxies

Send container traffic, image pulls, and Compose services through ProxyScrape HTTP or SOCKS5 endpoints using environment variables, client and daemon proxy config, and app-level settings.

Linux SOCKS5 HTTP(S) Other

Overview

Docker containers are isolated from your host shell and its proxy settings, so a proxy that works in your terminal does not automatically apply inside docker run or docker compose. There are three practical places to insert a ProxyScrape endpoint: inside the container as environment variables, at the Docker client or daemon level so image pulls and builds use the proxy, and in application configuration for tools that ignore environment variables or need SOCKS5.

ProxyScrape offers residential, datacenter, and mobile proxies over http and socks5, billed either pay-as-you-go or as a flat monthly plan, so you can match the pool and billing model to the workload you are containerising. The endpoint host, port, and credentials are listed in your ProxyScrape dashboard.

This tutorial covers all three layers and shows how to confirm that container traffic is actually leaving through the proxy.

What you need

  • Docker Engine 20.10 or newer, or Docker Desktop
  • Docker Compose v2 (docker compose)
  • A ProxyScrape subscription plus the host, port, username, and password from your dashboard
  • Outbound access to the proxy port on your network

Choosing Where to Apply the Proxy

Layer Applies to Protocols Notes
Container environment variables Clients that read HTTP_PROXY (curl, pip, apt, many SDKs) http Quickest to set up; SOCKS5 URLs are ignored by most runtimes
Docker client or daemon config docker pull, docker build, docker push http Daemon-level changes need a service restart
Application config or a forwarder Tools with their own proxy settings, or SOCKS5-only needs http, socks5 Most reliable for non-standard clients

Start with environment variables and only move down the table when a tool ignores them.

Steps

1. Store your credentials outside the image

Build the proxy URL for the protocol you intend to use:

http://<username>:<password>@<host>:<port>
socks5h://<username>:<password>@<host>:<port>

Keep the values in a file that never enters a build context or a Git repository.

mkdir -p ~/.config/proxyscrape
cat > ~/.config/proxyscrape/proxy.env <<'EOF'
PROXY_USER=your-username
PROXY_PASS=your-password
PROXY_HOST=proxy-host-from-dashboard
PROXY_PORT=proxy-port-from-dashboard
EOF
chmod 600 ~/.config/proxyscrape/proxy.env

If the password contains @, :, /, or #, percent-encode those characters before placing it in a URL.

2. Verify the endpoint from the host

set -a; . ~/.config/proxyscrape/proxy.env; set +a

curl -sS -x "http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" https://api.ipify.org; echo
curl -sS -x "socks5h://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" https://api.ipify.org; echo

Use socks5h:// rather than socks5:// so hostname resolution happens at the proxy instead of locally. If only one of the two commands succeeds, use that protocol for the rest of this setup.

3. Pass the proxy to a single container

docker run --rm \
  -e HTTP_PROXY="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" \
  -e HTTPS_PROXY="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" \
  -e http_proxy="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" \
  -e https_proxy="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" \
  -e NO_PROXY="localhost,127.0.0.1,::1" \
  curlimages/curl:latest -sS https://api.ipify.org; echo

Many runtimes read only the lowercase names and some read only the uppercase ones, so set both. NO_PROXY keeps loopback and container-internal traffic off the proxy.

4. Manage the proxy with Docker Compose

Create an .env file in the Compose project directory so Compose can interpolate the values, and add it to .gitignore.

PROXY_USER=your-username
PROXY_PASS=your-password
PROXY_HOST=proxy-host-from-dashboard
PROXY_PORT=proxy-port-from-dashboard
services:
  worker:
    image: python:3.12-slim
    environment:
      HTTP_PROXY: "http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}"
      HTTPS_PROXY: "http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}"
      http_proxy: "http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}"
      https_proxy: "http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}"
      NO_PROXY: "localhost,127.0.0.1,::1"
    command:
      - python
      - -c
      - "import urllib.request; print(urllib.request.urlopen('https://api.ipify.org').read().decode())"
docker compose up --build
docker compose logs worker

Note that values placed in an env_file are injected into the container but are not used for ${...} interpolation. Compose reads those from the shell environment or the project .env file.

5. Route image pulls and builds through the proxy

For a single user, configure the Docker client so builds inherit the proxy. Save this as ~/.docker/config.json:

{
  "proxies": {
    "default": {
      "httpProxy": "http://<username>:<password>@<host>:<port>",
      "httpsProxy": "http://<username>:<password>@<host>:<port>",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}

Docker's client and daemon proxy configuration supports HTTP proxies only, so use an http:// endpoint here even if you use SOCKS5 inside containers.

On Linux hosts where the daemon itself must reach a registry, add a systemd drop-in instead:

# /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
docker info | grep -i proxy

6. Configure tools that ignore environment variables

A few package managers and runtimes need explicit settings.

apt inside a Debian-based image:

echo 'Acquire::http::Proxy "http://<username>:<password>@<host>:<port>";' \
  > /etc/apt/apt.conf.d/95proxy

pip:

pip install --proxy "http://<username>:<password>@<host>:<port>" requests

For SOCKS5-only tools, proxychains-ng provides a wrapper that forces connections through the proxy:

# /etc/proxychains4.conf (excerpt)
strict_chain
proxy_dns
[ProxyList]
socks5 <host> <port> <username> <password>
proxychains4 curl -sS https://api.ipify.org; echo

7. Verify egress and watch usage

Confirm the address the container sees, then compare it with the address you get without any proxy variables set. If the two match, the proxy is not being used.

docker run --rm \
  -e HTTPS_PROXY="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT" \
  curlimages/curl:latest -sS https://api.ipify.org; echo

Rotating endpoints may return a different exit IP from the pool on each request, which is expected for scraping and monitoring workloads. If your ProxyScrape plan exposes session or sticky options, add the session identifier to the username field as described in your dashboard, and keep an eye on usage there because request volume is metered.

Troubleshooting

407 Proxy Authentication Required

The username or password is wrong, or the password contains characters that were not percent-encoded. Re-copy the credentials from the ProxyScrape dashboard and rebuild the URL.

The host works but the container fails

  • Confirm both uppercase and lowercase proxy variables are set inside the container.
  • Check that the container can resolve the proxy hostname: docker run --rm curlimages/curl:latest -sS -I http://<host>.
  • On Docker Desktop, containers reach the internet through a VM, so verify the proxy port is not blocked by a host firewall.
  • Print the variables to rule out empty values: docker run --rm --env-file ~/.config/proxyscrape/proxy.env alpine env | grep -i proxy.

Connections time out

  • The egress port may be blocked by a corporate firewall or a local VPN. Test from the host first.
  • HTTP and SOCKS5 endpoints commonly listen on different ports. Use the port that matches the protocol you configured.

SOCKS5 URLs are ignored

Most runtimes implement only HTTP proxy environment variables. Use an application-level setting such as --proxy, a proxychains-ng wrapper, or the library's own proxy argument instead of relying on ALL_PROXY.

docker pull still fails after daemon configuration

Run docker info | grep -i proxy to confirm the daemon picked up the variables, and remember that ~/.docker/config.json applies only to the current user. Check your noProxy list for entries that accidentally cover the registry hostname.

TLS or certificate errors

HTTPS targets require the proxy to support the CONNECT method, which curl and the Docker client use automatically. If you configured an HTTP proxy URL, verify that the target port is permitted by your ProxyScrape endpoint.

Summary

  • Containers do not inherit host proxy settings, so pass credentials explicitly with HTTP_PROXY, HTTPS_PROXY, and their lowercase equivalents.
  • Use ~/.docker/config.json or a systemd drop-in to route image pulls and builds, remembering that Docker's own proxy configuration is HTTP-only.
  • Some tools such as apt, pip, and SOCKS5-only clients need their own configuration or a proxychains-ng wrapper.
  • Always verify the egress IP from inside the container and keep credentials in a file that is excluded from version control.
  • ProxyScrape's residential, datacenter, and mobile pools over http and socks5, on pay-as-you-go or flat monthly billing, give you options to match each containerised workload.