Foreword
This repository contains my personal configuration for my systems, so its really important that you know it's personal and not everything will fit your needs. Therefore most things will not work out of the box without some changes, so be warned!!!!
warning
Also to note that this configuration will not work if you do not change any of the secrets since they are encrypted.
What does this repo provided
- Modular configuration, so you can add or remove parts of the configuration
 - Sensible defaults, so you can get started quickly
 - Docs kind of
 - Catppuccin everywhere.
 
🖥️ Systems
| Name | Main User | Type | OS | Extra Details | 
|---|---|---|---|---|
| amaterasu | isabel | Desktop | NixOS | A powerful desktop dual booting windows 11 | 
| athena | isabel | Hybrid | NixOS | My oldest laptop, altogh this flake still supports it, its barely in use | 
| aphrodite | isabel | Sever | NixOS | The host of most tgirl.cloud services | 
| lilith | n/a | Iso | NixOS | An iso image of my NixOS configuration, used to install NixOS on new systems | 
| minerva | isabel | Server | NixOS | This is the orginal server, hosting most of my personal services | 
| skadi | isabel | Server | NixOS | Oracle free server, mostly used for the pds and aarch64 builds | 
| tatsumaki | isabel | Laptop | macOS | A macbook air, given to me by uni, almost exclusively used at uni | 
| valkyrie | isabel | WSL2 | NixOS | This is my WSL2 instance, installed on amaterasu | 
🧩 Modules
- flake - modules which are used to build the flake outputs
 - generic - modules which are intended to work with any module system (e.g. home-manager, nix-darwin, etc.)
 - nixos - modules which work on NixOS
 - base - modules which work on either NixOS or macOS
 - darwin - modules which work on macOS
 - home - modules which are used to configure home-manager
 - iso - modules which are used to build isos
 - wsl - modules which work on WSL2
 
When writing a module, you should follow these guidelines:
- Use a tree like structure for the head lambda args if and only if it is needed.
 
{
  lib,
  pkgs,
  inputs,
  ...
}:
{
  /* ommitted config */
}
importsshould do its best to avoid going backwards in the flake's file structure.
Despite my best efforts to advice you as to not do this, many of you still choose to do so. So here is a guide on how to make it your own. So maybe consider donating to me before continuing.
donation platforms in order of preference:
Making it your own
- There are a number of files you will want to edit but the best place to
start would be renaming the 
isabeluser to your own user and deleting the robin user. - Following this you will want to edit 
/modules/base/users/options.nixand change any mentions ofisabelto your username. - Then you can create a file in that will contain your ssh key
/modules/base/users/<user>.nix. - Finally you will want to edit 
/modules/nixos/users/<user>.nixto add your encrypted password, generated withmkpasswd. - I host a number off different types of hosts, so there is likely one that will nicely match yours. To check what is a good match for you, look at the hosts table.
 - At this point you should have found the ideal host, so your going to rename the directory that it is into your preferred hostname.
 - Then you should make any needed adjustments. This should include renaming the home-manager users and configuring the options.
 - You will then want to edit 
modules/nixos/environment/locale.nixsuch that you have the correct timezone and locale. - You likely don't want to use my lix fork, so you should regex replace
izlixwith your preferred nix implementation. If your preferred nix implementation does not support nestedinput.followsyou will have to edit theflake.nix. - There is a lot of maintenance burden in this repository, so you should see what you can remove safely. But there's no safe way to guide you on this so best of luck.
 
NixOS
You might want to use the lilith iso configuration, provided in this repository
- To build it you can run 
nix build .#images.lilith. - Or you can download it from the release page.
 
If you opted to use the lilith iso image, you can use the iznix-install
script to install it on your system. Otherwise, you can follow the steps below.
- Install NixOS, you might need to follow the manual
 - Clone this repository to 
~/.config/flake - Run 
sudo nixos-rebuild switch --flake ~/.config/flake#<host> 
Dual boot
If you would like to set up duel boot with Windows, you should consider enabling secure boot. To do so you should follow the lanzaboote guide.
- Locate the Windows EFI partition
 
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT
- Mount the Windows EFI partition
 
sudo mkdir /mnt/winboot
sudo mount /dev/nvme0n1p1 /mnt/winboot
- Copy the Windows EFI files to the NixOS EFI partition
 
