My journey was: Wireguard (dropped because it is pain in the ass to configure and poor Windows support) -> Tailscale (dropped because it had RCEs at the time) -> Nebula (needs a separate service that issues host certificates, or manual clunky process) -> Yggdrasil. This was for personal stuff, but now I am also using it for my p2p GPU cloud startup (see https://borg.games/setup).
In comparison to other options I found Yggdrasil to be straightforward to setup:
1. Get it
2. Edit yggdrasil.conf to add public peers you want to connect to. You can get them from https://publicpeers.neilalexander.dev/
3. Repeat on all machines (Android is supported, unsure about iOS)
Now they have access to each other and everyone else in Yggdrasil by their _permanent_ Yggdrasil IPv6 address (derived from PrivateKey in yggdrasil.conf).
OPTIONAL quality-of-life stuff:
4. add Listen entries to yggdrasil.conf and a corresponding port forward on your home router then use it as a peer for your out-of-home machines to avoid extra hop to public peers
5. Create a bunch of DNS AAAA (IPv6) at your favorite DNS provider to give your machines names
Extra bonus: they recently added userspace stack support, so you can embed Yggdrasil directly into your app, and use it as a SOCKS proxy: https://github.com/yggdrasil-network/yggstack