diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/README.md b/README.md index 193b717..544cd59 100644 --- a/README.md +++ b/README.md @@ -1 +1,99 @@ # Nix flake development environment example + +> **Warning**: [Nix flakes][flakes] are an experimental feature in [Nix]. Flakes +> will eventually become the de facto standard way to use Nix and thus you may +> find it worthwhile to learn how to use them. But beware that there may be +> breaking changes in the user interface around flakes. + +This repo provides an example [Nix flake][flakes] that outputs a reproducible Nix +[development environment][env] that works across [several systems][systems]. + +## Prerequisites + +In order to use this starter template, you need to have [Nix installed][install] +and [flakes enabled][enable]. + +## Explore this flake + +To see what this flake provides: + +```shell +nix flake show +``` + +### System support + +As you can see, this flake outputs `default` development environments +(`devShells`) for a variety of architectures: + +- `aarch64-darwin` (macOS on Apple Silicon) +- `aarch64-linux` (Linux on ARM64) +- `x86_64-darwin` (macOS on AMD/Intel) +- `x86_64-linux` (Linux on AMD/Intel) + +## Using the environment + +There are two ways to use the [Nix development environment][env] provided in +this flake: + +1. You can clone this repo and run `nix develop` inside of it: + + ```shell + git clone https://github.com/nix-dot-dev/nix-flake-example + cd nix-flake-example + nix develop + ``` + + > **Note**: If you have [direnv] installed, you can also enter this + > flake-provided development environment by running `direnv allow`. Once + > you've done that, you will automatically enter the environment every time + > you navigate to this directory. + + +This will likely take some time, as Nix needs to download [Nixpkgs] and then +install the tools provided in the environment. Once that's finished, you should +be greeted by a welcome message and then enter a [Bash] shell with a `bash-5.1$` +prompt. + +This dev environment provides several tools: + +- [Node.js] +- [Python] +- [Go] +- [Terraform] + +You can see that these tools are installed in your local [Nix store][store] by +running commands like these: + +```shell +which node +which npm +which python +which go +``` + +In all cases, you should see paths of this form: + +```shell +/nix/store/${LONG_HASH}-${PACKAGE_NAME}/bin/${EXECUTABLE_NAME} +``` + +That means that if you run `node`, `npm`, `python`, and so on you'll use +versions of those tools in the Nix store and _not_ versions installed in +directories like `/usr/bin`. + +[bash]: https://gnu.org/software/bash +[direnv]: https://direnv.net +[enable]: https://nixos.wiki/wiki/Flakes#Enable_flakes +[env]: https://nixos.org/explore +[flakes]: https://nixos.wiki/wiki/Flakes +[go]: https://go.dev +[install]: https://nixos.org/download +[nix]: https://nixos.org +[nix.dev]: https://nix.dev +[nixpkgs]: https://github.com/NixOS/nixpkgs +[node.js]: https://nodejs.org +[python]: https://python.org +[store]: https://nixos.org/manual/nix/stable/command-ref/nix-store +[systems]: #system-support +[terraform]: https://terraform.io diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..ee97bb0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,42 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1672751307, + "narHash": "sha256-oC9HKU8y50GDx+/mVvg3MJO/uevyFpBgVKR8/lujMPc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a72e226b04c008ccc499e9e19dcda9dae493a8c9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9c072b9 --- /dev/null +++ b/flake.nix @@ -0,0 +1,79 @@ +{ + # If you wish, you can provide flakes with a description string. This string is + # shown if you run `nix flake show` to get information about the flake. To see + # this description string, run this command: + # `nix flake show github:nix-dot-dev/nix-flake-example` + description = "nix.dev starter template for Nix flakes"; + + # Flake inputs are Nix code dependencies. What you don't see here in + # `flake.nix` is that each of these inputs has an entry in `flake.lock` that + # "pins" the input to a specific revision. This makes `flake.nix` and + # `flake.lock` inseparable. With flakes, the pinning mechanism previously + # provided by tools like Niv is built in. + inputs = { + # Nixpkgs is by far the largest Nix codebase in the world, providing tens of + # thousands of packages and utilities for the Nix language. Here, we + # essentially import Nixpkgs using a flake reference. `github` is the prefix + # for GitHub repos, but other prefixes include `gitlab` for GitLab repos, + # `path` for directories in the local filesystem, and more. + nixpkgs.url = "github:NixOS/nixpkgs"; + + flake-utils.url = "github:numtide/flake-utils"; + + # Although Nixpkgs and flake-utils are extremely common, you can use any + # valid flake as an input. + }; + + # Outputs are what the flake provides (packages, NixOS configurations, dev + # environments, and more). Flakes *must* have outputs or else they are... kind + # of pointless! In fact, you can think of flakes as a way of sharing Nix code + # with others. + outputs = { self, nixpkgs, flake-utils }: + let + # A set of systems to provide outputs for. In Nix flakes, many output + # types, like packages and development environments, need to be for + # specific systems. This flake supports these systems: + supportedSystems = [ + "x86_64-linux" # Linux on AMD/Intel + "aarch64-linux" # Linux on ARM64 + "x86_64-darwin" # macOS on AMD/Intel + "aarch64-darwin" # macOS on Apple Silicon + ]; + in + flake-utils.lib.eachSystem supportedSystems (system: + let + # This creates a system-specific version of Nixpkgs and stores it in a + # variable + pkgs = import nixpkgs { inherit system; }; + in + { + # When you specify a `default` environment, you can enter it by running + # `nix develop` with no arguments. In other words `nix develop` is the + # equivalent of `nix develop .#default`. + devShells.default = pkgs.mkShell { + # The packages provided in the environment. Because the packages are + # included in the `pkgs` attribute set, each is pinned to a specific + # revision of Nixpkgs via `flake.lock`, which makes the environment + # reproducible (as anyone else using this environment uses the same + # Git revision). + packages = with pkgs; [ + python3 # Python 3.10 in this revision of nixpkgs + go # Go 1.19 + nodejs # Node.js 18 + terraform + ]; + + # Nix development environments support environment variables. You + # can set variables like `DEBUG = true` or `ENV = "production"`. But + # beware: we do *not* recommend using environment variables to provide + # secrets! + MESSAGE = "This is only available inside the environment"; + + # Shell hooks are optional scripts that are run every time you enter + # the development environment. + shellHook = '' + echo "Welcome to an example Nix development environment for nix.dev!" + ''; + }; + }); +}