sudo rsync -av /mnt/winboot/EFI/Microsoft/ /boot/EFI/Microsoft/
- Finally, clean up
 
sudo umount /mnt/winboot
sudo rmdir /mnt/winboot
macOS
- Install Lix the package manager
 
curl -sSf -L https://install.lix.systems/lix | sh -s -- install
- Then enter a nix development shell in order to use git and other required tools
 
nix develop
- Now we need to switch to the configuration, remember to replace 
<host>with the system you are configuring 
just provision <host>
In the past this repo used to hold templates. Now the templates are located at tgirlcloud/nix-templates. Overall the commands remain the same except for the repo to use.
nix flake init -t github:tgirlcloud/nix-templates#<template>to initialize a new project with the templatenix flake new -t github:tgirlcloud/nix-templates#<template> <out dir>to create a new project in the specified directory
For the full list of templates check the nix-templates
repo directory or run nix flake show github:tgirlcloud/nix-templates.
The systems are configured in /systems/<hostname>.
To set up a system configuration it must be declared in /systems/default.nix.
- 
arch:
- default: "x86_64"
 - options: "x86_64", "aarch64"
 
 - 
class:
- default: "nixos"
 - options: "nixos", "darwin", "iso", "wsl"
 
 - 
system:
- default: 
constructSystem config.easyHosts.hosts.<hostname>.target config.easy-hosts.hosts.<hostname>.arch - note: This is a function that constructs the system configuration, it will make 
x86_64-linuxby from thetargetandarchattributes oraarch64-darwin 
 - default: 
 - 
deployable:
- default: false
 
 - 
modules:
- default: "[ ]"
 - options:
 
 - 
specialArgs:
- default: "{ }"
 
 
tip
Please consult easy-hosts for more information on how to set up a system configuration.
The user side is configured in /home/<user>.
To set up a user configuration it must be declared in
/modules/base/users/options.nix and /modules/base/users/<user>.nix can be
used for anything that is not preconfigured by
/modules/base/users/mkusers.nix. You will also want to add a hashed password
generated from mkpasswd to /modules/nixos/users/<user>.nix.
You should also add your user into the users.nix file for your system. Whilst
following the template:
{
  garden.system = {
    mainUser = "robin";
    users = [ "robin" ];
  };
  # you can add a home-manager configuration here for the user if it needs
  # anything special
  home-manager.users.robin.garden = {};
}
Adding packages to your user or system profile is different then most other
flakes. In this flake we use the garden.packages attribute to add our
packages, which take an attrset. This prevents us from having duplicate listings
of packages, and lets us think a little less when writing home-manger or
nixos/darwin module code.
An example of this may look like the following:
{ pkgs, ... }:
{
  garden.packages = {
    inherit (pkgs) git;
    wrapped-nvim = pkgs.symlinkJoin {
      name = "wrapped-nvim";
      paths = [ pkgs.nvim pkgs.astro-language-server ];
    };
  };
}
Sops Nix
We also use sops-nix to manage secrets
that are not files. For the most part this will be ssh keys, api keys and other
plaintext secrets.
To start you should identify whether you are creating a system level secret or a user level secret.
User secrets
If you are adding a user level secret, you should add your user to the list of
users in the .sops.yaml file. Then you should get your public key by running:
ssh-to-age < ~/.ssh/id_ed25519.pub
Then you can create your users secrets file. To do so you should run the command:
sops secrets/your_username.yaml
Where your_username is your actual username.
System secrets
If you are adding a system level secrets, you should get the hostname and its accompanied public key. To get the public key, you can run:
ssh-keyscan <host> | ssh-to-age
Where <host> is the ip address or hostname of the system you want to add.
Alternatively, if you are on the machine you can run:
ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub
Then you can create the system secrets file. To do so you should run the command:
sops secrets/services/<service>.yaml
You should replace <service> with the name of the service you are adding the secrets for.
Rotating secrets
To rotate a secret file all you have to run is:
sops rotate -i secrets/<file>.yaml
Where <file> is the name of the file you want to rotate.
To rotate all the secrets, you can run:
find secrets/ -name "*.yaml" | xargs -I {} sops rotate -i {}
Adding new owners to secrets
To add a new owner to a secret file, you must first add the new recipent to the .sops.yaml file. Then you can run the command:
sops updatekeys secrets/<file>.yaml
Where <file> is the name of the file you want to update.
Futhermore, to batch update all secrets, you can run:
find secrets/ -name "*.yaml" | xargs -I {} sops updatekeys -y {}
To uninstall nix darwin run the following command:
nix run github:LnL7/nix-darwin#darwin-uninstaller
Issues
A awesome list of issues I've had that I want to document for future reference.
chmod nix darwin error
error: chmod '"/nix/store/66kaihiqnn02vpxs6qydcbw9pq7nrkld-iterm2-3.5.4/Applications/iTerm2.app"': Operation not permitted
You can get this error when trying to run nix store gc. The fix for this is
to give nix FDA. To do so System Settings > Privacy & Security > Full Disk Access and add nix to the list of apps that have full disk access.
See also https://github.com/NixOS/nix/issues/6765
I use lix.
note
Furthermore this is with a custom patch set through izlix. Though I don't recommend using izlix. If you want the patches you may copy them for personal use.
This flake makes a point of using lix where possible.
To do so we add the following snippet taken from modules/base/nix/overlays/default.nix. What this does is use lix where possible rather than nix.
_: prev: {
  # in order to reduce our closure size, we can override these packages to
  # use the nix package that we have installed, this will trigget a rebuild
  # of the packages that depend on them so hopefully its worth it for that
  # system space
  nixVersions = prev.nixVersions // {
    stable = config.nix.package;
  };
}
I use fht-compositor as my window manager on linux. On macos I don't use a window manager, but when I do it has to be areospace. This page documents how they are used.
| SKHD Shortcut | fht-compositor Shortcut | What it does | 
|---|---|---|
| CMD+RETURN | SUPER+RETURN | open terminal | 
| SUPER+B | open browser | |
| CMD+Q | SUPER+Q | quit | 
| CMD+D | SUPER+D | launcher | 
| SUPER+F | full screen | |
| CMD+CTRL+[number] | SUPER+[number] | open workspace [number] | 
| CMD+SHIFT+[number] | SUPER+SHIFT+[number] | move to workspace [number] | 
lib.hardware:
lib.hardware.isx86Linux
check if the host platform is linux and x86
Arguments
- [pkgs] the package set
 
