I’ve been using Nix for a year now. It’s been going fairly well, by the way. Here are some misconceptions I’ve had to overcome to become a more productive Nixer.
§False: You can’t deploy Nix software to Docker or Kubernetes
False. If you can push to a docker registry such as docker.io, you can deploy to Docker or Kubernetes using Nix.
You can use dockerTools.buildImage
to build a docker image from Nix. The
return value of this function is a path to the docker image tarball. You can
load it to your local registry using docker load < /path/to/tarball
.
Wager wrote an excellent blog post about deploying software with Docker and
Nix. In short he can build Docker images using dockerTools.buildImage
within GitHub actions via:
- Invok
nix-build
docker load < /path/to/tarball
- Send the image to another registry using skopepo or docker push.
§But I need to use a Dockerfile
Did you review dockerTools.buildImage
? If yes, chances are your requirement
for a Dockerfile is either non-technical or quite obscure. In any case,
that’s a-ok! I found it is possible to install a flake from within a Dockerfile.
Alternatively you can use buildkit-nix
. buildkit-nix
lets you build docker
images from .nix
files directly from the docker command. Example: docker build -t nginx-nix -f default.nix .
.
§False: You shouldn’t use a shell.nix because flake.nix is a thing
Why reach for a power drill when all you really need is a screw driver? Ask yourself what your needs are:
-
Do you just want to specify software to pull in test something quickly or for development purposes only?
OR
-
Do you want to pin specific software versions in your environment? (Like NPM
package.lock
?) -
Do you wish to deploy or install a software application?
If you said no to software pinning and deploying software, you can get use a
shell.nix
. Its primary benefit is simplicity - there’s more tutorials out
there and support code that you can copy-paste.
If you think you’ll want to pin software or deploy software, skip the
shell.nix
.
Example: I use a shell.nix
to pull in tools like ansible or terraform within
a specific project directory. I do this in conjuction with direnv
automatically pulling in my shell.nix
. On the other hand my git repos that
need to be installable, should have flake.nix
files instead.
§False: You need to use git
False. Flakes do not need git to work. A source code manager (SCM) like git is best practice. You should use git or whatever you know. If you don’t know any, start with git :).1
git clone https://github.com/NixOS/templates.git
rsync -r templates/bash-hello .
cd bash-hello
ls -la # No .git directory here...
$(nix build . --print-out-paths)/bin/hello # Hello Nixers!
§False: Flakes replace Nix channels
False. I made a wiki edit documenting a community-perceived deprecation of nix-channels. This article was reverted within a day.
There are strong opinions on both sides. Don’t believe any of the folks claiming one is preferred over the other, as we will see below, Nix is designed to me mechanism free, so all preferences are equally (in)valid.
§False: You cannot use flakes with channels
You can use flakes with channels. It probably doesn’t make sense for your use case, but you can.
In most cases it isn’t desired to use flakes and channels simultaneously, such
as the case of using a flake.nix
for your NixOS configuration, but your flake
doesn’t set the nix.nixPath
to reference your flake. In this case
nix-shell
will pull in out of date software from an old Nix channel that you
thought you had gotten rid of.
§False: You don’t need to learn to code to use Nix
False. You should know how to code because Nix is written in a programming language called Nix. More precisely, you will be most successful with experience in functional programming, familiarity with a lazy evaluation model, variable substitution, familiarity with languages designed for configurations such as JSON/YAML/TOML/INI/Terraform HCL, thorough C++ won’t hurt, since Nix itself is written in C++.
Nix is rough around the edges, so you will want to have more than enough programming experience to dig yourself out of any Nix-holes that you fall into. If you do not know how to code, you won’t get very far with Nix. Keep this in mind when pushing for adoption within your organization. If you are unwilling to train your team to code with Nix, you shouldn’t adopt it, period.
§False: NixOS works well on low resource systems
False. Out of the box Nix will build derivations on a tmpfs in
/run/users/...
. This tmpfs is configured to be about 10% of your system
memory. With this poorly-found default, you will have intermittent build
issues on any host that does not have loads of RAM. The work around is to setting a
TMPDIR
environment variable. You can choose a directory that is not a tmpfs,
such as /tmp
on a default NixOS install. See my other blog post Can 4GiB meet your needs in 2023? for more tips with NixOS on low memory systems.
You will also expect to use more disk than if you used a more standard distro,
because you trade off reproducibility for installation footprint size. My
workstation’s /nix/store
is 93.1 GB.2
Evaluating Nix derivations can take some time, so you will likely have to have an expectation similar to Gentoo compile times if you’re building stuff on low end hardware (including running nixos-rebuild).
§False: NixOS is viable for 32-bit x86 systems
False, you need to build your own “distro” like Gentoo. Nix becomes a meta-distribution like Gentoo for x86 (IA-32) or other non-standard platforms. You will have to build most derivations (packages) because the build infra doesn’t cache most of x86 derivations. You will run out of memory due to poor NixOS defaults on low memory systems.
If none of the above deters you, x86 and NixOS work well together.
I tried to set up NixOS on my ThinkPad x31. Pentium M, mSata SSD in a IDE adapter, and 512 MiB of ram. NixOS failed this test miserably. I kept running out of memory. I added more swap, but found it simply took forever to run nixos-rebuild on a fairly minimal base sytem configuration. Meanwhile Debian was operating on that 2004 laptop with a graphical desktop and a couple GB of storage used.
§False: You need to use home-manager, age-nix, and additional packages to use NixOS
False. You can use Nix or NixOS without any additional software support packages. In fact, you should start with less - keeps it simple and lets you focus on what’s important - getting up to speed with Nix without incurring a massive time investment that is taking you away from getting your primary computing tasks done.
Regardless, these tools can be helpful. I recommend careful review before adopting any tool. Somebody else is maintaining that project and their usecases may not align with your own uses. Not to mention adopting even more Nix tools will become a worsening time sink, so be ready to waste a lot of time. Remember, everybody’s Nix solution is different, so you’re going to have to get messy with code about and get it working.
§False: You need to run NixOS to deploy Nix software
False. Nix works fine with Docker as outlined above.
You could also consider a hybrid approach: Ship the software in a Nix
closure - so it’ll live in /nix/store
, but manage the daemons or applications
using OS native subsystems such as systemd units or launchd definitions.
§Does using Nix without NixOS negate the benefit of Nix?
You can still have your reproducible builds and easy to maintain packages with
this workflow. I think this would be less work than shipping .deb
packages.
§False: To deploy software, you need to contribute to Nixpkgs
Nixpkgs is the official repository of Nix software. It presently has 5000+ issues open, and 4400+ pull requests open. Some are from 2017. Some are from minutes ago. It is not a good use of your time to contribute back to Nixpkgs. Only do so if you really do want to share your changes with the rest of the Nix community. If you do contribute, just be patient, maybe participate in some politicking so you can then ask your newly found Nix influencers to check over your PRs for you.
If you want to package software, you just do it, add it to your Nix configuration, and carry on. If you want to share it, you can consider contributing your changes to Nixpkgs. If you need to share with a smaller audience, consider adding these packages to a flake, then publishing the flake. This is an alternative way to ship software with Nix. Historically you can also use the Nix User Repositories (NUR).
If you try to contribute to Nixpkgs before knowing how to deploy custom software locally, you’re going to have a difficult time getting anything done quickly.
§Maybe false: My workplace should adopt Nix
Think about why you want Nix at work. If you think it objectively would eliminate a bunch of problems, it might be worth building an adoption plan and getting buy in. Consider who maintains your Nixpkgs fork or Nix codebases (you’ll end up with a flake or overlay for your custom derivations). Consider who will maintain all the infra needed to operate Nix in a meaningful way with significant customization to Nixpkgs. This looks like additional build environments designed just to build Nix closures. I’ve never done this, so there might be more components needed to use Nix at scale.
Nix is not a well understood product. Each consultant will try to bring their own unique solution to the same exact problem. Nobody really understands Nix except for a few extremely clever devs who have been cursed with the Curse of Knowledge. They don’t know how to relate to lay, non-Nix users anymore. You see this on forums and stuff. “It’s so easy!”, or “Just create a flake.nix and edit it to look like my sample.” Famous “Nix” words. And since everyone approaches Nix in a slightly different way due to its mechanism-free design, tutorials rarely work out of the box. You need to understand the content before trying to apply it in a tutorial.
§False: Nix is a cohesive solution
Absolutely false. Nix is like x11 - it provides mechanism but no policy. This means if you want to do something weird, Nix will let you. It also means you have to do a lot of research to determine which software support packages to pair with Nix. You will also spend time finding best practices, since there is no cohesive community guidance around the core NixOS system - you need to draw your own conclusions.
If you’re looking to adopt Nix for anything nontrivial, consider hiring somebody like myself to consult on the project. Nix is a business risk that can pay off with support.
§Conclusion
I like Nix. I hope you learned something surprisingly about Nix from this post. If you’re interested in trying out Nix or NixOS, try in a virtual machine or on a spare laptop. Try on something non-essential. I hope you like it too.
-
Pro tip: Run
git add --intent-to-add .
before runningnix build
, or nix build won’t see your changes not in the git index. You’ll still need to rungit add
before committing. ↩︎ -
According to ZFS the actual used size is this uses just 55.1 GB thanks to ZFS compression. This speeds up accessing
/nix/store
because less blocks need to be read from disk. ↩︎