This is my personal configuration that I use for Nixos, WSL on Windows, MacOS, and my PixelFold.
The general approach here is to isolate my user configuration into home
folder and system configurations in the system
folder. There are some deviations from this. For instance, all of the secrets are user based, but they are decrypted from the system configuration because we get more control from agenix (owner and group permissions) and I have found this approach does not require any custom activations or a restart of wsl.
I have used this repo for shell environments over the last couple of years or so but I've gotten carried away with hyprland and desktop tiling over the last few months. I've tried to put everything desktop related in the nyx.modules.desktop
configuration space under home-manager. Most of the options are specified in in the /systems/<platform>/hosts/<hostname>/home.nix
file. You can delete the entire desktop section if you don't want any your desktop to be modified.
The exceptions to this are:
-
Nixos
- Hyprland =>
system/nixos/modules/hyprland
- Hyprlogin =>
system/nixos/modules/hyprlogin
- Yubilogin =>
system/nixos/modules/yubilogin
- Hyprland =>
-
Darwin
- Yarbai =>
system/darwin/modules/system/yabai
- Dock =>
system/darwin/modules/dock
- Brews =>
system/darwin/brews.nix
- Casks =>
system/darwin/casks.nix
- Yarbai =>
.
├─ home # Home-manager and user configrations
├─ lib # Shared functions that generate attribute sets
├─ nix # Default Nix Configurations and Overlays
├─ setup # Intitial Install/Configure Scripts
├─ system # System / Host / Global configurations
These public repositories heavily influenced my configuration. The project architecture and most of the dot files in this project started directly from EdenEast's public nix configuration. I am sure I missed someone's repo in the list, but I'm trying to give credit where credit is due.
Below are descriptions of the hosts configurations. If you have access to windows / wsl, I recommend wsl/hosts/nixos.
├─ system
├─── darwin
├───── hosts
├─────── mwdavis-workm1 # => Work Macbook / 2022 16" Pro M1
├─── droid
├───── hosts
├─────── default # => Google Pixel Fold
├─── nixos
├───── hosts
├─────── ares # => Personal WSL w/ personal credential decryption
├─────── athena # => Personal laptop - Alienware m15 R6 / i7 / RTX 3080 / nixos only
├─────── hephaestus # => Home machine - Custom Build / i9 / AMD 7900xt / dual boot nixos+win
├─────── livecd # => Bootable installer ISO w/ custom shell
├─────── olenos # => Work laptop - Thinkpad x13 / i7 / integrated graphics / nixos only
├─────── virtualbox # => Oracle Virtualbox Image (Gnome + Shell)
├─────── nixos # => Generic WSL2
This repository uses ryantm/agenix to manage secrets. The secrets are stored as encrypted age files in a private repository. To run this as is, you will need to either remove all references to secrets or create your own secrets repository.
The easiest way to run this is to update 'flake.nix` to use my nix-secrets-example repository. Replace this:
secrets = {
url = "git+ssh://git@github.com/mwdavisii/nix-secrets.git";
flake = false;
};
with this:
secrets = {
url = "git+https://git@github.com/mwdavisii/nix-secrets-example.git";
flake = false;
};
Then make sure the options in '/system/$darwin or $wsl2>/hosts/$hostname/default.nix are all marked false as shown below. This will maintain the secrets skeleton, but should not error since no decryption configuration is provided.
nyx = {
modules = {
user.home = ../../shared/home.nix;
};
secrets = {
awsSSHKeys.enable = false;
awsConfig.enable = false;
userSSHKeys.enable = false;
userPGPKeys.enable = false;
};
profiles = {
desktop = {
enable = true;
};
};
};
If you want to actually build and decrypt secrets, here is what my secrets repository looks like:
.
├─ secrets.nix # The secrets file you're instructed to create in this tutorial => https://github.com/ryantm/agenix?tab=readme-ov-file#tutorial
├─ encrypted # Subdirectory to hold encrypted files
├─── id_ed25519.age files # Example encrypted file
** Note that if the repository is private and you're using sudo, it will be looking for the github ssh key in the /root/.ssh
directory and not your user directory.
- Make sure you have WSL enabled and installed. Click here if you need help setting up basic WSL2.
- Make sure you have git installed in windows. You can download it here.
- Open up a PowerShell window
- Clone this repo and start the windows side of the installation by executing start_here.ps1.
git clone https://github.com/mwdavisii/nyx.git
set-location ./nyx/setup/wsl
./start_here.ps1
- You should now be in your windows user directory, but in the NixOS shell. Move back into the startup directory and launch step2.sh.
cd ./nyx/setup/wsl
./step2.sh
Note
Some users have reported a shell error when running step 2. If you see an error message that contains \r
, it's likely git converted line breaks to windows format. I think it's caused b having git config --global core.autocrlf
set to true
on windows. If this happens, the easiest thing to do is go to your home directory cd ~
and clone another copy of the repo through nix (commands below). If you do this this, don't forget to update your secrets.
sudo nix-channel --add https://nixos.org/channels/nixos-24.05 nixos
sudo nix-channel --update
nix-shell -p git vim
git clone https://github.com/mwdavisii/nyx
After this, you shou be able to continue to step 6.
- Before running the last step, open ./flake.nix in your favorite text editor and look for the lines below and change the following values:
- displayName => Display Name used in GitHub config
- email => Display Name used in GitHub config`
- signingKey => The key used to sign git commits. (you can leave blank)`
- windowsUserDirName => This is the folder name of your windows profile. It is used to create the symlink from WSL to VS Code and add it to your path.
*Note: Leave the userName as nixos for wsl unless you know how to configure non-default users in nixos for WSL. As of now, it requires building from nix-community/NixOS-WSL which is more than I care to tackle at the moment.
{
userName = "nixos";
email = "mwdavisii@gmail.com";
displayName = "Mike D.";
signingKey = "5A60221930345909";
windowsUserDirName = "mwdav";
}
- Finally, run the last script, step3.sh.
./step3.sh
Now close the current shell and open a new one. After the initial install, you can apply updates by executing the refresh script.
./switch.sh #Rebuilds and switches to the home environment.
- Make sure you have git installed. You can download it here.
- Clone this repository.
git clone https://github.com/mwdavisii/nyx.git
cd ./nyx/macos
- Launch the installation script
./start_here.sh
- Copy the
./users/mwdavisii.nix
file into a new file with your username. Then use your favorite text editor and update the information in the file. You can safely ignore the windowsUserDirName value, that is exclusively for WSL2 and VS Code.
- displayName => Display Name used in GitHub config
- email => Display Name used in GitHub config`
- signingKey => The key used to sign git commits. (you can leave blank)`
{
userName = "mwdavisii";
email = "mwdavisii@gmail.com";
displayName = "Mike D.";
signingKey = "5A60221930345909";
windowsUserDirName = "";
}
- Edit the
./flake.nix
file and look for the following lines. Change the user to the user you created above and if you are running an intel mac, changeaarch64-darwin
tox86_64-darwin
.
darwinConfigurations = mapAttrs' mkDarwinConfiguration{
mwdavis-workm1 = {system = "aarch64-darwin"; user = "mwdavisii";};
};
- Apply the changes
./step2.sh
- Now close the current shell and open a new one. After the initial install, you can apply updates by executing the refresh script.
./switch.sh #Rebuilds and switches to the home environment.
I've created a virtualbox host and am using nix-community to build. It supports all kinds of outputs. My plan was to create a host for each platform I care about and continue to use nixosModules ++ commonModules
in lib/default.nix
and flakes.nix
to define the configurations.
- You will need to install Nix-on-Droid from f-droid
- Go into the root of the initial installation and edit
~/.config/nixpkgs/nix-on-droid.nix
to add 'git' to the packages - run
nix-on-droid switch --flake .
from the directory withflake.nix
in it. - Once complete, run
git clone https://github.com/mwdavisii/nyx.git
- Run
cd nyx
and the runnix-on-droid switch --flake .
Notes On NixOnDroid NixOnDroid is still rudimentary and doesn't have full support for attrs and other functions yet. Because of that, it doens't follow the same mkAttrs
into options
for build. It just looks at the files in home/droid/modules
and runs the configuration there. You can see many of the modules are simplified for this environment.
I have over 150+ commits in the last week. I am not new to declarative systems and have been using git ops strategies since they had a name. Nix was brand new to me and trying to pick up Nix + Flakes + Attributes at the same time was difficult. I can't tell you how many times I've typed git reset --hard
or nix-on-droid rollback
.
Here are some things that would have shortned my learning curve:
- EdenEast's Nyx Readme
- Introduction to Nix & NixOS
- An Introduction to Nix Flakes
- Flakes aren't real and cannot hurt you: a guide to using Nix flakes the non-flake way
- There is a lot of basic documentation and examples for nixos, flakes, and most modules. However, when introducing attribute sets, I found it more difficult to apply the published examples to the more complex approach. There was a lot of looking at other peoples repos, asking gemini for help, and a good bit of trial and error.
- I tried to be pure, but quickly found out the variation between systems and packages didn't always allow it.
- For instance, I would have put all user secrets inside of
home/
instead ofsystem/
, but I kept having issues with ryantm/agenix in home manager, and didn't want to use a custom activation script.
- For instance, I would have put all user secrets inside of
- Rollback a build that successfuly failed by executing
nixos-rebuild switch --rollback
ordarwin-rebuild switch --rollback
ornix-on-droid rollback
.- I was frequently wiping and rebuilding the entire system before I knew this.
- In regards to
nyx.modules
,nyx.profiles
, andnyx.secrets
- In each
mk${system}Configuration
, the lines below actually create the root options (config.nyx.profiles
,config.nyx.modules
, andconfig.nyx.secrets
). - These options are set in
system/$system/hosts/$hostname/default.nix
. - These options are applied from various subdirectories:
- Secrets (
config.nyx.secrets
) are applied fromsystem/shared/secrets
- Profiles (
config.nyx.profiles
) are applied fromsystem/shared/profiles
- Modules (these are applied by home-manager)
- App Modules (
config.nyx.modules.app
) are applied fromhome/shared/modules/app
- Dev Modules (
config.nyx.modules.dev
) are applied fromhome/shared/modules/dev
- Shell Modules (
config.nyx.modules.shell
) are applied fromhome/shared/modules/shell
- App Modules (
- Secrets (
- In each
Example from lib/default.nix
:
(import ../system/nixos/shared/modules)
(import ../system/shared/profiles)
(import ../system/shared/secrets)
(import (strToPath config ../in/hosts))
Example from system/$system/hosts/$hostname/default.nix
:
nyx = {
modules = {
user.home = ./home.nix;
};
secrets = {
awsSSHKeys.enable = true;
awsConfig.enable = true;
userSSHKeys.enable = true;
userPGPKeys.enable = true;
};
profiles = {
desktop = {
enable = true;
};
};
};