Installing OS-level packages using Nix
The Nix Package Manager is a powerful tool for managing packages on Unix-like operating systems. Nix allows users to install software in a predictable, reproducible, and reliable manner. It's different from traditional package managers like apt-get
, yum
, and pacman
in that it allows multiple versions of software to coexist on the same system without conflict.
How Nix Works
Nix works by installing packages into the Nix store, which is typically located at /nix/store
. Each package in the store has a unique path that includes its name, version, and a hash of its dependencies.This approach brings several advantages:
- Atomic upgrades and rollbacks: Changes to the system are made atomically. If the installation of a package fails, the system remains in its previous state. Also, you can roll back to a previous configuration if required.
- Multiple versions: Different applications can use different versions of the same package without any conflict.
- Reproducible environment: Given a Nix expression, Nix will always build the same environment, regardless of the current state of the system.
In addition, once a package is installed, Nix automatically makes its commands available from the terminal by adding its installation location to the PATH environment variable. This means that you can start using the commands provided by the package immediately after installation, just like you're used to with other package managers.
Using Nix
Nix comes preinstalled with Codesphere. You can install packages with the nix-env
command. For instance, to install hello
, a program that produces a friendly greeting, you'd run (according to the package instructions):
nix-env -iA nixpkgs.hello
You can remove packages with the -e
option:
nix-env -e hello
And you can update packages with the -u
option:
nix-env -uA nixpkgs.hello
You can find a list of available Nix packages including instructions for installation on their search: https://search.nixos.org/packages
Package Names and Versions in Nix
Please note that package names in Nix may differ from those in other package managers like apt-get
. The exact names and versions of packages available in Nix can be viewed in the Nix package index on the mentioned NixOS website.
Some packages in Nix may be named differently or have different versions than in other package managers, as the Nix community maintains the packages independently.
Creating Project-Specific Environments with Nix
Unlike traditional package managers that install development tools and libraries system-wide, Nix allows for the creation of project-specific environments with the necessary tools and libraries. This can be achieved with the nix-shell
command.
To create a project-specific environment, you need to create a shell.nix
file in your project directory that lists the required dependencies. Here's a simple example:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [ pkgs.python3 pkgs.python3Packages.numpy ];
}
You can then run nix-shell
in your project directory to provide a shell with Python and NumPy. In this environment, you can be sure that you have the correct versions of your dependencies, regardless of the state of the rest of your system.
You can also use this in our CI pipelines with a syntax similar to this: nix-shell --run "your command"
.
Creating your own packages
You can also use .nix files to create your own packages or even install things with other package managers that are themselves a nix package.
You can use this for example to install Java quarkus by adding the following shell.nix file:
{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = with pkgs; [ jbang ];
shellHook = ''
echo ">>>> Making sure quarkus is installed"
jbang trust add https://repo1.maven.org/maven2/io/quarkus/quarkus-cli/
jbang app install --fresh --force quarkus@quarkusio
echo ">>>> Updating PATH"
export PATH=~/.jbang/bin/:$PATH
echo ">>>> You can start the debug mode via 'quarkus dev' (this project was created via 'quarkus create')."
'';
}
Finding legacy packages
Sometimes it can be difficult to find package versions for older legacy versions of some frameworks like php because they are not maintained in the core Nix repository. We found this community maintained search engine to very helpful in these cases: https://lazamar.co.uk/nix-versions/?channel=nixpkgs-unstable&package=
Use with caution, some packages may be maintained better than others.
Transitioning from apt-get to Nix
If you're used to using apt-get
or another traditional package manager, there are a few key differences you should be aware of when switching to Nix.
- Installation location: As mentioned above, Nix installs packages in the Nix store, not in common directories like
/usr/bin
. - Root privileges: You don't need to use
sudo
to install packages with Nix. This is because Nix installs packages to your user's Nix store, not system-wide. - Multiple versions: Nix allows you to have multiple versions of a package installed at once. This is different from
apt-get
, which only allows one version to be installed at a time. - System configuration: Nix goes beyond package management and can manage your system configuration. This is a more advanced feature and goes beyond the scope of this introduction.
Workaround for NX The following projects are defined in multiple locations:
It seems like some frameworks like NX complain about packages installed via Nix in our .codesphere-internal
folder which exists in every workspace.
While this seems to be a bug on their end https://github.com/nrwl/nx/issues/20959#issue-2060897714 there is an easy workaround by adding .codesphere-internal/*
into your .nxignore
or alternatively .gitignore
file.