# Enabling NixOS with Flakes Compared to the default configuration method currently used in NixOS, Flakes offers better reproducibility. Its clear package structure definition inherently supports dependencies on other Git repositories, facilitating code sharing. Therefore, this book suggests using Flakes to manage system configurations. This section describes how to use Flakes to manage NixOS system configuration, and **you don't need to know anything about Flakes in advance**. ## Enabling Flakes Support for NixOS {#enable-nix-flakes} Currently, Flakes is still an experimental feature and not enabled by default. We need to manually modify the `/etc/nixos/configuration.nix` file to enable the Flakes feature and the accompanying new nix command-line tool: ```nix{12,16} { config, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; # ...... # Enable the Flakes feature and the accompanying new nix command-line tool nix.settings.experimental-features = [ "nix-command" "flakes" ]; environment.systemPackages = with pkgs; [ # Flakes clones its dependencies through the git command, # so git must be installed first git vim wget curl ]; # Set the default editor to vim environment.variables.EDITOR = "vim"; # ...... } ``` After making these changes, run `sudo nixos-rebuild switch` to apply the modifications. Then, you can use the Flakes feature to manage your system configuration. The new nix command-line tool also offers some convenient features. For example, you can now use the `nix repl` command to open a nix interactive environment. If you're interested, you can use it to review and test all the Nix syntax you've learned before. ## Switching System Configuration to `flake.nix` {#switch-to-flake-nix} After enabling the Flakes feature, the `sudo nixos-rebuild switch` command will prioritize reading the `/etc/nixos/flake.nix` file, and if it's not found, it will attempt to use `/etc/nixos/configuration.nix`. You can start by using the official templates to learn how to write a flake. First, check what templates are available: ```bash nix flake show templates ``` Among them, the `templates#full` template demonstrates all possible usage. Take a look at its content: ```bash nix flake init -t templates#full cat flake.nix ``` Referencing this template, create the file `/etc/nixos/flake.nix` and write the configuration content. All subsequent system modifications will be taken over by Nix Flakes. Here's an example of the content: ```nix{16} { description = "A simple NixOS flake"; inputs = { # NixOS official package source, using the nixos-23.11 branch here nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; }; outputs = { self, nixpkgs, ... }@inputs: { # Please replace my-nixos with your hostname nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ # Import the previous configuration.nix we used, # so the old configuration file still takes effect ./configuration.nix ]; }; }; } ``` Here we defined a system named `my-nixos`, with its configuration file located at `/etc/nixos/` as `./configuration.nix`. This means we are still using the old configuration. Now, when you execute `sudo nixos-rebuild switch` to apply the configuration, the system should not change at all because we have simply switched to using Nix Flakes, and the configuration content remains consistent with before. After the switch, we can manage the system through the Flakes feature. Currently, our flake includes these files: - `/etc/nixos/flake.nix`: The entrypoint for the flake, which is recognized and deployed when `sudo nixos-rebuild switch` is executed. - `/etc/nixos/flake.lock`: The automatically generated version lock file, which records the data sources, hash values, and version numbers of all inputs in the entire flake, ensuring system reproducibility. - `/etc/nixos/configuration.nix`: This is our previous configuration file, which is imported as a module in `flake.nix`. Currently, all system configurations are written in this file. - `/etc/nixos/hardware-configuration.nix`: This is the system hardware configuration file, generated by NixOS, which describes the system's hardware information. ## Conclusion Up to this point, we have merely added a very simple configuration file, `/etc/nixos/flake.nix`, which has merely been a thin wrapper around `/etc/nixos/configuration.nix`, offering no new functionality and introducing no disruptive changes. In the content of the book that follows, we will learn about the structure and functionality of `flake.nix` and gradually see the benefits that such a wrapper can bring. > Note: The configuration management method described in this book is NOT "Everything in a > single file". It is recommended to categorize configuration content into different nix > files, then introduce these configuration files in the `modules` list of `flake.nix`, > and manage them with Git. > > The benefits of this approach are better organization of configuration files and > improved maintainability of the configuration. The section > [Modularizing NixOS Configuration](./modularize-the-configuration.md) will explain in > detail how to modularize your NixOS configuration, and > [Other Useful Tips - Managing NixOS Configuration with Git](./other-useful-tips.md) will > introduce several best practices for managing NixOS configuration with Git. [nix flake - Nix Manual]: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#flake-inputs [nixpkgs/flake.nix]: https://github.com/NixOS/nixpkgs/tree/nixos-23.11/flake.nix [nixpkgs/nixos/lib/eval-config.nix]: https://github.com/NixOS/nixpkgs/tree/nixos-23.11/nixos/lib/eval-config.nix [Module System - Nixpkgs]: https://github.com/NixOS/nixpkgs/blob/23.11/doc/module-system/module-system.chapter.md [nixpkgs/nixos-23.11/lib/modules.nix - _module.args]: https://github.com/NixOS/nixpkgs/blob/nixos-23.11/lib/modules.nix#L122-L184 [nixpkgs/nixos-23.11/nixos/doc/manual/development/option-types.section.md#L237-L244]: https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/doc/manual/development/option-types.section.md?plain=1#L237-L244