There's no separate "server" download. The MyOwnMesh daemon under AllMyStuff is any combination of a regular member and the infrastructure roles it hosts for everyone else. You turn roles on; it starts the listeners and advertises them so your other machines find them on their own. Roles are device-wide — one box can serve your whole fleet.
Be a normal member. Turn it off on a dedicated box so it hosts services and joins nothing — pure infrastructure.
Where two devices find each other — a self-hosted relay your fleet uses instead of the shared one. Safe to run publicly (built-in flood limits).
Tells a device the address the world sees it on, so peers can punch a direct path. No auth, nothing stored.
The fallback relay for devices behind hard NAT (phone hotspots, CGNAT). Answers STUN too, so it covers both on one port.
Application-layer routing between your approved devices. Off by default; needs node on. Most fleets don't need it.
For a typical home fleet, signaling + TURN on one box is the whole job — TURN gives you STUN for free on the same port.
Pick a machine that's always on — a $5 VPS, a Pi in the closet, a spare mini-PC. It doesn't run AllMyStuff; it just runs the MyOwnMesh daemon. We'll take it to a public, TLS-secured signaling relay with STUN + TURN, running as a service that survives reboot.
The mesh under AllMyStuff is MyOwnMesh — free and MIT. On your server, install just the daemon (no desktop app needed to host):
Run it once in the foreground to confirm it starts (we make it permanent in step 6):
A dedicated relay box shouldn't be a member of your fleet — it should just carry introductions. Turn node off so it hosts services and joins nothing:
ctl talks to a running daemon over its local socket, so keep myownmesh serve running in another shell while you configure (or jump to step 6 and run it as a service first).
The simple on/off is one command each. STUN comes free with TURN, so you usually only enable the two:
TURN needs a couple of things the on/off toggle can't set — a login and the box's public IP. Open the config (myownmesh config edit) and fill in the turn block:
node defaults on and signaling ships safe flood-limit defaults, so neither needs to appear by hand. After editing the file, restart the daemon — or re-apply live from the CLI / the desktop GUI's Settings → Services.:3478 is only TURN's control channel. Every relayed connection flows through a separate UDP port, drawn from the OS ephemeral range by default — so you open that whole range too. The enable turn command prints the exact list:
inactive does not mean your cloud provider lets the packets in — open the ports in the security group too. Forgetting the UDP range is exactly why clients show 0 srflx · 0 relay candidates and fall back to nothing.relay_port_min/relay_port_max (e.g. 49152–65535) and open only that range.The relay speaks plain ws://. For your fleet to reach it from anywhere you want TLS on 443 (wss://, which also slips through restrictive networks). One command installs Caddy, writes the proxy, locks the relay to loopback, and starts it:
Two things still have to be true for the certificate to come up:
wss:// a marketing domain hits the website, not a relay. Use a dedicated name like relay.example.com that resolves to your server.Register the daemon with the box's init system — systemd on Linux, launchd on macOS — so it comes back after a reboot:
service status shows installed / enabled / running; start, stop, restart, uninstall do the rest. That's the box done — now point your devices at it.
No config files on this side — it's a settings panel. In the desktop app, open Settings → Networks, pick your network, and open its Servers editor.
Replace the three lists with your own box, then Save & reconnect:
wss://relay.example.com (no port — 443). This is the one that matters most: both ends of a network must share a signaling relay to find each other.stun:relay.example.com:3478.turn:relay.example.com:3478, with the username and credential you set in step 3.Headless box with no app? Set the same three under each network's signaling.servers / stun_servers / turn_servers in its config.json.
Point signaling, STUN and TURN all at your own box and turn off the public fallback, and your devices introduce themselves entirely on infrastructure you control — no shared servers, no third parties in the path.
Set the signaling list to your wss:// host and clear the public fallback (public_fallback: false in config). STUN/TURN as explicit lists pointing only at your box.
Who-is-who is proved with signatures over the encrypted channel, no matter who runs signaling. A relay only ever introduces devices — it never sees your screens, files or audio, and can't forge a device.
Your relay is an accelerator, not a single point of failure. If the box goes down and you've left the fallback on, devices drop back to the shared servers and keep working.
Want this without keeping a server alive yourself? The Private Line is exactly this, run for you at 1 Gbps, for $10/mo. Same network model — one is your time, one is your money.
On the server, ctl services status shows what's bound and — for signaling — whether devices are actually reaching you. That separates "nobody's connected yet" from "I'm broken."
connections: 0The relay's fine — traffic isn't arriving. Check, in order: DNS (does the name resolve here?), TLS/proxy (run npx wscat -c wss://relay.example.com — expect a connect), then the firewall.
0 srflx · 0 relay on clientsUDP isn't getting through. You opened 443 for the proxy but not TURN's control port and its relay range — at the host firewall and the cloud security group. Re-run the step-4 checklist.
It needs a credential, and a public_ip on a wildcard bind. Set both in config.json, then re-apply or restart the daemon.
The #1 cause is two machines on different signaling relays. Make sure every device lists the same wss:// host under Settings → Networks → Servers.
4848, plain ws://. Front it with Caddy for public wss://.3478. Don't run standalone STUN and TURN on the same port — TURN covers both.{ username, password }. Mirror a pair into each device's TURN entry.0 = the OS ephemeral range (open it all). Pin a window to shrink the firewall surface.0 = unlimited.50 events/s, 20 REQ/s, 64 subs, 16 filters/REQ, 65536 bytes, 64 conns/IP. 0 = no limit.~/.myownmesh/config.json. Move the whole tree with MYOWNMESH_HOME.