Reproducible builds and deployments.

Share your development tools between developers (and CI, and deployments) without worrying (XXX: need a better word). NixOS is an open source project that will help you achieve redproducibility in your project. Many know NixOS as the declerative linux distribution that is not afraid to be different (XXX: too bullshit like argument).

Get started

TODO: A video / picture of NixOS in action!


Try new tools without fear

Don't clutter your system with tools that you use only now and then.

python --version
python: command not found
nix-shell -p python3
(nix-shell)python --version
Python 3.7.7

One tool, multiple languages

nix-shell -p python3 nodejs go rustc
(nix-shell)node --version
v10.20.1
(nix-shell)go version
go version go1.14.1 linux/amd64
(nix-shell)rustc --version
rustc 1.42.0

Isolated development environments

After you get familiar with nix-shell -p you can take the next step further and learn some Nix. To setup a more persistent environment you can also write a simple shell.niix file:

{ pkgs ? import <nixpkgs> {}
}:
pkgs.mkShell {
  name = "dev-shell";
  buildInputs = [
    pkgs.python3
    pkgs.python3Packages.virtualenv
    pkgs.nodejs
    pkgs.yarn
  ];
}

Then enter development environment with:

nix-shell
(nix-shell)virtualenv --version
16.7.9
(nix-shell)yarn --version
1.22.4

Commit the above shell.nix file and let you coworkers have easier time setting their development environment.

Minimal docker image

Declarative way to build minimal docker images. No build tools inside docker image, no complex multi stage build process, only what your application needs.

The following Nix expression (default.nix) defines a docker image with only Python 3 installed in it.

{ pkgs ? import <nixpkgs> {}
}:
pkgs.dockerTools.buildLayeredImage {
  name = "only-python";
  contents = [ pkgs.python3 ];
}

To build and run the image you need to:

nix-build
...
/nix/store/hb8xwmgd1pfrwgmc3indi2rrgcjr3wa3-docker-image-only-python.tar.gz
docker load -u ./result
...
Loaded image: hello:hb8xwmgd1pfrwgmc3indi2rrgcjr3wa3
docker run hello:hb8xwmgd1pfrwgmc3indi2rrgcjr3wa3 python -c "print('hello world')"
hello world

Learn more how to build docker images.

Declarative cloud images

How hard would it be to build and configure Amazon AMI?

With the following amazon.nix we defined nginx which is serving example /var/www folder, having a valid ssl certificate (via LetsEncrypt) and enabled recommended security settings.

{ pkgs, ...}:
{
  security.acme.acceptTerms = true;
  security.acme.email = "nix@example.com";
  services.nginx = {
    enable = true;
    recommendedGzipSettings = true;
    recommendedOptimisation = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;
    virtualHosts."example.com" = {
      enableACME = true;
      forceSSL = true;
      locations."/".root = "/var/www";
    };
  };
}

Now we just need to build it and upload it.

nix-build '<nixpkgs/nixos/release.nix>' -A amazonImage.x86_64-linux --arg configuration ./amazon.nix
...
/nix/store/wmg6gcgnh6bk8d98syydfq73q6hjv682-nixos-amazon-image-20.09pre130979.gfedcba-x86_64-linux
ls -lh ./result/
-r--r--r--     1 root root   1.4G Jan  1  1970 nixos-amazon-image-20.09pre130979.gfedcba-x86_64-linux.vhd
dr-xr-xr-x     2 root root      4 Jan  1  1970 nix-support
nix-shell -p awscli
(nix-shell)export AWS_IMAGE="./result/nixos-amazon-image-20.09pre130979.gfedcba-x86_64-linux.vhd"
(nix-shell)aws s3 cp --region $REGION $AWS_IMAGE "S3://${BUCKET}/${AWS_IMAGE#/}"
...

TODO: Ideas

  • How to integrate with CI (travis, github actions, buildkite, ...) but that is notreally a deployment

NixOps

TODO: can not come with a good example that is simple enough