I mitigate code execution worries by running all of my services in individual LXD containers. They're all using isolated user namespaces (unique mappings), and are firewalled away from being able to access my internal network. The data is bind-mounted from a ZFS filesystem which is backed up by the host and uploaded to BackBlaze. The containers themselves are also snapshotted by ZFS. Thus, I think the risks of exploits being able to do much damage are greatly reduced.
However, there is still a worry about information disclosure. Yeah, NextCloud can only access the documents it manages -- but some of those documents are somewhat sensitive. I don't know what the ideal solution for this would be (a wholly separate NextCloud instance just for accessing the private stuff? But what if your family needs to access them?). My main worry when hosting NextCloud was that I am entirely trusting the safety of my NextCloud-stored data to an authentication flow that they wrote themselves in PHP (and has had pretty ugly flaws such as silently disabling 2FA or letting you bypass it by clicking "cancel".)
This is a feature. Besides, you can send friends and family a QR code to connect to your WireGuard VPN. It isn't perfect, but it beats having your personal data stolen.
Thanks to letsencrypt "now" (for some time, I know.. but I wanted to do this way before they allowed one to) allowing wildcard TLS certs, I host the above on a domain which doesn't have a single public IP DNS entry, yet has full proper "validated, browser approved" TLS cert.
IOW, I fire up my zerotier client on my phone, open brave, put the URL in, and off I go. https, and for my eyes only.
It's great!
Where people set wildcard DNS this means passive DNS reveals typos, as well as such "hidden" services. wwww.example.com and ddd.example.com are common typos for www for example whereas int-test.example.com is maybe interesting to black hats.
Then dont share your links publicly.
If configuration requires a path to get further than a canned reply from nginx (403, 404, static page..), then it should reduce attack surface a lot. You should not be able to get anywhere near php without the path.
Put your services, on a shared domain name, only yourdomain.com and under a sub-path, like yourdomain.com/thisISAlmostLikeaPassword/nextcloud the subpath is hidden by TLS, unless you make it public by posting it on the internet. And also if you arent careful, like using google "auto-suggest" or just using any Google products, then they will at least know about your path.
Why not just add real HTTP authentication to the site instead?
One should always be wary of password-like mechanisms like secret paths, secret ports, etc. since none of these things are made to be secret, and could be disclosed by something unforeseen. (Paths, for instance, are saved in your browser history/cache, your HTTP caching proxy, if any, and also in the server’s access logs.)
But you see, for what we are discussing here, you could have exploited it even without authenticating, and especially it would have been easier for scanners to find it and exploit, if it was on its own domain.
Defense in depth.
For some services, yes I do basic http auth, besides their own shitty auth.
Downgrade attack, would not work since I use HTTPS Everywhere, and once my browser has visited the site it refused to downgrade - that header is set.