Type
isx86Linux :: AttrSet -> Bool
Example
isx86Linux pkgs
=> true
lib.hardware.primaryMonitor
assume the first monitor in the list of monitors is primary get its name from the list of monitors
Arguments
- [config] the configuration that nixosConfigurations provides
 
Type
primaryMonitor :: AttrSet -> String
Example
primaryMonitor osConfig
=> "DP-1"
lib.hardware.ldTernary
ldTernary, short for linux darwin ternary
Inputs
- [pkgs] is the package set
 - [l] the value to return if the host platform is linux
 - [d] the value to return if the host platform is darwin
 
Type
ldTernary :: AttrSet -> Any -> Any -> Any
Example
ldTernary pkgs "linux" "darwin"
=> "linux"
lib.helpers:
lib.helpers.mkPub
Create a public key for a given host
Arguments
- [host] the host to create the public key for
 - [key] this is a attrset with the key type and key
 
Type
mkPub :: (String -> AttrSet -> AttrSet) -> String -> AttrSet -> AttrSet
Example
mkPub "github.com" {
  type = "rsa";
  key = "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
}
=> {
  "github.com-rsa" = {
    hostNames = [ "github.com" ];
    publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
  };
}
lib.helpers.mkPubs
Create public keys for a given host
Arguments
- [host] the host to create the public keys for
 - [keys] the list of keys to create
 
Type
mkPubs :: (String -> List) -> String -> List -> AttrSet
Example
mkPubs "github.com" [
  {
    type = "rsa";
    key = "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
  }
  {
    type = "ed25519";
    key = "AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
  }
]
=> {
  "github.com-ed25519" = {
    hostNames = [ "github.com" ];
    publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
  };
  "github.com-rsa" = {
    hostNames = [ "github.com" ];
    publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
  };
}
lib.helpers.giturl
Create git url aliases for a given domain
Arguments
- [domain] the domain to create the alias for
 - [alias] the alias to use
 - [user] the user to use, this defaults to "git"
 - [port] the port to use, this is optional
 
Type
giturl :: (String -> String -> String -> Int) -> AttrSet
Example
giturl { domain = "github.com"; alias = "gh"; }
=> {
  "https://github.com/".insteadOf = "gh:";
  "ssh://git@github.com/".pushInsteadOf = "gh:";
}
lib.helpers.filterNixFiles
filter files for the .nix suffix
Arguments
- [k] they key, which is the file name
 - [v] the value, which is the type of the file
 
