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.
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.jsonor 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 aproxychains-ngwrapper. - 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
httpandsocks5, on pay-as-you-go or flat monthly billing, give you options to match each containerised workload.