dockerfiles (or even better but less popular, {default,shell,flake}.nix) are code that can be tracked in a repository and reasoned about, "stuff installed locally" isn't.
I don't see how Nix is better than Docker as they serve different purposes. While I agree using containers helps aid in automating build environments, you can also checkin shell scripts and Ansible roles into repos as well. I understand the criticism and hopefully people aren't going to be so thin-skinned to take offense, but at the same time if it works then it works.
Nix and Docker share the same purpose in this context: declaring the dependencies needed for this environment. This can include shell scripts, system-level dependencies etc. If anything I would say Nix would be better here (logical middleground in filesystem separation between having access only to whats in the container vs having to juggle system-level dependency versions for the entire system), while also having better version pinning.
> I don't see how Nix is better than Docker as they serve different purposes
Nix can build many things, among them whole operating systems on the metal, virtual machine images, and container images (including Docker images).
When you use Nix to generate Docker images and deploy them in production using Docker, Nix is not functioning as an alternative to Docker, but your *.nix file is functioning as an alternative to your Dockerfile.
Defining container images in terms of Nixpkgs rather than via a Dockerfile, and assembling it via Nix rathet than `docker build` does have some advantages.
1. It moves you from mere repeatability in the direction of true reproducibility— it makes your outcomes more predictable and reliable
2. Having the benefit of knowledge of the actual dependencies on the system down to the package (or subpackage) level, Nix knows how to generate minimal images when Docker can't.
Plus there's the prospect of reuse, I guess; an environment you've defined in Nix for building Docker containers is easy to install and debug in other environments, without the extra complexity of Docker and filesystems exports/imports, port forwarding, etc. That can be nice, to be able to easily separate out what you're troubleshooting or learning as you're creating or modifying the image's environment.
But yeah that doesn't mean that pairing Dockerfiles with imperative or convergent configutation management or provisioning tools can't also sometimes work well enough in a given situation.