Type
filterNixFiles :: String -> String -> Bool
Example
filterNixFiles "default.nix" "regular"
=> true
lib.helpers.importNixFiles
Import all file that filterNixFiles allows for
Arguments
- [path] the path to the directory
 
Type
importNixFiles :: String -> List
Example
importNixFiles ./.
=> [ {...} ]
lib.helpers.importNixFilesAndDirs
import all nix files and directories
Arguments
- [dir] the directory to search for nix files
 
Type
importNixFilesAndDirs :: String -> List
Example
importNixFilesAndDirs ./.
=> [ "flake.nix" ]
lib.helpers.boolToNum
return an int based on boolean value
Arguments
- [bool] the boolean value
 
Type
boolToNum :: Bool -> Int
Example
boolToNum true
=> 1
lib.helpers.containsStrings
a function that checks if a list contains a list of given strings
Arguments
- [list] the list to search in
 - [targetStrings] the list of strings to search for
 
Type
containsStrings :: List -> List -> Bool
Example
containsStrings ["a" "b" "c"] ["a" "b"]
=> true
lib.helpers.indexOf
a function that returns the index of an element in a list
Arguments
- [list] the list to search in
 - [elem] the element to search for
 
Type
indexOf :: List -> Any -> Int
Example
indexOf [1 2 3] 2
=> 1
lib.helpers.intListToStringList
convert a list of integers to a list of string
Arguments
- [list] the list of integers
 
Type
intListToStringList :: List -> List
Example
intListToStringList [1 2 3]
=> ["1" "2" "3"]
lib.secrets:
lib.secrets.mkSystemSecret
Create secrets for use with agenix.
Arguments
- [file] the age file to use for the secret
 - [owner] the owner of the secret, this defaults to "root"
 - [group] the group of the secret, this defaults to "root"
 - [mode] the permissions of the secret, this defaults to "400"
 
Type
mkSystemSecret :: (String -> String -> String -> String) -> AttrSet
Example
mkSystemSecret { file = "./my-secret.age"; }
=> {
  file = "./my-secret.age";
  owner = "root";
  group = "root";
  mode = "400";
}
lib.services:
lib.services.mkServiceOption
A quick way to use my services abstraction
Arguments
- [name]: The name of the service
 
Type
mkServiceOption :: String -> (Int -> String -> String -> AttrSet) -> AttrSet
lib.validators:
lib.validators.ifTheyExist
a function that will append a list of groups if they exist in config.users.groups
Arguments
- [config] the configuration that nixosConfigurations provides
 - [groups] a list of groups to check for
 
Type
ifTheyExist :: AttrSet -> List -> List
Example
ifTheyExist config ["wheel" "users"]
=> ["wheel"]
lib.validators.anyHome
check if a predicate for any user config is true
Arguments
- [conf] the configuration that nixosConfigurations provides
 - [cond] predicate function to check against config variable
 
Type
anyHome :: AttrSet -> (Any -> Bool) -> Bool
Example
anyHome config (cfg: cfg.programs.hyprland.enable)
=> true
  
  garden option search
Try searching for something!
Resources
A collection of resources from people who just make good stuff.
- Xe's blog
 - The aux forum
 - Viper's Blog
 - Nix Pills, this one might be a bit much if you don't care too much about the internals
 - Solène's Blog
 - Jade Lovelace's blog
 - Astrid's blog
 - nixpkgs news
 - nix.dev
 - cafkafk's blog
 - zimbatm's blog
 - my own blog
 - official wiki
 - zero to nix
 
Projects / Configurations
These are some configuration or projects that I have taken inspiration from or find to be of a high quality that people should also consider reading.
People
Thanks to all these people otherwise this config and I would be lost.
- comfysage, for making my day that bit brighter and occasionally putting me on your back
 - getchoo, for making catppucin/nix and helping a ton
 - nullishamy, for tricking me into using NixOS
 - nekowinston, for fixing half my problems
 - jakehamilton, for teaching me too much about modules
 - nyxkrage, for being there to answer my questions
 - NotAShelf, lots of valuable information
 - Minion3665, for making me write better docs
 - Thorn, picrewnix????
 
