Simple Docker container to run a Tor node.
-
Maintained by: Sven Gottwald
-
Where to get help: svengo/docker-tor issues
-
Docker Hub: svengo/tor
-
GitHub Container registry: svengo/docker-tor
-
Tor project: Tor Project
The Docker images are tagged with the precise Tor version number. Only the current Tor release (aliased as latest) is supported. No other versions are guaranteed to be stable or secure.
Security is a priority. I regularly rebuild this image with the latest Alpine packages, ensuring you have the most recent security fixes. To maintain this, several automated systems are in place:
- Dependabot: Configured to automatically update dependencies (dependabot.yml).
- GitHub Actions: A suite of workflows monitors for updates and performs checks:
- Anchore Grype Scanning for vulnerability detection.
- APK Update Checks to ensure package repositories are up-to-date.
- Rebuild on APK Updates to automatically rebuild Docker images when APK security updates are available.
- Update Tor Version to automatically check for and update to the latest Tor release.
- Codacy Integration for code quality analysis.
- CodeQL to identify vulnerabilities and errors in GitHub Actions workflows.
This command will start a Tor node and open ports 9001 and 9030:
docker run -d -p 9001:9001 -p 9030:9030 --name tor svengo/torIt is recommended to use docker compose for running the container. Use the supplied docker-compose.yml and copy docker-compose.env.dist to docker-compose.env. You can edit docker-compose.env to your needs.
Data is stored in an anonymous volume that is mounted on /data (see docker inspect for more information). You can use a host volume to store the data in a specific directory on the host. Make sure you set the permissions correctly, or Tor will not be able to write to the directory (default uid 100 / gid 101).
Start the container:
docker run -d -p 9001:9001 -p 9030:9030 --name tor -v /data/tor:/data svengo/torMost environment variables are used to populate /etc/tor/torrc-defaults, for more advanced configuration you can edit /data/torrc directly. Note that TZ is not a torrc directive; instead, it configures the container timezone.
docker run -d -p 9001:9001 -p 9030:9030 --name tor -v /data/tor:/data -e "NICKNAME=MyDockerTorNode" -e "CONTACTINFO=foo@example.com" svengo/torsvengo/tor uses several environment variables to generate the torrc-defaults-file, the variables are set to reasonable defaults (see below). You can edit /data/torrc to your needs after the first start.
| Variable | Default | Description |
|---|---|---|
ORPORT |
9001 |
Advertise this port to listen for connections from Tor clients and servers. Format: [address:]PORT [flags]. This option is required to be a Tor server. |
DIRPORT |
9030 |
If this option is nonzero, advertise the directory service on this port. Format: [address:]PORT [flags]. |
EXITPOLICY |
reject *:* # no exits allowed |
Set an exit policy for this server. Each policy is of the form accept[6]|reject[6] ADDR[/MASK][:PORT]. If /MASK is omitted, then this policy just applies to the host given. Instead of giving a host or network you can also use * to denote the universe (0.0.0.0/0 and ::/128), or *4 to denote all IPv4 addresses, and *6 to denote all IPv6 addresses. PORT can be a single port number, an interval of ports FROM_PORT-TO_PORT, or * . If PORT is omitted, that means *. |
CONTROLPORT |
(optional) | If set, Tor will accept connections on this port and allow those connections to control the Tor process using the Tor Control Protocol. Format: PORT|unix:path|auto [flags]. Note: unless you also specify HASHEDCONTROLPASSWORD, setting this option will cause Tor to allow any process on the local host to control it. If you use docker compose, you must also uncomment the corresponding port mapping in docker-compose.yml to make it reachable from the host. |
HASHEDCONTROLPASSWORD |
(optional) | Allow connections on the control port if they present the password whose one-way hash is hashed_password. You can compute the hash of a password by running docker run -it --rm svengo/tor:latest tor --hash-password "your_password". |
NICKNAME |
ididnteditheconfig |
Set the server's nickname to 'name'. Nicknames must be between 1 and 19 characters inclusive, and must contain only the characters [a-zA-Z0-9]. |
CONTACTINFO |
Random Person <nobody AT example dot com> |
Administrative contact information for this relay or bridge. This line can be used to contact you if your relay or bridge is misconfigured or something else goes wrong. You can use Tor ContactInfo Generator to create a contact info following ContactInfo-Information-Sharing-Specification. |
MYFAMILY |
(optional) | Declare that this Tor server is controlled or administered by a group or organization identical or similar to that of the other servers, defined by their identity fingerprints. When two servers both declare that they are in the same family, they are treated as a single server by the bandwidth authorities and entry guards. When listing a node, it's better to list it by fingerprint than by nickname: fingerprints are more reliable. |
ADDRESS |
(optional) | The IPv4 address of this server, or a fully qualified domain name of this server that resolves to an IPv4 address. You can leave this unset, and Tor will try to guess your IPv4 address. |
SOCKS_PORT |
(optional) | Port for the SOCKS proxy. If set, Tor will listen on this port for SOCKS connections. If you use docker compose, you must also uncomment the corresponding port mapping in docker-compose.yml to make it reachable from the host. |
SOCKS_POLICY |
(optional) | Access-control policy for the SOCKS proxy. If unset, all connections to SocksPort are accepted (potential security risk). Example: accept * |
TZ |
(optional) | Configure the system timezone for the container. If unset, the container uses UTC. Example: Europe/Berlin |
RELAY_BANDWIDTH_RATE |
(optional) | Average bandwidth limit for the relay. This allows the relay to use up to the specified rate, but averages the usage over time. Example: 100 KBytes |
RELAY_BANDWIDTH_BURST |
(optional) | Maximum bandwidth burst for the relay. This allows short bursts above the average rate, but still limits the maximum rate. Example: 200 KBytes |
Please report any problems as issues on github.