Flakes are just a mechanism of pinning dependencies to fixed versions. When you run a flake it doesnt matter if you're on 24.05, 24.11, or unstable, it'll produce the exact same output.
Yeah, they provide a reproducible environment for the modules.
However, one should know that there is a catch which can make flakes believe differently on different machines when updating inputs. That is when you have inputs in your flake that point to your flakes registry. Especially the system entries can trip you up
Docker Compose runs services, manages dependencies between services, isolates each service in a container, manages a private network. Out-of-the-box flakes don't do any of that - except arguably running one service at a time. What flakes do is build software, which is the thing that Docker Compose doesn't really do. (Or doesn't do well.)
I'd compare flakes to Makefiles with waaay more expressiveness and reproducibility. Or maybe a comparison could be to a Dockerfile, minus containerization, with waaay more expressiveness and reproducibility.
There are tools you can add on to get Nix to do what Docker Compose does:
Arion is a Nix frontend for Docker Compose. You're still using Docker Compose, but it layers on the extra expressiveness and reproducibility of Nix flakes, or other kinds of Nix expressions.
process compose flake is similar, but instead of Docker Compose it is a frontend for Process Compose. You get a similar result, but without containerization. That can potentially avoid the need to run in a VM on non-Linux systems that don't natively support containers.
With docker, the built product is containerized. With a flake, the end product goes into the nix store directory, and may be used in another package, or available to run, or be used in a service, or all the above.