Docker mainly does two things: there's Docker images as a way of sharing some container-image, and the container runtime to allow running those images for tasks or services in isolated/fresh ways.
Docker images make it easy to distribute software which runs the same everywhere.
Nix is a package manager which tackles that problem, but without using container images: Nix is for distributing software so it has the same behaviour everywhere.
Nix users are often very enthusiastic about Nix because it also enables all sorts of neat developer experiences. e.g. Nix is great for setting up development environments.
In terms of Nix-vs-Docker, Nix is also capable of building Docker/OCI images. So, you could use Nix instead of writing a Dockerfile.
so locally i use process-compose to avoiding waiting docker builds.
Using a dockerfile with a step like "RUN nix ..."? You can, but it strikes me as a cumbersome way of doing things. Mitchell H describes this way of doing things here: https://mitchellh.com/writing/nix-with-dockerfiles
Whereas, I'd reckon the more idiomatic thing to do is to build the Docker image with Nix code. -- You're going to get a precisely defined environment to share across workstation/CI/etc. Some example Nix code for building Docker images is here https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-supp...
But you can use it for things like:
- declare your application with all dependencies explicitly, so when someone else wants to build it they can (I would argue this is the primary purpose and rest is just built on top of that) - common dev environment (so other developers can get the same dev environment as you with all exact same build tools) - build toolchain (for example if you do embedded environment) - you could use it as a replacement for homebrew/mac ports - a configuration file holding your .dot files (home manager) - if you use NixOS (OS that was built around Nix) then you have OS with a built-in configuration management (i.e. salt/puppet/ansible/chef) that is truly declarative
I think this[1] also shows some crazy stuff you can do with it.
Regarding question around Docker, the great thing is that if you define your application as a nix derivation, then you can easily generate docker that just contains your application and dependencies (the docker in that case is just a deployment unit). The reproducible environment is what docker promised, but practically failed to deliver. Instead of deliver reproducibility, it actually delivered repeatability.
Yes, actually I got interested in Nix because with requirements.txt I could only define python dependencies, and I had no control over for example installing postgresql C library that psycopg2 depends on.
> Then you pair it with a containerization technology like Docker or Podman
You don't have to, but you can, given that in most places containers are being used a lot of people use nix that way.
> And if you use NixOS, you can skip the last part?
Yes, although keep in mind that for example the requirement is to use Kubernetes then you would have to use Kubernetes. But if you need to create for example an EC2 instance. You can use Ubuntu + ansible or you could use NixOS.
Honestly I don't have much experience with NixOS as at my workplace we are mandated to use specific distro for everything.
Edit: I forgot to add additional benefits with using NixOS compared to Ubuntu + ansible for example. All updates are atomic. You either end up with the new configuration or the old configuration, there's no in-between as it would happen with ansible. Second big benefit is easy way to rollback.