Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

torproxy — Minimal Tor HTTP & SOCKS5 Proxy for Docker

A minimal Tor HTTP and SOCKS5 proxy for Docker. torproxy routes proxy traffic through the Tor network, works with sensible defaults, and includes a local REST API and Docker health check for reliable automation. The HTTP proxy listens on port 8118, SOCKS5 on port 9050, and the API on port 8080.

Simple, secure Tor for Docker

torproxy is deliberately focused: provide an HTTP proxy that routes traffic through Tor, without a large configuration surface or complex startup parameters. It is designed for Docker users who want a dependable service that is easy to run, automate, and monitor.

  • Minimal setup: start it with Docker Compose or one docker run command.
  • Ready-aware health check: the container is healthy only when Tor is connected and the proxy is usable.
  • Small REST API: check the connection and connect, disconnect, or request a new circuit without using the Tor Control Protocol directly.
  • Safe local defaults: proxy and API bind to localhost by default; Tor's internal services remain private inside the container.
  • Docker-native operation: simple networking, restart policy support, and no unnecessary configuration.

The result is a small Docker Tor proxy that fits cleanly into scripts, CI/CD jobs, monitoring, Home Assistant, n8n, and Docker Compose stacks.

Why use Tor?

Tor sends requests through several independent servers before they reach their destination. As a result, the destination sees a Tor exit IP address instead of your normal public IP address. This can improve privacy when an application needs to use an HTTP proxy.

Note: Tor is not a guarantee of anonymity and does not protect data sent without encryption. Use https:// whenever possible. Because traffic takes a longer route, websites and downloads can be noticeably slower than with a normal internet connection.

Quick start

docker compose up -d
curl -v -x http://127.0.0.1:8118 https://check.torproject.org/api/ip
curl -v --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip

Compose makes all ports available only on this computer (127.0.0.1). This is intentional: neither proxy nor the control API has a password.

Usage

Configure software that supports an HTTP proxy with:

Setting Value
Host 127.0.0.1
Port 8118
Scheme http

For SOCKS5-aware software, use 127.0.0.1:9050. The SOCKS5 port resolves host names through Tor; with curl, use --socks5-hostname:

curl -v --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip

For a direct Docker run:

docker run -d --name torproxy --restart unless-stopped \
  -p 127.0.0.1:8118:8118 \
  -p 127.0.0.1:8080:8080 \
  -p 127.0.0.1:9050:9050 \
  hapheus/torproxy:latest

Use from other Docker containers

Containers in the same Docker network can use torproxy:8118 as their proxy. They can also reach the control API at torproxy:8080, so only connect containers you trust to that network.

curl -v -x http://torproxy:8118 https://check.torproject.org/api/ip

Automate privacy-aware workflows

The REST API exists so applications do not need to speak the Tor Control Protocol or manage Tor processes themselves. A workflow can ask whether the proxy is ready, pause Tor traffic when it should not run, resume it when work starts, or request a fresh Tor circuit between independent jobs.

This is useful for authorised web-data collection, scheduled integrations, and automation where the application should use a Tor exit IP instead of exposing the network's normal public IP. Always respect the target site's terms, robots guidance, rate limits, and applicable law.

For example, an n8n workflow can use ordinary HTTP Request nodes to call the local API:

  1. GET http://torproxy:8080/status — continue only when the status is connected.
  2. Run the task through the HTTP proxy at http://torproxy:8118.
  3. POST http://torproxy:8080/reconnect — optionally request a new circuit before a separate, authorised job.

The same pattern works in shell scripts, CI/CD pipelines, health monitoring, and any service that can make HTTP requests. A reconnect is a request to Tor, not a guarantee of a different IP address.

Is it ready?

The image reports healthy only after Tor is connected and the proxy can be used. Starting the container is quick, but establishing a Tor connection can take a little longer.

That distinction lets dependent services wait for a usable proxy instead of merely a running container:

services:
  app:
    depends_on:
      torproxy:
        condition: service_healthy

With Compose, inspect the health state with:

docker inspect --format '{{.State.Health.Status}}' "$(docker compose ps -q torproxy)"

For the direct docker run example, use:

docker inspect --format '{{.State.Health.Status}}' torproxy

REST API for Tor status and connection control

The container includes a small JSON REST API for automation and monitoring. With Compose, it is available on this computer at http://127.0.0.1:8080. Containers in the same Docker network can access it too. It has no password, so do not make it publicly available.

Method Endpoint Short description Example response
GET or POST /status Shows the connection state and current Tor IP. {"status":"connected","ip":"109.70.100.9"}
GET /ip Shows the current Tor IP. Returns 503 until an IP is available. {"ip":"109.70.100.9"}
GET or POST /connect Establishes or resumes the Tor connection. {"action":"connect","status":"success"}
GET or POST /disconnect Disconnects from Tor and blocks proxy traffic. {"action":"disconnect","status":"success"}
GET or POST /reconnect Creates a new Tor connection and requests a new IP. {"action":"reconnect","status":"success"}

For /status, connected means the proxy is ready, connecting means Tor is still starting, and disconnected means it was stopped with /disconnect. The ip value is null until Tor is ready or while it is disconnected.

/reconnect asks Tor for a new connection and exit IP. Tor may rate-limit this request, so a different IP cannot be guaranteed every time.

Examples:

curl http://127.0.0.1:8080/status
curl -X POST http://127.0.0.1:8080/reconnect
curl -X POST http://127.0.0.1:8080/disconnect

The IP result is cached for up to 30 seconds. /disconnect and /reconnect clear that cache.

Settings

The default settings work without any extra file. To change a port, create a .env file in the project folder, for example:

TORPROXY_HOST_PORT=8118
TORPROXY_LISTEN_ADDRESS=0.0.0.0
TORPROXY_LISTEN_PORT=8118
TORPROXY_API_PORT=8080
TORPROXY_SOCKS_PORT=9050
Variable Default Purpose
TORPROXY_HOST_PORT 8118 Port on your computer for the proxy.
TORPROXY_LISTEN_ADDRESS 0.0.0.0 Address the proxy uses inside its container. Usually leave this unchanged.
TORPROXY_LISTEN_PORT 8118 Proxy port inside the container. Usually leave this unchanged.
TORPROXY_API_PORT 8080 Port for the status and control API.
TORPROXY_SOCKS_PORT 9050 Port on your computer and inside the container for Tor's SOCKS5 proxy.

The settings are checked when the container starts. The SOCKS5 port is published only on 127.0.0.1, so it is not accessible from outside the host. Other containers on the same Docker network can also reach it at torproxy:9050.

Safety

This project is deliberately small: it has no user accounts, password protection, or saved state. Its local API can connect, disconnect, and renew the Tor connection.

Do not expose ports 8118, 9050, or 8080 to the internet. Anyone who can reach either proxy can use it, and anyone who can reach the API can control its connection.

Both proxy endpoints send traffic through Tor. Although the SOCKS5 listener binds to the container network so Docker can forward it, Compose publishes it only on the host loopback interface.

License

Released under the MIT License.

💝 Support the Project

If you find this project helpful, consider showing some support:

  • ☕ Buy me a coffee: Send a tip via PayPal.
  • ❤️ Charity Donation: Donate to Österreichische Krebshilfe (Austrian Cancer Aid) or any local animal welfare organization.
  • 🎯 Dream Support: I would love some tickets for the World Darts Championship at Ally Pally (Alexandra Palace) – hopefully, I will make it there one day!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages