en

Docker Containers for Tor Hidden Services

Docker containers simplify application deployment and provide an additional layer of isolation for .onion service applications. The Tor sidecar pattern runs a Tor daemon container alongside the application container, managing hidden service configuration automatically. This guide covers Docker and Docker Compose deployment patterns for Tor hidden services, including network isolation, volume management, and production-ready configuration.

Need this done for your project?

We implement, you ship. Async, documented, done in days.

Start a Brief

Tor Sidecar Container Pattern

The sidecar pattern runs a Tor daemon container alongside the application container in the same Docker network. The Tor container manages the hidden service and provides SOCKS5 proxy access. The application container runs on a private Docker network (not exposed to host network), and the Tor container forwards .onion connections to the application container's private IP. Docker Compose setup: define two services - app (the application) and tor (the Tor daemon). The tor service uses an official Tor Docker image or a custom Dockerfile with torrc configuration. The torrc mounts a volume for the HiddenServiceDir (to persist the .onion address across container restarts). Network: create a custom bridge network (tor_net) with no external access for the app service, and give the tor service access to both tor_net and the host network (for outbound Tor connections). The HiddenServicePort in torrc maps to the app container's internal IP and port. The .onion address persists as long as the mounted volume for the hidden service directory is preserved.

Docker Compose Configuration for .onion Services

A production docker-compose.yml for a .onion service with Tor sidecar. Define the application service with no published ports (not exposed to host), connected only to the private tor_network. Define the Tor service with a custom torrc configuration, mounted volumes for the HiddenServiceDir (named volume for persistence) and torrc file (bind mount from host). The tor service has no published ports exposed to the host - only outbound Tor connections. Add a nginx service as an intermediary if needed (static files, reverse proxy). Docker secrets for sensitive environment variables: use Docker's secrets management to inject passwords and API keys without embedding in docker-compose.yml. Define secrets as files, reference them in service configurations. Application services read secrets from /run/secrets/ in the container. Restart policy: set restart: unless-stopped for all services to ensure automatic restart after server reboots.

Container Network Isolation for Security

Docker's network isolation adds a layer of security to .onion service deployments. Create multiple Docker networks: a public network (tor_external) for the Tor container's outbound connections, and a private network (app_internal) for inter-container communication. The application container should only be on app_internal - it has no direct internet access. Nginx (if used) connects to both networks: app_internal for accessing the application and the Tor container's internal network for receiving connections from Tor. Use iptables rules (or Docker's built-in network policy) to prevent containers from making unexpected outbound connections. Container security options: add --security-opt no-new-privileges to prevent privilege escalation, use --cap-drop ALL --cap-add NET_BIND_SERVICE to minimize Linux capabilities, run application containers as non-root users (USER directive in Dockerfile). These measures ensure that even a compromised container has minimal ability to affect the host system or other containers.

Volume Management and Persistence

Tor hidden service identity persistence is critical - losing the HiddenServiceDir means losing the .onion address. Use named Docker volumes for the HiddenServiceDir: in docker-compose.yml, define a named volume (tor_hs_keys) mounted at the container's HiddenServiceDir path. Named volumes persist across container stops and restarts but are destroyed with docker compose down -v (never use -v in production). The volume location on the host: /var/lib/docker/volumes/tor_hs_keys/_data. Backup the .onion private key from this directory. For application data: use named volumes for database data directories, uploaded file directories, and cache directories. Distinguish between data that must persist (keys, database) and data that can be regenerated (cache, built assets). Recreatable data can use tmpfs volumes (in-memory, not persistent) for performance. For migration: export named volumes with docker run --rm -v myvolume:/data alpine tar -C /data -cz . > backup.tar.gz.

Updating and Rolling Deployments with Docker

Docker simplifies application updates for .onion services. Build a new application image with updated code. Push to a private container registry accessible via .onion (or transfer the image tar file via SCP over Tor: docker save myapp:latest | gzip | torsocks scp user@server.onion:/tmp/myapp.tar.gz). On the server: load the new image (docker load < /tmp/myapp.tar.gz), update the image tag in docker-compose.yml, and run docker compose up -d myapp to update only the application service without restarting the Tor service. The Tor service continues running during the application update - the .onion address remains active while the new application container starts. Zero-downtime: for zero-downtime, use a load balancer (nginx upstream) with multiple application container replicas and update them one at a time using Docker scale commands. After successful deployment: remove old images with docker image prune to free disk space.

Why Anubiz Host

100% async — no calls, no meetings
Delivered in days, not weeks
Full documentation included
Production-grade from day one
Security-first approach
Post-delivery support included

Ready to get started?

Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.

Anubiz Chat AI

Online