Proxy setup · 2 min read

Using HTTP_PROXY / HTTPS_PROXY environment variables

The HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment variables are the fastest way to send a program's outbound traffic through a proxy. Here is how they behave across curl, wget, Python, Node.js and Docker — and where they quietly don't.

How the proxy environment variables work

HTTP_PROXY, HTTPS_PROXY and NO_PROXY are an old, cross-platform convention: many command-line tools and HTTP libraries read them at startup and route outbound requests through whatever proxy you name. The effect is simple — your real / origin IP stays hidden and the destination sees the proxy's exit address instead.

The naming trips people up. HTTP_PROXY is the proxy used for http:// destination URLs and HTTPS_PROXY for https:// destination URLs — it does not mean "a proxy reached over HTTPS". The scheme inside the value (http:// or socks5h://) is what decides how your client reaches our proxy.

Not every tool honors these variables, and the ones that do disagree on the details:

ToolReads env vars?Notes
curlYeslowercase http_proxy only for HTTP; both cases for HTTPS
wgetYeshonors http_proxy, https_proxy, no_proxy
Python requests / urllibYesautomatic; a per-request proxies= arg overrides
Node.js core fetch / httpNoneeds undici ProxyAgent or global-agent
Docker CLI / buildPartialpass via --build-arg, -e or config.json

Ours are datacenter proxies (not residential), so consumer sites may flag them more readily — great for APIs, CI and scraping targets you control, less so for locked-down consumer platforms. Our authenticated SOCKS5 and HTTP proxies take a username and password, so nothing egresses without your credential. For always-on, full-device routing use the WireGuard VPN instead; to try the throwaway public proxy list or price metered access see pricing. More recipes live in the guides, and a full comparison of VPN vs proxy is here too.

Set the variables in your shell (curl + wget)

Export once, then ordinary commands egress through the proxy. Auth goes inline in the URL as USER:PASS. Set the lowercase form too — curl only reads lowercase http_proxy for the HTTP scheme.

bash
# HTTP proxy endpoint (port 3128) with inline auth
export HTTP_PROXY="http://USER:[email protected]:3128"
export HTTPS_PROXY="http://USER:[email protected]:3128"
# curl and some tools only read the lowercase form — set both
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"

# Never send local / internal traffic through the proxy
export NO_PROXY="localhost,127.0.0.1,::1,.internal,169.254.169.254"
export no_proxy="$NO_PROXY"

# Now normal commands go through the proxy
curl https://api.ipify.org      # prints the proxy exit IP, not yours
wget -qO- https://api.ipify.org

# One-off, without exporting anything:
curl -x http://USER:[email protected]:3128 https://example.com

# SOCKS5 (port 1080). socks5h makes DNS resolve AT the proxy,
# so your origin never leaks the hostname lookup.
export ALL_PROXY="socks5h://USER:[email protected]:1080"
curl https://api.ipify.org

Python and Node.js

Python's requests/urllib pick the variables up automatically. Node's core http and global fetch() do not — you must attach a proxy agent yourself.

python
# --- Python: requests, urllib, pip and httpx honor the env vars ---
import requests
print(requests.get("https://api.ipify.org").text)   # proxy exit IP

# Override per-request (this ignores the env vars):
proxies = {
    "http":  "http://USER:[email protected]:3128",
    "https": "http://USER:[email protected]:3128",
}
requests.get("https://api.ipify.org", proxies=proxies)

# SOCKS5 needs the extra:  pip install "requests[socks]"
proxies = {"https": "socks5h://USER:[email protected]:1080"}


# --- Node.js (>=18): core fetch does NOT read HTTP_PROXY on its own ---
// import { ProxyAgent, setGlobalDispatcher } from "undici";
// setGlobalDispatcher(
//   new ProxyAgent("http://USER:[email protected]:3128"));
// const r = await fetch("https://api.ipify.org");
// console.log(await r.text());        // proxy exit IP
//
// To make libraries respect the env vars instead:
//   npm i global-agent
//   GLOBAL_AGENT_HTTP_PROXY=$HTTP_PROXY node -r global-agent/bootstrap app.js

Docker (build and runtime)

Containers do not inherit your shell environment. Pass the variables explicitly for builds and runs; the daemon that pulls images reads them from its own config file.

bash
# Build-time: forward the proxy into the build
docker build \
  --build-arg HTTP_PROXY="http://USER:[email protected]:3128" \
  --build-arg HTTPS_PROXY="http://USER:[email protected]:3128" \
  --build-arg NO_PROXY="localhost,127.0.0.1" .

# Runtime: inject into the running container
docker run --rm \
  -e HTTP_PROXY="http://USER:[email protected]:3128" \
  -e HTTPS_PROXY="http://USER:[email protected]:3128" \
  -e NO_PROXY="localhost,127.0.0.1" \
  curlimages/curl https://api.ipify.org

# The Docker daemon itself (image pulls) reads ~/.docker/config.json:
#   { "proxies": { "default": {
#       "httpProxy":  "http://USER:[email protected]:3128",
#       "httpsProxy": "http://USER:[email protected]:3128",
#       "noProxy":    "localhost,127.0.0.1" } } }

Gotchas worth knowing

Percent-encode credentials

Special characters in USER:PASS break the URL. Encode them: @ becomes %40, : becomes %3A, / becomes %2F, # becomes %23. Otherwise the parser cuts the value in the wrong place.

HTTPS_PROXY targets https:// URLs

It selects the proxy for https destination URLs — not a proxy reached over HTTPS. The scheme in the value (http:// or socks5h://) is what sets how you connect to our proxy.

NO_PROXY is picky

Comma-separated, no spaces, suffix-matched (.example.com). CIDR ranges and the * wildcard are supported by some tools and ignored by others, so test rather than assume.

socks5h vs socks5

With socks5:// your machine resolves DNS locally and only the TCP connection is proxied. Use socks5h:// so the hostname lookup also happens at the proxy, keeping DNS off your origin.

Credentials are visible locally

Env vars show up in ps output, shell history and CI logs. Use a per-account proxy credential you can rotate, and prefer secret stores over committing them to a Dockerfile or pipeline.

Not every client obeys them

Node's core http and fetch, plus some SDKs, ignore these variables entirely. Always confirm with an IP echo like api.ipify.org that traffic actually left through the proxy exit, not your real IP.

Share this page
FAQ

Questions, answered

Why does curl ignore HTTP_PROXY but respect http_proxy?

For the HTTP scheme, curl deliberately reads only the lowercase http_proxy. The uppercase HTTP_PROXY was disabled years ago because CGI scripts receive an HTTP_* environment variable from client headers, which could hijack a proxy setting. For HTTPS and NO_PROXY curl reads both cases. The safe habit is to export both the uppercase and lowercase forms.

What is the difference between HTTPS_PROXY and 'a proxy over HTTPS'?

HTTPS_PROXY chooses which proxy handles requests to https:// destination URLs. It says nothing about how you connect to the proxy itself — that is set by the scheme in the value. http://proxy.s4m.online:3128 reaches our HTTP proxy in cleartext CONNECT; socks5h://proxy.s4m.online:1080 reaches the SOCKS5 endpoint. Your actual payload to an https site stays TLS-encrypted end to end regardless.

Can I put a SOCKS5 URL in HTTP_PROXY?

curl accepts socks5:// and socks5h:// in the proxy URL, but many other tools do not. For portability, use ALL_PROXY for SOCKS5 or the library's own SOCKS option. Prefer socks5h:// so DNS resolves at proxy.s4m.online:1080 instead of leaking lookups from your origin.

Are these residential proxies?

No. s4m proxies are authenticated datacenter SOCKS5 and HTTP proxies, billed pay-as-you-go. Datacenter IPs are fast and reliable for APIs, CI and scraping targets you control, but some consumer sites detect and block datacenter ranges more easily than residential ones. We do not sell or claim residential IPs.

Will setting these variables hide my real IP everywhere?

Only for programs that actually read them. Node's core http, global fetch, certain SDKs and any app that opens raw sockets will bypass the proxy and expose your real IP. After configuring, verify with an IP echo such as api.ipify.org, or use our WireGuard VPN when you need every process on the device routed.

Route your requests through s4m

Authenticated SOCKS5 and HTTP datacenter proxies, metered pay-as-you-go, plus flat-rate WireGuard VPN. No-logs by design, RAM-first, anonymous accounts. Add a dedicated personal IP whenever you need a static exit.

People found this page by searching for

Real search phrases this page answers — the linked ones open the page that covers them in depth.