Knowledgebase / Self-hosting Guide / Can I Host My Onion Service Myself?

Can I Host My Onion Service Myself?

Technically speaking, you can certainly host your own onion service if you have a personal server. But, the downside is that you bear the burden of providing all the necessary security and infrastructure to keep your site up and running. Also, without a content delivery network, your site's loading speed slows down for visitors who are geographically distant. In addition, if you lack technical expertise, you might need to dedicate considerable time to understand and experiment with the Tor software and web server setup.

We suggest installing Docker if you're planning to establish an Onion Service and host it yourself. Docker is a software platform designed to facilitate building, testing, and deploying applications with speed. It organizes software into uniform units known as containers, which incorporate all the necessary components for the software's operation, such as libraries, system tools, code, and runtime. Docker enables swift deployment and scaling of applications in any environment, ensuring the smooth running of your code.

Also We suggest utilizing Docker Compose once Docker has been installed. Docker Compose serves as a utility for formulating and executing applications that involve multiple containers. It is instrumental in facilitating a smooth and productive development and deployment process. Docker Compose makes it straightforward to handle your entire application stack, including services, networks, and volumes, through a single, easily understood YAML configuration file. Consequently, all the services from your configuration file can be created and initiated with just one command.

To use Docker Compose, you should define services in a Compose file. Create a file called
compose.yaml
in your project directory and paste the following:
services:
  web:
    image: nginx
  tor:
    image: osminogin/tor-simple
    volumes:
      - ./config/torrc:/etc/tor/torrc
      - ./hidden_service:/var/lib/tor/hidden_service
This Compose file defines two services:
web
and
tor
.
The
web
service uses a public NGINX image pulled from the Docker Hub registry.
The
tor
service uses a public Tor image pulled from the Docker Hub registry. Two bind mounts are defined for this service. The first bind mount enables you to configure the Tor software to use Tor as an onion service. The second bind mount allows you to check your hidden service address, and persist your onion service public and private keys on your host server. In the event that your container is removed, your onion service keys are retained.
Create a directory called
config
in your project directory, and create a file called
torrc
inside the
config
directory and paste the following:
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 web:80
Create a directory called
hidden_service
in your project directory and update the permission:
# This command ensure that the hidden_service folder is owned by user tor, and owned by group nogroup in terms of container
chown 100:65533 hidden_service
# This command ensure that the hidden_service folder is not too permissive, and ensure the folder is accessed by tor user owner
chmod 700 hidden_service
From your project directory, start up your application by running
docker compose up
.
$ docker compose up

 ✔ Network onion_service_default  Created                                                                                        0.2s 
 ✔ Container onion_service-tor-1  Created                                                                                        0.0s 
 ✔ Container onion_service-web-1  Created                                                                                        0.0s 
