Host a Decentralized Website with NomadNet
This is Part 10 of a 12-part series on building private, resilient communication networks with Reticulum, LoRa, and associated tools.
The web as we know it depends on DNS, domain registrars, hosting providers, and certificate authorities. NomadNet lets you host pages — essentially tiny websites — directly on the Reticulum network. No domain name, no server, no cloud provider. Your node is the server, and it's reachable by its cryptographic address.
What is NomadNet?
NomadNet is a terminal-based application that provides:
- Encrypted messaging via LXMF (like Sideband and MeshChat)
- Page hosting — serve static and dynamic content to anyone on the Reticulum network
- Page browsing — visit pages hosted on other NomadNet nodes
- A distributed message store — hold messages for offline users (propagation node)
The page hosting is what makes NomadNet unique in the ecosystem. Pages are written in micron markup (a lightweight format designed for low-bandwidth networks) and can be browsed from NomadNet, MeshChat, or Sideband.
Step 1: Install NomadNet
pip install nomadnet
Or on restricted systems:
pip install nomadnet --break-system-packages
Step 2: First Run
nomadnet
On first launch, NomadNet:
1. Creates its config directory at ~/.nomadnetwork/
2. Generates a Reticulum identity
3. Opens the terminal UI with a guide section
The UI has several sections accessible via the top menu: - Conversations — LXMF messaging - Network — browse nodes and pages - Guide — built-in documentation
Press Ctrl+Q to quit.
Step 3: Enable Page Hosting
NomadNet serves pages from ~/.nomadnetwork/storage/pages/. Create this directory if it doesn't exist:
mkdir -p ~/.nomadnetwork/storage/pages
To enable your node as a connectable page host, edit ~/.nomadnetwork/config:
[node]
enable_node = yes
node_name = My Node
announce_at_start = yes
announce_interval = 360
This tells NomadNet to: - Act as a connectable node that serves pages - Announce itself on the network so others can find it - Re-announce every 360 minutes (6 hours)
Step 4: Write Your First Page
NomadNet pages use micron markup, a simple format designed for minimal bandwidth. Create ~/.nomadnetwork/storage/pages/index.mu:
>Welcome to My Node
This is a decentralized page hosted on the Reticulum network.
No DNS. No cloud. No domain registrar. Just cryptography and radio waves.
>>About
This node is part of a local Reticulum mesh network.
It serves pages over LoRa, WiFi, and the internet simultaneously.
>>Links
`[My Blog|/blog.mu]`
`[Network Info|/info.mu]`
`[Contact Me|lxmf://YOUR_LXMF_ADDRESS_HERE]`
Micron Markup Quick Reference
| Syntax | Result |
|---|---|
>Heading |
Level 1 heading |
>>Subheading |
Level 2 heading |
>>>Sub-subheading |
Level 3 heading |
`[Link Text\|/path.mu]` |
Link to another page |
`[External\|lxmf://address]` |
Link to an LXMF address |
*bold text* |
Bold |
_italic text_ |
Italic |
- at line start |
Horizontal rule |
! at line start |
Preformatted/code block toggle |
Create additional pages in the same directory. Link between them using relative paths.
Step 5: Create Dynamic Pages
NomadNet can execute scripts to generate pages dynamically. Create a file with a .mu extension that starts with a shebang:
Create ~/.nomadnetwork/storage/pages/status.mu:
#!/usr/bin/env python3
import time
import os
print(">Node Status")
print("")
print(f"Current time: {time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Uptime: {os.popen('uptime -p').read().strip()}")
print(f"Load: {os.popen('cat /proc/loadavg').read().strip()}")
print("")
print(">>System")
print(f"Hostname: {os.uname().nodename}")
print(f"Platform: {os.uname().sysname} {os.uname().machine}")
Make it executable:
chmod +x ~/.nomadnetwork/storage/pages/status.mu
When someone visits /status.mu, NomadNet executes the script and serves the output as a micron page. You can use Python, bash, PHP, or any language — NomadNet just runs the file and captures stdout.
Step 6: Run as a Daemon
For an always-on node that serves pages without the TUI:
nomadnet --daemon
Or with console logging:
nomadnet --daemon --console
Create a systemd service at ~/.config/systemd/user/nomadnet.service:
[Unit]
Description=NomadNet Daemon
After=default.target
[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=nomadnet --daemon
[Install]
WantedBy=default.target
Enable it:
systemctl --user daemon-reload
systemctl --user enable --now nomadnet.service
sudo loginctl enable-linger $USER
Step 7: Browse Your Node
From NomadNet (TUI)
On another machine running NomadNet, go to the Network section, press Ctrl+U to open the URL dialog, and enter your node's destination hash. NomadNet will connect and display your pages.
From MeshChat
MeshChat can browse NomadNet pages. Enter the node's destination hash in the page browser.
From Sideband
Sideband also supports browsing NomadNet pages from its interface.
Setting Up a Propagation Node
NomadNet can also act as an LXMF propagation node — storing messages for offline users and delivering them when they reconnect. This is the Reticulum equivalent of a mail server.
In ~/.nomadnetwork/config:
[node]
enable_node = yes
node_name = My Propagation Node
announce_at_start = yes
[propagation]
enable_propagation = yes
Now your node will accept and store LXMF messages for any destination. When a user configures your node as their propagation node in Sideband or MeshChat, messages sent to them while offline will be held by your node until they connect and retrieve them.
Community Extensions
The NomadNet community has built several useful extensions:
- NomadForum — a discussion forum system for NomadNet
- micron-blog — a blogging system using micron pages
- md2mu — convert Markdown to micron markup
- LXMF-Bot — automated LXMF message responders
- LXMF Messageboard — a public message board over LXMF
- NomadForecast — weather forecasts served as NomadNet pages
These are all available on GitHub and can be installed alongside NomadNet.
Page Hosting over LoRa
Yes, you can serve NomadNet pages over LoRa. It's slow — a simple text page might take 10-30 seconds to load at typical LoRa data rates — but it works. This means someone with a handheld RNode can browse your pages from kilometers away with zero internet infrastructure.
For LoRa-served pages, keep them small: - Minimal text, no unnecessary formatting - Avoid dynamic pages that generate large output - Think "information bulletin" not "website"
What's Next
You're now hosting decentralized content on the Reticulum network. In the next guide, we'll add maximum privacy by routing Reticulum traffic through I2P and Tor — hiding not just your message contents, but your network identity and physical location.
Previous: [Part 9 — Bridge Your LoRa Island to the Internet] Next: [Part 11 — Reticulum over I2P and Tor: Maximum Privacy Networking]
