Introduction
Nixflk is a template which grants a simple way to use, deploy and manage NixOS systems for personal and productive use. It does this by providing a sane repository structure, integrating several popular projects like home-manager, setting clear guidelines, offering useful conveniences, and eliminating boilerplate so you can focus on deploying your systems.
In addition, every package and NixOS profile is built and uploaded to a binary cache, so everything provided is available without building anything. This is especially useful for the packages that are pulled from master, as without the cache, rebuilds are quite frequent.
Community Profiles
There are two branches from which to choose: core and community. The commuity branch builds on core and includes several ready-made profiles for discretionary employment.
⚠ Advisory
Nixflk leverages the flakes feature available via an experimental branch of nix. Until nix 3.0 is released, this project should be considered unstable.
License
Nixflk is licensed under the MIT License.
Quick Start
The only dependency is nix, so make sure you have it installed.
Get the Template
Here is a snippet that will work as long as nix-shell
is in your path:
nix-shell https://github.com/nrdxp/nixflk/archive/core.tar.gz -A shell \
--run "flk get core"
cd flk
nix-shell
git init
git add .
git commit -m init
cachix use nrdxp
You can change
core
tocommunity
in the call toflk get
This will place you in a new folder named flk
in the current directory with
git set up, and a nix-shell that provides all the dependencies, including the
required nix version. In addition, the cachix cache which contains all the
binary outputs from this flake is added for faster deployment.
Next Steps:
ISO
Making and writing an installable iso for hosts/NixOS.nix
is as simple as:
flk iso NixOS
dd bs=4M if=result/iso/*.iso of=/dev/$your_installation_device \
status=progress oflag=sync
This works for any file matching hosts/*.nix
excluding default.nix
.
From NixOS
Generate Configuration
Assuming your happy with your existing partition layout, you can generate a basic NixOS configuration for your system using:
flk up
This will make a new file hosts/up-$(hostname).nix
, which you can edit to
your liking.
While the
up
sub-command is provided as a convenience to quickly set up and install a "fresh" NixOS system on current hardware, committing these files is discouraged.They are placed in the git staging area automatically because they would be invisible to the flake otherwise, but it is best to move what you need from them directly into a host module of your own making, and commit that instead.
Make sure your i18n.defaultLocale
and time.timeZone
are set properly for
your region. Keep in mind that networking.hostName
with be automatically
set to the filename of your hosts file, so hosts/my-host.nix
will have the
hostname my-host
.
Now might be a good time to read the docs on suites and profiles and add or create any that you need.
Installation
Once your ready to deploy hosts/my-host.nix
:
flk my-host switch
Instead of
switch
, you can passbuild
,test
,boot
, etc just as withnixos-rebuild
.
This calls nixos-rebuild
with sudo to build and install your configuration.
It is convenient to have the template living at
/etc/nixos
so you can simplysudo nixos-rebuild switch
from anywhere on the system, but it is not required.
Hosts
Nix flakes contain an output called nixosConfigurations
declaring an
attribute set of valid NixOS systems. To simplify the management and creation
of these hosts, nixflk automatically imports every *.nix
file inside this
directory to the mentioned attribute set, applying the projects defaults to
each. The only hard requirement is that the file contain a valid NixOS module.
As an example, a file hosts/system.nix
will be available via the flake
output nixosConfigurations.system
. You can have as many hosts as you want
and all of them will be automatically imported based on their name.
For each host, the configuration automatically sets the networking.hostName
attribute to the name of the file minus the .nix
extension. This is for
convenience, since nixos-rebuild
automatically searches for a configuration
matching the current systems hostname if one is not specified explicitly.
It is recommended that the host modules only contain configuration information specific to a particular piece of hardware. Anything reusable across machines is best saved for profile modules.
This is a good place to import sets of profiles, called suites, that you intend to use on your machine.
Additionally, this is the perfect place to import anything you might need from the nixos-hardware repository.
Example
hosts/librem.nix
:
{ suites, hardware, ... }:
{
imports = suites.laptop ++ [ hardware.purism-librem-13v3 ];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };
}
Profiles
Profiles are simply NixOS modules which contain generic expressions suitable for any host. A good example is the configuration for a text editor, or window manager. If you need some concrete examples, just checkout the community branch.
Constraints
For the sake of consistency, there are a few minor constraints. First of all, a
profile should always be defined in a default.nix
, and it should always be a
a function taking a single attribute set as an argument, and returning a NixOS
module which does not define any new module options. If you need to make new
module option declarations, just use modules.
These restrictions help simplify the import logic used to pass profles to suites.
Example
✔profiles/develop/default.nix
:
# good profile definition
{ ... }:
{
programs.zsh.enable = true;
}
❌profiles/develop.nix
:
# bad profile definition
{
options = {};
}
Subprofiles
Profiles can also define subprofiles. They follow the same constraints outlined above. A good top level profile should be a high level concern, such a your personal development environment, and the subprofiles should be more concrete program configurations such as your text editor, and shell configs. This way, you can either pull in the whole development profile, or pick and choose individual programs.
Conclusion
Profiles are the most important concept in nixflk. They allow us to keep our nix expressions self contained and modular. This way we can maximize reuse while minimizing boilerplate. Always strive to keep your profiles as generic and modular as possible. Anything machine specific belongs in your host files.
Suites
Suites provide a mechanism for users to easily combine and name collecitons of profiles. For good examples, check out the suites defined in the community branch.
In the future, we will use suites as a mechanism for deploying various machine types which don't depend on hardware, such as vm's and containers.
Definition
rec {
workstation = [ profiles.develop profiles.graphical users.nixos ];
mobileWS = workstation ++ [ profiles.laptop ];
}
Usage
hosts/my-laptop.nix
:
{ suites, ... }:
{
imports = suites.mobileWS;
}
Users
Users are a special case of profiles that define system users and home-manager configurations. For your convenience, home manager is wired in by default so all you have to worry about is declaring your users. For a fully fleshed out example, check out the developers personal branch.
Basic Usage
users/myuser/default.nix
:
{ ... }:
{
users.users.myuser = {
isNormalUser = true;
};
home-manager.users.myuser = {
programs.mpv.enable = true;
};
}
External Usage
You can easily use the defined home-manager configurations outside of NixOS
using the hmActivations
meta-package defined in the flakes legacyPackages
output. The flk helper script makes this even easier. Just
make sure you have home-manager
installed.
This is great for keeping your environment consistent across Unix systems, including OSX.
From within the projects devshell:
# builds the nixos user defined in the NixOS host
flk home NixOS nixos
# activate
flk home NixOS nixos switch
Manually from outside the project:
# build
nix build "github:nrdxp/nixflk#hmActivationPackages.NixOS.nixos"
# activate
./result/activate && unlink result
Cachix
The cachix directory simple captures the output of sudo cachix use
for the
developers personal cache, as well as the nix-community cache. You can easily
add your own cache, assuming the template lives in /etc/nixos, by simply
running sudo cachix use yourcache
.
These caches are only added to the system after a nixos-rebuild switch
, so it
is recommended to call cachix use nrdxp
before the initial deployment, as it
will save a lot of build time.
In the future, users will be able to skip this step once the ability to define the nix.conf within the flake is fully fleshed out upstream.