Attaching to onion_service-tor-1, onion_service-web-1
onion_service-web-1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
onion_service-web-1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
onion_service-web-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
onion_service-web-1  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
onion_service-web-1  | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
onion_service-web-1  | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
onion_service-web-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
onion_service-web-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
onion_service-web-1  | /docker-entrypoint.sh: Configuration complete; ready for start up
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: using the "epoll" event method
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: nginx/1.25.4
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: OS: Linux 3.10.0-1160.105.1.el7.x86_64
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: start worker processes
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: start worker process 31
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: start worker process 32
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: start worker process 33
onion_service-web-1  | 2024/03/26 13:07:37 [notice] 1#1: start worker process 34
onion_service-tor-1  | Mar 26 13:07:37.192 [notice] Tor 0.4.8.10 running on Linux with Libevent 2.1.12-stable, OpenSSL 3.1.2, Zlib 1.3, Liblzma 5.4.5, Libzstd 1.5.5 and Unknown N/A as libc.
onion_service-tor-1  | Mar 26 13:07:37.192 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://support.torproject.org/faq/staying-anonymous/
onion_service-tor-1  | Mar 26 13:07:37.192 [notice] Read configuration file "/etc/tor/torrc".
onion_service-tor-1  | Mar 26 13:07:37.195 [notice] Opening Socks listener on 127.0.0.1:9050
onion_service-tor-1  | Mar 26 13:07:37.196 [notice] Opened Socks listener connection (ready) on 127.0.0.1:9050
onion_service-tor-1  | Mar 26 13:07:37.000 [notice] Parsing GEOIP IPv4 file /usr/share/tor/geoip.
onion_service-tor-1  | Mar 26 13:07:37.000 [notice] Parsing GEOIP IPv6 file /usr/share/tor/geoip6.
onion_service-tor-1  | Mar 26 13:07:37.000 [notice] Bootstrapped 0% (starting): Starting
onion_service-tor-1  | Mar 26 13:07:37.000 [notice] Starting with guard context "default"
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 5% (conn): Connecting to a relay
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 10% (conn_done): Connected to a relay
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 14% (handshake): Handshaking with a relay
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 15% (handshake_done): Handshake with a relay done
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 20% (onehop_create): Establishing an encrypted directory connection
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 25% (requesting_status): Asking for networkstatus consensus
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 30% (loading_status): Loading networkstatus consensus
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] I learned some more directory information, but not enough to build a circuit: We have no usable consensus.
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 40% (loading_keys): Loading authority key certs
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] The current consensus has no exit nodes. Tor can only build internal paths, such as paths to onion services.
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] Bootstrapped 45% (requesting_descriptors): Asking for relay descriptors
onion_service-tor-1  | Mar 26 13:07:38.000 [notice] I learned some more directory information, but not enough to build a circuit: We need more microdescriptors: we have 0/7543, and can only build 0% of likely paths. (We have 0% of guards bw, 0% of midpoint bw, and 0% of end bw (no exits in consensus, using mid) = 0% of path bw.)
onion_service-tor-1  | Mar 26 13:07:39.000 [notice] Bootstrapped 50% (loading_descriptors): Loading relay descriptors
onion_service-tor-1  | Mar 26 13:07:39.000 [notice] The current consensus contains exit nodes. Tor can build exit and internal paths.
onion_service-tor-1  | Mar 26 13:07:40.000 [notice] Bootstrapped 55% (loading_descriptors): Loading relay descriptors
onion_service-tor-1  | Mar 26 13:07:40.000 [notice] Bootstrapped 61% (loading_descriptors): Loading relay descriptors
onion_service-tor-1  | Mar 26 13:07:41.000 [notice] Bootstrapped 66% (loading_descriptors): Loading relay descriptors
onion_service-tor-1  | Mar 26 13:07:42.000 [notice] Bootstrapped 71% (loading_descriptors): Loading relay descriptors
onion_service-tor-1  | Mar 26 13:07:42.000 [notice] Bootstrapped 75% (enough_dirinfo): Loaded enough directory info to build circuits
onion_service-tor-1  | Mar 26 13:07:43.000 [notice] Bootstrapped 90% (ap_handshake_done): Handshake finished with a relay to build circuits
onion_service-tor-1  | Mar 26 13:07:43.000 [notice] Bootstrapped 95% (circuit_create): Establishing a Tor circuit
onion_service-tor-1  | Mar 26 13:07:43.000 [notice] Bootstrapped 100% (done): Done

Compose pulls a NGINX, Tor image, and starts the services you defined.

To check the V3 Onion Address of your onion service, open the file
hidden_service/hostname
.

Open the Tor Browser, and paste your onion service URL in a browser to see the application running.

You should see a welcome message of your NGINX server:

You should see a welcome message of your NGINX server:

This is a basic example of how to host an onion service by yourself. Using Docker and Docker Compose, setting up an onion service becomes very easy. For more information on Docker and Docker Compose, we recommend visiting the official site to explore and learn more.

Link to Tor Project

Link to NGINX

Link to Docker

Link to Docker Compose

Tags:
  • Tor
  • Web Server
  • Security
  • Infrastructure
  • Docker
  • Docker Compose
  • NGINX

24/7 Expert Support

Our experts are always on hand to help answer your questions, get you started, and grow your presence online. You can email us any time