It is straightforward, but so is the NixOS module system, and I could describe writing a custom module the same way you described custom Docker images.
But it works on Ubuntu, it works on Debian, it works on Mac, it works on Windows, it works on a lot of things other than a Nix install.
And I have to know Docker for work anyhow. I don't have to know Nix for anything else.
You can't win on "it's net easier in Nix" than anywhere else, and a lot of us are pretty used to "it's just one line" and know exactly what that means when that one line isn't quite what we need or want. Maybe it easier after a rather large up-front investment into Nix, but I've got dozens of technologies asking me for large up-front investments.
Nix is for reproducibility. Nix and docker are orthogonal. You can create reproducible docker image via nix. You can run nix inside docker on systems that doesn’t allow you to create the nix store.
Docker containers also don't have a "standard" for where to put binaries (outside of CMD/ENTRYPOINT), how to configure users/uids (many still run as root?), whether to put multiple services in one container or separate containers, where to put user data, etc. NixOS coordinates this centrally like any distro, assigning paths and UIDs and ports.
If a Docker image truly is the best way to use a bit of functionality (like Home Assistant), then I will just configure NixOS to run it in podman as a systemd service with host networking.
I have not come across something that I could not package. The trick is that Nix composes functionality in a way that Dockerfiles or docker-compose configs cannot, because it's one language, one system, one abstraction.