Introduction
SkyOS :: Sk7Str1p3's NixOS configuration
Note
This hosts system and home configurations are public for your own learning and research. They are not meant to be used with any hardware other than mine. Trying to build and deploy them to other systems without appropriate changes can render your machines unbootable and damage data.
Noticable features
- 🛡️ Secure Boot (with custom keys)
- 🧽 Impermanence
- 🔐 Full disk encryption
- 🥸 Secrets management for both evaluation and activation time
- 🎨 Stylix colorscheme
- 🗃️ Documentation
Hosts Preview
<\images here>
Evaluation time secrets
Some secrets cannot be left in cleartext (e.g time zone, user’s real names), but are required at evaluation time, and in some cases using sops-nix’s template is really inconvenient. To handle this, currently i use strange approach: I manually encrypt files with sops, commit them and manually decrypt. git-agecrypt wasn’t suitable for me. In future, i will replace it with my own implementation of transparent git encryption based on sops.
Also, this used only for secrets which may be safely left in world-readable store. For more sensitive secrets I use sops-nix, which decrypts secrets only at runtime.
Documentation
Docs are generated from comments in .nix files.
This results in kind of weird config format, but
makes it easier to track configuration changes
and add/remove docs as required.
How docs are generated
nixdoc utility enables us to generate documentation
from comments in .nix file, like doxygen and rustdoc do.
nixdoc requires this flags:
- category (derived from file’s path)
- description (derived from file’s first line if it’s commented)
most hard part is to generate SUMMARY.md.
generator uses orderKey of type {num}|{mdPath} and derives indentation from path’s depth,
so chapters have proper order.
run nix build .#docBuild to build documentation.
run nix run .#docServe to serve documentation site
Flake
Entry point of NixOS configuration
- Defines external sources and locking their commit, which gives us purity.
- Declares ready-to-use configurations (e.g. development shells, packages, etc.)
Essentially, flake.nix is like Cargo.toml in Rust or package.json in Node.js, but for an entire operating system.
Flake inputs
Declares configuration’s dependencies. Inputs are sorted by their purpose and functionality. See sub chapters to learn which inputs are intended for.
Warning
Because nix doesn’t support splitting flake inputs into several files,
flake.nixis generated via flake-file. Then adding new input, remember runningnix run .#write-flaketo apply changes!In next chapters, you’ll see attributes of type
flake.inputs.{class}.{input}. Then accessing inputs in repl, remove {class}, so instead of calling e.g.flake.inputs.core.nixpkgs, you callflake.inputs.nixpkgs.
Core Inputs
Essential inputs that form the foundation of the NixOS configuration
flake.inputs.core.nixpkgs
The Core of NixOS, providing packages and modules.
Points to nixos-unstable branch for latest features an updates
flake.inputs.core.flake-parts
A modular flake framework that simplifies flake organizing and reduces boilerplate code.
flake.inputs.core.flake-file
Like flake-parts, but for flake inputs
flake.inputs.core.sops-nix
Runtime secrets management.
User inputs
Inputs providing modules or packages for user configurations. Check next chapters to learn more.
flake.inputs.home.home-manager
System for managing a user environment. Allows declarative configuration of user specific (non-global) packages and dotfiles.
flake.inputs.home.stylix
Theming framework for NixOS
User inputs :: Sk7Str1p3
Inputs used by user Sk7Str1p3
flake.inputs.home.Sk7Str1p3.niri
Flake for configuring Niri. Used because home-manager does not support Niri yet.
flake.inputs.home.Sk7Str1p3.spotify
Spotify wrapper (spicetify) with better customization
Development shells
Isolated environments for convenient software development. Provides shells for all languages I use:
- ❄️ Nix
🦀 Rust(not yet)🐍 Python(not yet)
Also provides separate shell for configuration development (not yet).
devShells/{name}/default.nix files contain package list (as attrset for documentation comments) and,
for some shells, shell hooks. It usually looks like this:
# {language name}
/**
Some info on shell
* /
pkgs:
{
/**
description on foo
* /
packages.foo = pkgs.foo;
/**
description on bar
* /
packages.bar = pkgs.bar
/**
comments on shell hook
* /
shellHook = ''
...
'';
}
Also, it has templates, so you can use development shell for projects which don’t have their own.
Nix
Basic shell for nix-only projects. Many nix projects have their own devshell, but they don’t install most necessary tools.
devShells.nix.packages.nixd
nix language server
devShells.nix.packages.nil
another one nix language server
devShells.nix.packages.nixfmt
nix formatter
devShells.nix.packages.statix
nix linter
SkyOS
Development shell with tools needed for configuration editing
devShells.nixos.packages.sops
tool for managing runtime secrets. See sops-nix for more info
devShells.nixos.packages.git-agecrypt
tool for managing eval time secrets.
In near future, it’s going to be replaced by my own project which uses sops instead of bare age
devShells.nixos.packages.nixdoc
tool for generating documentation from comments in .nix files
devShells.nixos.packages.mdbook
tool for generating book from md files made by nixdoc
Hosts
Entry point for machines’ configurations.
Each host forder must has the following structure:
└── {hostname}
├── about.nix
├── configuration.nix
└── hardware.nix
configuration.nix can be used to override default values, and hardware.nix is used to store hardware-related stuff.
About file
File which keep some info about host. It can have these fiels (may be extended in future):
name
used as networking.hostName value
users
sets machine users. Users must have their configuration defined at users/
Edit this configuration file to define what should be installed on
about
Edit this configuration file to define what should be installed on
Do not modify this file! It was generated by ‘nixos-generate-config’
default
about
Edit this configuration file to define what should be installed on
Do not modify this file! It was generated by ‘nixos-generate-config’
default
default
module
plan
service
stalwart
stalwartM
Users
This module contains users’ configuration which is declared on system level.
It includes user’s password, shell, etc.
Parameters is imported from about.json in user’s folder. File can have these keys (may be expanded in future):
realName: User’s real name (optionally)extraGroups: groups (optionally)shell: User’s shellsession: User’s default graphical session (optionally)sshKeys: User’s authorized SSH keys (optionally)
Session must have format of “{type}:{session}” where type is one of co (short for “compositor”) and de (short for “desktop environment”).
This type is actually important, because it depends where nix will search corresponding option for enabling your session.
If co, it will search it in programs.*, and if de, in services.desktopManager.*
User’s face (optionally)
- if any, should be located at users/{user}/face.png
- i prefer store this encrypted, but you can keep it in clear text
User’s password must be stored at users/{user}/password.yaml and encrypted with sops. Format of unencrypted file:
# {your password}
{username}:
userPassword: {hash}
where {hash} is result of echo {your password} | mkpasswd -s
Wallpapers can be png or jpg format, and must be stored at users/{user}/wallpaper.{ext}