The registry itself can be self-hosted easily, however everything on top (authentication, web UI, automation, ...) is surprisingly difficult. Plus technical challenges as pointed out by other commenters.
AWS has a registry as well. Both solutions are and easy way to host private and public repos. But Dockerhub offers access to a huge ecosystem that everyone is already plugged into that would be devastating if it shut down. You’d potentially have to re create so many base images from scratch.
Nexus isn’t a terrible option, but the application feels pretty dated from a deployment and maintenance perspective. We’re using it for ruby gems and internal docker registry. I haven’t looked into viable alternatives for the gems side of things—that works well enough—but we’re replacing the docker registry with gitlab.
Just run a custom GitLab instance, and you get all that for free.
For my open source projects on git.kuschku.de I also have a gitlab container registry on k8r.eu, and it’s been amazing to work with.