Skip to content

Instantly share code, notes, and snippets.

@jschoolcraft
Forked from inscapist/flake-direnv.md
Created March 4, 2022 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jschoolcraft/b3f6781a4cef84afcca62bf7d5ef256a to your computer and use it in GitHub Desktop.
Save jschoolcraft/b3f6781a4cef84afcca62bf7d5ef256a to your computer and use it in GitHub Desktop.
Nix Flakes and Direnv on Mac OSX (Catalina)

Development environment with Nix Flakes and Direnv

This document is targeted at those who seek to build reproducible dev environment across machines, OS, and time.

It maybe easier for remote teams to work together and not spending hours each person setting up asdf/pyenv/rbenv, LSP servers, linters, runtime/libs. Nix is probably the closest thing to Docker in terms of development environment.

Flake is used here because it provides hermetic build, with absolutely no reliance on system environment (be it Arch/Catalina/Mojave). Also it freezes dependencies in flake.lock so builds are reproducible.

This gist provides the setup to develop Java/Clojure/Python applications on Nix. But it can be easily adapted to ruby, nodejs, haskell.

Nix

https://nixos.org/guides/install-nix.html

No assumption is made whether you are using home-manager, configuration.nix. I don't use those because I am not pure enough :p

You just need to know:

  1. What is a nix derivation (read here)
  2. The main nix commands (read here)
  3. What is a nix channel

In summary:

  • nix-env is like homebrew, eg. nix-env -iA nixpkgs.nixfmt
  • nix-build turns derivation into binary. (think of it as make)
  • nix-shell or nix develop allows you go enter a shell with the build environent

Nix packages can be found at https://search.nixos.org/packages

Initially, I have mistaken the Nix channel (eg. nix-channel --add https://nixos.org/channels/nixpkgs-unstable) as the same as the Nix package (nix-env -f '<nixpkgs> -q nix'). They are not the same, the former determines the version/recency of packages, while the latter is a CLI.

Flake

Install bleeding-edge Nix with flake support

# At the time of writing, they are equivalent, just run either 1 of them:
nix-env -iA nixpkgs.nixFlakes # do this,
nix-env -iA nixpkgs.nixUnstable # or this

Enable flake's experimental flag

Modify ~/.config/nix/nix.conf with You might see ca-references in other people's nix.conf, and that is for running nix profile list|add|remove, which is out of the scope of this guide.

experimental-features = nix-command flakes
keep-derivations = true
keep-outputs = true

keep-* is used by nix-direnv in the next section

Usage

To use flake, simply create flake.nix in the project root.

Flakes are self-contained units that have inputs (dependencies) and outputs (packages, deployment instructions, Nix functions for use in other flakes)

taken from https://serokell.io/blog/practical-nix-flakes

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs";
  };

  outputs = { self, nixpkgs }: {
    packages.x86_64-linux.hello = /* something here */;
  };
}

You can use various input format in flake (and that is a power I like)

{
  # github example, also supported gitlab:
  inputs.nixpkgs.url = "github:Mic92/nixpkgs/master";
  # git urls
  inputs.git-example.url = "git+https://git.somehost.tld/user/path";
  # local directories (for absolute paths you can omit 'path:')
  inputs.directory-example.url = "path:/path/to/repo";
  # Use this for non-flakes
  inputs.bar.url = "github:foo/bar/branch";
  inputs.bar.flake = false;
  # Overwrite inputs in a flake
  # This is useful to use the same nixpkgs version in both flakes
  inputs.sops-nix.url = "github:Mic92/sops-nix";
  inputs.sops-nix.inputs.nixpkgs.follows = "nixpkgs";
  # Pin flakes to a specific revision
  inputs.nix-doom-emacs.url = "github:vlaci/nix-doom-emacs?rev=238b18d7b2c8239f676358634bfb32693d3706f3";
  inputs.nix-doom-emacs.flake = false;
}

Direnv

Direnv does not depend on Nix at all, install it from official website https://direnv.net.

Even without Nix, Direnv is pretty useful on its own. I use it with Doom emacs (https://github.com/hlissner/doom-emacs/tree/develop/modules/tools/direnv)

Nix Direnv

Do this for the first time:

git clone https://github.com/nix-community/nix-direnv $HOME/nix-direnv

# then, put this in ~/.direnvrc 
#   to source nix-direnv into .direnv
echo "source $HOME/nix-direnv/direnvrc" >> ~/.direnvrc

Where to go from here

  1. Learn more about Nix language, stdenv and the API
  2. Read up on Flake here and here
  3. Write your own overlay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment