DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Abhishek Anand Amralkar
Abhishek Anand Amralkar

Posted on • Updated on

Manage Your Systems with Nix Package Manager

Nix Package Manager

We will walk through the Nix Package Manager and how we can build immutable systems. This is my first attempt to get Nix for all of my machines mostly Debian's(2 Laptops and 1 Desktop) and a MacBook.

The quickest way to install Nix is to open a terminal and run the following command (as a user other than root with sudo permission):

curl -L https://nixos.org/nix/install | sh

Add source $HOME/.nix-profile/etc/profile.d/nix.sh to your .bashrc or .zshrc.

echo 'source $HOME/.nix-profile/etc/profile.d/nix.sh' >> ~/.bashrc

The Basics

After installation we have some new commands available:

* nix-env used to install dependencies and alter your current profile
* nix-shell used to start shells based on nix expressions
* nix-store used to query or manipulate the nix store

Install a Package

nix-env -iA nixpkgs.clojure 

# Output
installing 'clojure-1.10.1.507'
building '/nix/store/y6r745pjimp232bgknncx27a074i4j0z-user-environment.drv'...
created 44 symlinks in user environment

Query a Package

nix-env -qaP 'consul'

# Output
nixpkgs.consul                      consul-1.7.2
nixpkgs.consul-alerts               consul-alerts-0.6.0
nixpkgs.consul-template             consul-template-0.19.4
nixpkgs.prometheus-consul-exporter  consul_exporter-0.3.0

Uninstall a Package

nix-env -e clojure

#Output
uninstalling 'clojure-1.10.1.507'

Nix Shell

Nix-shell lets you open a shell in a new environment.

In Nix; an environment is a collection of derivations (aka functions) that are put into your PATH.

We can create an environment by creating a .nix file to define the environment. Create a file called consul.nix with below content

Derivations

Nix is built around the concept of derivations. A derivation is simply defined as "a build action". It produces 1 (or maybe more) output paths in the nix store.

with import <nixpkgs> {};

let
  clj = pkgs.clojure;
in
stdenv.mkDerivation rec {
  name = "clojure-environment";

  buildInputs = [
    clj
    pkgs.leiningen
  ];

  shellHook = ''
    echo "using clojure: ${clojure.name}"
  '

and finally login to your env shell

nix-shell packages/clojure.nix
using clojure: clojure-1.10.1.507

To install packages from Non NixOS

{ pkgs ? import <nixpkgs> {} }:
with import <nixpkgs> {};

pkgs.stdenv.mkDerivation {
  name = "consul";

  src = pkgs.fetchurl {
    url = "https://releases.hashicorp.com/consul/1.8.0/consul_1.8.0_linux_amd64.zip";

    sha256 = "98df3e0a8ede84794fa4d20b1b6b5d52ad3b983dec916c4d612cecba7c48a421";
  };
  phases = ["unpackPhase" "installPhase"];



  unpackPhase = ''


'';

  installPhase = ''
    mkdir -p $out/bin
    ${pkgs.unzip}/bin/unzip $src -d $out/bin
    chmod +x $out/bin/consul

  '';
}

To run it

nix-env -f consul.nix -i

The stdenv

The standard build environment in the Nix Packages collection provides an environment for building Unix packages.

To build a package with the standard environment, you use the function stdenv.mkDerivation, instead of the primitive built-in function derivation, e.g.

with import <nixpkgs> {};

let
  py = pkgs.python;
in
stdenv.mkDerivation rec {
  name = "python-environment";

  buildInputs = [
    py
  ];

  shellHook = ''
    echo "using python: ${python.name}"
  '

The standard environment provides the following packages:

    The GNU C Compiler, configured with C and C++ support.
    GNU coreutils (contains a few dozen standard Unix commands).
    GNU findutils (contains find).
    GNU diffutils (contains diff, cmp).
    GNU sed.
    GNU grep.
    GNU awk.
    GNU tar.
    gzip and bzip2.
    GNU Make. 
    Bash. 
    The patch command.

Phases

    patch phase
    configure phase
    build phase
    check phase
    install phase
    buildup phase

Nix Expressions

Nix is not just a package manager. Nix is OS and a Language too.

The Nix expression language is a pure, lazy, functional language. Purity means that operations in the language don't have side-effects (for instance, there is no variable assignment). Laziness means that arguments to functions are evaluated only when they are needed. Functional means that functions are β€œnormal” values that can be passed around and manipulated in interesting ways. The language is not a full-featured, general-purpose language. Its main job is to describe packages, compositions of packages, and the variability within packages.

To read more

https://nixos.org/nix/manual/#ch-expression-language

In this blog, we just looked into just a small functionality of NIX. NIX is much more than that.

Happy Nixing!

Top comments (2)

Collapse
ssimontis profile image
Scott Simontis

I don't think I understand any benefits here. I have to learn new tools versus using ones I am very familiar with, and I don't see any assistance provided when it comes to configuration file setup or producing repeatable builds/deployments.

Collapse
mrturkmen profile image
Ahmet Turkmen

This blog post gives more valuable information how nix is providing more benefits.

grahamc.com/blog/nix-and-layered-d...

🌚 Browsing with dark mode makes you a better developer by a factor of exactly 40.

It's a scientific fact.