4 ms·
There’s a few different levels of commitment, I’ll go through the just “dip your toes” variant to the fully commuted version: * Use Nix shell for developer env
by ratorx 4y ago
There’s a few different levels of commitment, I’ll go through the just “dip your toes” variant to the fully commuted version:
* Use Nix shell for developer environment. Use it to provide a version of Docker, Rust, development Postgres etc. This is just a kind of virtualenv you activate after you cd into the project directory. You can manually manage the versions of the tooling for your project separately (if needed) and you don’t need to install these globally on your developer machine.
* Replace Dockerfile with a Nix package. This may be a bit trickier depending on how complicated the app is. You can build the rust app with Nix and then build a Docker image from the rust app and all other things you want in the container. You can do the same for Postgres (although there’s less point, since the Docker image is officially maintained). There’s no direct benefit to doing this (except maybe smaller images if you aren’t using e.g. alpine and maybe slightly better cacheability).
* Replace your base OS with NixOS. This is whatever you run the Docker containers on. You’d still use Docker containers and Docker compose, but the underlying OS would be NixOS, rather than Ubuntu/Debian/etc.
* Replace Docker containers with systemd services on NixOS. This is the hardest sell, but a lot of people use Docker just for versioning and providing dependencies, and you can just use Nix for that. So if you don’t need to use Docker for other things, you can just run apps on bare NixOS, using systemd configured with Nix (the language). That’s what using services on NixOS will do. You’ll basically be writing systemd services for your app (there is already going to be one provided by NixOS for Postgres) in the Nix language and running them directly on Linux. One thing that’s not easy to do with Docker Compose is cron jobs (for backups monitoring etc.). You can run these just as systemd timers. This also has some nice benefits (e.g. user isolation whereas Docker containers run as root, Unix sockets to avoid needing to bind ports and restrict access to certain users, no extra (runtime) layers on top of your OS, less complex networking).
To illustrate as examples on the Docker flow
Start:
Docker, Rust etc. installed globally.
Dockerfile -> build OCI image -> run it as a container on Debian/whatever as distro
Stage 1:
Docker, Rust etc. installed in a Nix Shell
Dockerfile -> build OCI image -> run it as a container on Debian/whatever as distro
Stage 2:
Docker, Rust etc. installed in a Nix Shell
Nix package -> build OCI image with Nix -> run it as a container on Debian/whatever as distro
Stage 3 (can be done independently of 1 and 2):
Docker, Rust etc. installed in a Nix Shell
Nix package -> build OCI image with Nix -> run it as a container on NixOS
Stage 4:
Docker, Rust etc. installed in a Nix Shell
Nix package running as a systemd service managed by NixOS