Lightweight, secure Docker HTTP/SOCKS5 Tor proxy with local REST control API
3.1K
A lightweight, secure, and production-ready Docker container combining Tor, Privoxy (HTTP/HTTPS proxy), SOCKS5, and a local REST control API.
Source repository: https://github.com/hapheus/torproxy
socks5h://)./reconnect), query health diagnostics, and pull Prometheus metrics.torproxy), never as root.linux/amd64, linux/arm64, and linux/arm/v7.TORPROXY_COUNTRY=DE or DE,AT) backed by tor-geoipdb.docker run -d \
--name torproxy \
--restart unless-stopped \
-p 127.0.0.1:8118:8118 \
-p 127.0.0.1:9050:9050 \
-p 127.0.0.1:8080:8080 \
hapheus/torproxy:latest
services:
torproxy:
image: hapheus/torproxy:latest
container_name: torproxy
restart: unless-stopped
ports:
- "127.0.0.1:8118:8118"
- "127.0.0.1:9050:9050"
- "127.0.0.1:8080:8080"
docker run -d \
--name torproxy \
--restart unless-stopped \
-e TORPROXY_COUNTRY=DE \
-p 127.0.0.1:8118:8118 \
-p 127.0.0.1:9050:9050 \
-p 127.0.0.1:8080:8080 \
hapheus/torproxy:latest
Wait a few seconds for Tor to bootstrap, then test:
# 1. Check REST API status
curl -s http://127.0.0.1:8080/status | jq .
# 2. Test HTTP proxy via Privoxy
curl --proxy http://127.0.0.1:8118 https://check.torproject.org/api/ip
# 3. Test SOCKS5 proxy (using remote DNS to prevent leaks)
curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
# 4. Request a new Tor identity / circuit
curl -X POST http://127.0.0.1:8080/reconnect
# 5. Dynamically switch exit country without restart
curl -X POST "http://127.0.0.1:8080/reconnect?country=DE"
The management API listens on port 8080 (HTTP):
| Endpoint | Methods | Description |
|---|---|---|
/status | GET | Tor bootstrap and current verified egress IP address. |
/ip | GET | Current verified Tor egress IP address. |
/health | GET | Multi-subsystem health check (tor, proxies, egress). Returns HTTP 200 when healthy, 503 during bootstrap/errors. |
/diagnostics | GET | Uptime, reconnect counters, bootstrap details, and cache status. |
/metrics | GET | Prometheus exposition format metrics. |
/reconnect | POST (or GET) | Triggers SIGNAL NEWNYM to establish a new circuit. Supports ?country=DE query or JSON body. |
/disconnect | POST (or GET) | Disables Tor network traffic (SETCONF DisableNetwork=1). |
/connect | POST (or GET) | Re-enables Tor network traffic (SETCONF DisableNetwork=0). Supports ?country=DE query or JSON body. |
Warning
The management API is unauthenticated by default. Bind it strictly to `127.0.0.1` or place it behind an authenticating reverse proxy if exposed across networks.
| Variable | Default | Description |
|---|---|---|
TORPROXY_LISTEN_ADDRESS | 0.0.0.0 | Bind address for Privoxy and Tor inside the container. |
TORPROXY_LISTEN_PORT | 8118 | Privoxy HTTP proxy port. |
TORPROXY_SOCKS_PORT | 9050 | Tor SOCKS5 proxy port. |
TORPROXY_API_PORT | 8080 | REST API port. |
TORPROXY_COUNTRY | (unset) | Comma-separated ISO 3166-1 alpha-2 codes (e.g. DE, AT, US, DE,AT) to restrict exit nodes. |
TORPROXY_STRICT_NODES | 0 | If 1/true, refuse circuits if nodes in the requested country/countries are unavailable. |
For maximum security in production, run with a read-only root filesystem and drop all Linux capabilities:
services:
torproxy:
image: hapheus/torproxy:latest
restart: unless-stopped
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
tmpfs:
- /tmp:rw,noexec,nosuid,size=32M
- /run:rw,noexec,nosuid,size=16M
- /var/lib/tor:rw,noexec,nosuid,size=64M
- /var/log/privoxy:rw,noexec,nosuid,size=16M
ports:
- "127.0.0.1:8118:8118"
- "127.0.0.1:9050:9050"
- "127.0.0.1:8080:8080"
This project is licensed under the MIT License.
Content type
Image
Digest
sha256:a7a679b74…
Size
52.2 MB
Last updated
about 19 hours ago
docker pull hapheus/torproxy