NixOS Explore Download Learn Community Blog Donate Search

Reproducible builds and deployments.

Nix is a tool that takes a unique approach to package management and system configuration. Learn how to make reproducible, declarative and reliable systems.

Download Get started
  • image/svg+xml

    Reproducible

    Nix builds packages in isolation from each other. This ensures that they are reproducible and don't have undeclared dependencies, so if a package works on one machine, it will also work on another.

  • image/svg+xml

    Declarative

    Nix makes it trivial to share development and build environments for your projects, regardless of what programming languages and tools you’re using.

  • image/svg+xml

    Reliable

    Nix ensures that installing or upgrading one package cannot break other packages. It allows you to roll back to previous versions, and ensures that no package is in an inconsistent state during an upgrade.

Examples

    Try new tools without fear

    $ # Lets see if python is present on the system$ python --versionpython: command not found$ # Use nix-shell to create a shell environment with python$ nix-shell -p python3(nix-shell) $ python --versionPython 3.7.7(nix-shell) $ # YAAAY! Python is available(nix-shell) $ exit$ # And this is how you create on demand environments

    Multiple languages, one tool

    $ # Lets create an environment with multiple packages$ nix-shell -p python3 nodejs go rustc(nix-shell) $ node --versionv10.20.1(nix-shell) $ go versiongo version go1.14.1 linux/amd64(nix-shell) $ rustc --versionrustc 1.42.0(nix-shell) $ # Imagine how easy(nix-shell) $ exit$ # And POOF, just like that you are back to your normal environment after$ # playing around. No system was hurt during this time :)

    Development environments

    $ # You can also persist your development environment.$ # Here is a short example with python and nodejs:$ cat -n shell.nix 1 { pkgs ? import <nixpkgs> {} # here we import the nixpkgs package set 2 }: 3 pkgs.mkShell { # mkShell is a helper function 4 name="dev-environment"; # that requires a name 5 buildInputs = [ # and a list of packages 6 pkgs.python3 7 pkgs.python3Packages.virtualenv 8 pkgs.nodejs 9 pkgs.yarn 10 ]; 11 shellHook = '' # bash to run when you enter the shell 12 echo "Start developing..." 13 ''; 14 }$ # Pause the video to read and understand the shell.nix$ # To enter the dev-environment simply run:$ nix-shellStart developing...(nix-shell) $ python --versionPython 3.7.7(nix-shell) $ virtualenv --version16.7.9(nix-shell) $ # With python and virtualenv you should be ready to start(nix-shell) $ # your python project(nix-shell) $ node --versionv10.20.1(nix-shell) $ yarn --version1.22.4(nix-shell) $ # Having node and yarn in PATH you already know you can(nix-shell) $ # do all the good stuff with nodejs(nix-shell) $ exit$ # How hard is it in your company to share the same version of required$ # tooling across different machines?

    Minimal docker images

    $ # We all love docker. But over time it can become tedious to write$ # reliable docker files.$ # What if you could use the power of Nix to build Docker images?$ cat -n docker.nix 1 { pkgs ? import <nixpkgs> { system = "x86_64-linux";} 2 }: # nixpkgs package set 3 pkgs.dockerTools.buildLayeredImage { # helper to build Docker image 4 name = "nix-hello"; # give docker image a name 5 tag = "latest"; # provide a tag 6 contents = [ pkgs.hello ]; # packages in docker image 7 }$ # Pause the video to read and understand the docker.nix$ # Now we build a Docker image with nix-build$ nix-build docker.nix -o result/nix/store/91ry9y0686xn9dgnn6rawfvknj8582ws-nix-hello.tar.gz$ # We can import the image into Docker as usual$ docker load -i ./resulte25615ae850b: Loading layer 1.649MB/1.649MBbde5792b3b71: Loading layer 256kB/256kB1d9c7edd824b: Loading layer 31.63MB/31.63MBab8ee9b997a1: Loading layer 266.2kB/266.2kBf568d8025dd8: Loading layer 71.68kB/71.68kBLoaded image: nix-hello:latest$ # You can see that the Docker layers were automatically calculated.$ docker images | grep nix-hellonix-hello latest 83667617cdb9 50 years ago 32.9MB$ # And for the final thing let's test that it really works$ docker run -ti nix-hello:latest helloHello World!$ # There is a lot we didn't cover in this little demo, but we hope$ # it shows that declarative docker images are possible.

    Declarative cloud images

    $ # How hard would it be to build and configure an Amazon EC2 image?$ # Let us configure a Nginx to serve a "Welcome to nginx!" page, with a$ # valid SSL certificate (via LetsEncrypt) and recommended security settings$ cat -n amazon.nix 1 { pkgs, ...}: 2 { 3 security.acme.acceptTerms = true; 4 security.acme.email = "nix@example.com"; 5 services.nginx = { 6 enable = true; 7 recommendedGzipSettings = true; 8 recommendedOptimisation = true; 9 recommendedProxySettings = true; 10 recommendedTlsSettings = true; 11 virtualHosts."example.com" = { 12 enableACME = true; 13 forceSSL = true; 14 locations."/".root = "${pkgs.nginx}/html"; 15 }; 16 }; 17 }$ # Pause the video to understand the amazon.nix$ # Now we just need to build it.$ nix-build '<nixpkgs/nixos/release.nix>' \ -A amazonImage.x86_64-linux \ --arg configuration ./amazon.nix \ -o ./result...$ ls ./result/nixos-amazon-image-20.09pre130979.gfedcba-x86_64-linux.vhdnix-support$ # The resulting Virtual Hard Disk image (.vhd suffix) can then be$ # imported to Amazon EC2 as usual.

    Test your configurations

    $ # In this example we will look into how to test your NixOS configuration$ # We will create a simple configuration with the `hello` package installed$ # system wide and check that the `hello` world binary works.$ cat -n test.nix 1 { pkgs ? import <nixpkgs> {} 2 }: 3 pkgs.nixosTest { 4 name = "example-test"; 5 # virtual machine with one package installed system wide 6 machine = { pkgs, ... }: { 7 environment.systemPackages = [ pkgs.hello ]; 8 }; 9 testScript = '' 10 # run hello on machine and check for output 11 machine.succeed('hello | grep "Hello, world!"') 12 # test is a simple python script 13 ''; 14 }$ # Pause the video to understand the test.nix$ # To run the test you simply need to run:$ nix-build test.nix...machine1: must succeed: hello | grep "Hello, world!".../nix/store/99cb3pmmyaxp0rs6r596kqq5v8ivp45j-vm-test-run-example-test$ # While this example is simple you can imagine how handy it can be$ # to test interactions between many machines.$ # You can take screenshots, scrape for text and more. Checkout what$ # else you can do in the Tests section in the NixOS manual$ # Happy testing!