"With NixOS, your entire system is just one file: /etc/nixos/configuration.nix!"
... I took that literally.
- Literate configuration defining my entire infrastructure, including Emacs
- Dendritic configuration based on flakes (using flake-file) for personal hosts as well as servers on:
- NixOS
- home-manager only (no full NixOS) with support from nixGL
- nix-darwin
- nix-on-droid
- Streamlined configuration and deployment pipeline:
- Framework for packages, overlays, dendritic modules (features), and library functions
- Dynamically generated config:
- host configurations
- dns records
- network setup (+ WireGuard mesh on systemd-networkd)
- Remote Builders for
[x86_64,aarch64]-linuxrunning on Buildbot, feeding a private nix binary cache and updating the flake on a weekly basis - Bootstrapping:
- Limited local installer (no secrets handling) with a (kinda un-)supported demo build
- Fully autonomous remote deployment using nixos-anywhere and disko (with secrets handling)
- Improved nix tooling
- Support for advanced features:
- Secrets handling using sops-nix (pls no pwn β€οΈ)
- Management of personally identifiable information using nix-plugins
- Full Yubikey support (with SSH support for SK keys, certs and PGP keys)
- LUKS-encryption with support for remote disk unlock over SSH
- Secure boot using Lanzaboote
- BTRFS-based Impermanence
- Configuration shared between configurations (configuration for one nixosConfiguration can be defined in another nixosConfiguration)
- Global attributes shared between all configurations to reduce attribute re-declaration
- Config library for defining config-based functions for generating service information
- Reduced friction between full NixOS- and home-manager-only deployments
- efficient secrets handling depending on system context
- automatic config sharing between contexts
- dendritic structure for keeping features in a centralized manner
Click here for a summary of my infrastructure
| Topic | Program |
|---|---|
| β©οΈ Bar | Waybar or Noctalia Shell |
| βοΈ Editor | Emacs |
| π Browser | Firefox |
| π¨ Theme | City-Lights (managed by stylix) |
| π Shell | zsh |
| π₯οΈ Terminal | Kitty |
| π Launcher | Fuzzel or Noctalia Shell |
| π¨ Alerts | Mako or Noctalia Shell |
| πͺ DM | greetd |
| πͺ WM | SwayFX or Niri |
| Topic | Program |
|---|---|
| βοΈ S3 | Garage |
| β Anki Sync | Anki Sync Server |
| βοΈ Minecraft | Minecraft |
| βοΈ Paste Tool | Microbin |
| βοΈ Mail | simple-nixos-mailserver |
| π Collections | Koillection |
| π³ Git | Forgejo |
| π΄ RSS | FreshRss |
| π½οΈ Recipes | Mealie |
| ποΈ Photos | Immich |
| π΅ Music | Navidrome + Spotifyd + MPD |
| π Nix Build farm | Buildbot |
| π½ Threat Detection | CrowdSec |
| π DNS Records | NSD |
| ποΈ Monitoring | Grafana + Mimir + Loki + Tempo + Alloy + Pyroscope + Gotify |
| πΈ Finance | Firefly-III |
| πΎ Backups | Restic |
| π Filesharing | Nextcloud + CopyParty + Croc |
| π Documents | Paperless |
| π CalDav/CardDav | Radicale |
| π Books | Kavita |
| πΈ Image Sharing | Slink |
| πΊ Video Streaming | Invidious + Invidious Companion |
| πΌ Videos | Jellyfin |
| π File Sync | Syncthing |
| π Search Engine | SearXNG |
| π Cert-based SSH | OPKSSH |
| π Link Shortener | Shlink |
| π¨ Home Asset Management | Homebox |
| πΈοΈ Nix Binary Cache | Attic |
| ποΈ Shell History | Atuin |
| π¨οΈ Messaging | Matrix |
| π VPN Access | Firezone |
| ποΈ DHCP | Kea |
| π‘οΈ Local DNS Resolver | AdGuard Home |
| π¦ Firefox Sync | Firefox-Syncserver |
| πͺ Second Hand Site Info | Shopservatory + Socks Proxy |
| πͺͺ SSO | Kanidm + oauth2-proxy |
| Name | Hardware | Use |
|---|---|---|
| π» bakery | Lenovo Ideapad 720S-13IKB | Personal laptop |
| π» machpizza | MacBook Pro 2016 | MacOS reference and build sandbox |
| π» pyramid | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop |
| π treehouse | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference |
| π₯οΈ hintbooth | HUNSN RM02, 8GB RAM | Router, DNS Resolver, home NGINX endpoint |
| π₯οΈ summers | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, data storage |
| π₯οΈ winters | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) |
| βοΈ belchsfactory | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binary cache |
| βοΈ eagleland | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver |
| βοΈ liliputsteps | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion |
| βοΈ moonside | Cloud Server: 4 vCPUs, 24GB RAM | Game servers, syncthing + other lightweight services |
| βοΈ stoicclub | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative DNS server |
| βοΈ twothreetunnel | Cloud Server: 2 vCPUs, 8GB RAM | Service proxy |
| πͺ chaostheater | Asus Z97-A, i7-4790k, GTX970, 32GB RAM | Home Game Streaming Server (Windows/AtlasOS, not nix-managed) |
| π± magicant | Samsung Galaxy Z Flip 6 | Phone |
| πΏ brickroad | - | Kexec tarball for bootstrapping low-memory machines |
| πΏ drugstore | - | NixOS-installer ISO for bootstrapping new hosts |
| πΏ policestation | - | NixOS live ISO for generating cryptographic keys |
| β hotel | - | Demo config for checking out this configuration |
| β toto | - | Helper configuration for deployment testing |
| β vacanthouse | - | Staging environment |
The full documentation can be found here:
SwarselSystems literate configuration
I went to great lengths in order to document the full design process of my infrastructure properly; the above document strives to serve as an introductory lecture to nix / NixOS while at the same time explaining the config in general.
If you came here for my raw Emacs configuration, the relevant files live here in elisp form (these files are generated from the nix emacs-init module):
Click here for instructions on how to install the demo system
If you just want to see if this configuration is for you, run this command on any system that has nix installed:
nix run --experimental-features 'nix-command flakes' github:Swarsel/.dotfiles#swarsel-rebuild -- -u <YOUR_USERNAME>This will activate the hotel configuration on your system, which is a de-facto mirror of my main configuration with secret-based settings removed.
Since you do not have my SSH keys, the installer automatically replaces the private flake inputs (my work repository and the encrypted repository secrets) with public demo stand-ins via --override-input - nothing in the repository is modified for this. This should only be used to evaluate the system - if you want to use it long-term, you will need to create a fork and make some changes.
Click here for deployment instructions
The deployment process for this configuration is mostly automated, there are only a few steps that are needed to be done manually. You can choose between a remote deployment strategy that is also able to deploy new age keys for sops for you and a local installer that will only install the system without any secret handling.
- Fork this repo, and write your own host config at
hosts/nixos/<YOUR_ARCHITECTURE>/<YOUR_CONFIG_NAME>/default.nix(you can use one of the other configurations as a template. Also see https://github.com/Swarsel/.dotfiles/tree/main/modules for a list of all additional options). At the very least, you should replace thesecrets/directory with your own secrets and replace the SSH public keys with your own ones (otherwise I will come visit you!πβ€οΈ). I personally recommend to use the literate configuration andorg-babel-tangle-filein Emacs, but you can also simply edit the separate.nixfiles. - Have a system with
nixavailable booted (this does not need to be installed, i.e. you can use a NixOS installer image; a custom minimal installer ISO can be built by runningjust isoin the root of this repo) - Make sure that your Yubikey is plugged in or that you have your SSH key available (and configured)
- Run
swarsel-bootstrap -n <CONFIGURATION_NAME> -d <TARGET_IP>on your existing system. - Alternatively (if you run this on a system that is not yet running this configuration), you can also runnix run --experimental-features 'nix-command flakes' github:Swarsel/.dotfiles -- -n <CONFIGURATION_NAME> -d <TARGET_IP>(this runs the same program as the command above). - Follow the installers instructions: - you will have to choose a disk encryption password (if you want that feature) - you will have to confirm once that the target system has rebooted - you will have to enter the root password once during the final system install
- That should be it! The installer will take care of setting up disks, secrets, and the rest of the hardware configuration! You will still have to sign in manually to some web services etc.
- Boot the latest install ISO from this repository on an UEFI system.
- Run
swarsel-install -n <CONFIGURATION_NAME> - Reboot
Alternatively, to install this from any NixOS live ISO, run nix run --experimental-features 'nix-command flakes' github:Swarsel/.dotfiles#swarsel-install -- -n <CONFIGURATION_NAME> at step 2.
I would like to express my gratitude (not solely) to:
The people who help maintain NixOS, nix-community, and other nix-related projects.
The people who have inspired me with their configurations
- theSuess with their home-manager
- hlissner with their dotfiles
- AntonHakansson with their nixos-config
- EmergentMind with their nix-config
- oddlama with their nix-config
If you feel that I forgot to pay you tribute for code that I used in this repository, please shoot me a message and I will fix it :)
Q: How do I get started with nix?
A: Click here for a small list of tips that should be helpful if you are new to the nix ecosystem
-
Temporarily install any package using
nix shell nixpkgs#<PACKAGE_NAME>- this can be e.g. useful if you accidentally removed home-manager from your packages on a non-NixOS machine.- if you need multiple packages, you can do
nix shell nixpkgs#{<pkg1>,<pkg2>,<pkg3>}. - you can set
nix.registryto add more flakes to your registry. I use this to add anshorthand tonixpkgs, which allows me to donix shell n#{<pkg1>,<pkg2>,<pkg3>}.
- if you need multiple packages, you can do
-
Alternatively, use comma
- More info on
nix [...]commands: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix - some examples:
nix flake update <input-name>lets you update a specific input only.nix repl <your flake path>gives quick insight into your written configuration.nix eval <your flake path>#<config attribute>quickly returns an attribute in your written configurationnix fmtformats your flake using the formatter specified underformatterin yourflake.nix
- More info on
-
When you are trying to setup a new configuration part, GitHub code search can really help you to find a working configuration. Just filter for
.nixfiles and the options you are trying to set up. -
getting packages at a different version than your target (or not packaged at all) can be done in most cases easily with fetchFromGithub (https://ryantm.github.io/nixpkgs/builders/fetchers/)
-
you can easily install old revisions of packages using https://lazamar.co.uk/nix-versions/. You can conveniently spawn a shell with a chosen package available using
vershell <NIXPKGS_REVISION> <PACKAGE>. Just make sure to pick a revision that has flakes enabled, otherwise you will need the legacy way of spawning the shell (see the link for more info) -
when developing modules in a dev branch of another flake, you can use
--override-inputto temporarily use the local directory as the flake source. -
including
nixosConfig ? configin your module arguments is a smart way of enabling a module to pull in config from NixOS or home-manager config, no matter if it is a NixOS system or not. -
you can have a quick CLI evaluation for nix commands with e.g.
nixpgks.libavailable usingnix-instantiate --strict --eval --expr "let lib = import <nixpkgs/lib>; in <expression>". -
if you are looking for a specific library,
nix-locatemakes it easy to look for them. -
to look at the dependencies pulled in by a tool, use
nix-tree- to find out which derivation uses another derivation, use
nix store --query --referrers <derivation>
- to find out which derivation uses another derivation, use
-
to get a neat overview of your config changes in recent generations, use
nix profile diff-closures --profile /nix/var/nix/profiles/system- to get instead the changes since the last boot, use
nix profile diff-closures /run/*-system - if you just need the generation numbers, use
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system - to then switch to another generation, you can use
sudo nix-env --switch-generation <generation number> -p /nix/var/nix/profiles/systemfollowed bysudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
- to get instead the changes since the last boot, use
-
These links are your best friends:
- The nix documentation: https://nix.dev/
- The nixpkgs reference manual: https://nixos.org/manual/nixpkgs/unstable/#buildpythonapplication-function
- the nixpkgs repository - especially useful to look at the various READMEs that are in various places in the repository (find using GitHub code search) as well as the issues and PRs pages
- and the nixpkgs Pull Request Tracker
- The NixOS manual: https://nixos.org/manual/nixos/stable/
- The NixOS package search: https://search.nixos.org/packages
- and the nix package version search: https://lazamar.co.uk/nix-versions/
- The NixOS option search https://search.nixos.org/options
- mipmip's home-manager option search: https://mipmip.github.io/home-manager-option-search/
- Alan Pearce's
nix-darwinsearch: https://searchix.alanpearce.eu/options/darwin/search (which supports all of the other versions as well :o) - For the above, you can use the CLI tool manix
- Nix function search: https://noogle.dev/
- Search for nix-community options: https://search.nΓΌschtos.de/
-
But that is not all:
- Some nix resources
- A tour of Nix: https://nixcloud.io/tour/
- The Nix One Pager: https://github.com/tazjin/nix-1p
- another one page introduction: https://learnxinyminutes.com/nix/
- a very short introduction to Nix features: https://zaynetro.com/explainix
- introductory nix article: https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55
- and another one: https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix
- How to learn nix: https://ianthehenry.com/posts/how-to-learn-nix/
- the Nix Cookbook: https://github.com/functionalops/nix-cookbook?tab=readme-ov-file
- and the Nix Pills: https://nixos.org/guides/nix-pills/
- Some resources on flakes
- Why to use flakes and introduction to flakes: https://www.tweag.io/blog/2020-05-25-flakes/
- The NixOS & Flakes Book
- and Wombat's book
- as well as Ekala's book
- or the Zero to Nix series
- last but not least, NixOS in Production
- Practical nix flakes article: https://serokell.io/blog/practical-nix-flakes
- A bit on Overlays:
- Overview on overlays: Mastering Nixpkgs overlays article
- Some examples on best practices: Do's and Don'ts of overlays
- Blog article about overrides: https://bobvanderlinden.me/customizing-packages-in-nix/#using-modified-packages
- Also useful is the official NixOS Wiki
- there is also the unofficial NixOS Wiki that tends to be a bit outdated, use with care
- Some nix resources
-
Some resources for specific nix tools:
- Flake output reference: https://nixos-and-flakes.thiscute.world/other-usage-of-flakes/outputs
- You can find public repositories with modules at https://nur.nix-community.org/ (you should check what you are installing however):
- I like to use this for rycee's Firefox extensions: https://nur.nix-community.org/repos/rycee/
- List of nerd-fonts: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/data/fonts/nerd-fonts/manifests/fonts.json
- Stylix configuration options: https://danth.github.io/stylix/
- nix-on-droid options: https://nix-community.github.io/nix-on-droid/nix-on-droid-options.html#sec-options
-
Very useful tools that are mostly not directly used in configuration but instead called on need:
- Convert non-NixOS machines to NixOS using nixos-infect
- Create various installation media with nixos-generators
- Remotely deploy NixOS using nixos-anywhere
-
And a few links that are not directly nix-related, but may still serve you well:
- List of pre-commit-hooks: https://devenv.sh/reference/options/#pre-commithooks
- Waybar configuration: https://github.com/Alexays/Waybar/wiki
Q: Why Is this just called .dotfiles?



