This config is tailored to my needs, and is not meant to be a tutorial, but if you do find anything you like, feel free to yank it :)
This repository is home to the nix code that builds my systems:
- NixOS Desktop: NixOS with Flakes, Home-manager, Sops-Nix, etc.
- MacOS Laptop: nix-darwin with home-manager, share the same home-manager configuration with NixOS.
- HomeLab server: (TODO)
- Rpi-HomeAssistant: (TODO)
| Component | NixOS | MacOS |
|---|---|---|
| Color Scheme | Nord | Nord |
| Dev environment | direnv + devenv | direnv + devenv |
| Editor | Neovim | Neovim |
| File Manager | lf | lf |
| Fonts | Fira Code | Fira Code |
| Input remapper | N/A | Kanata |
| Launcher | Default | Raycast |
| Multiplexer | Zellij | Zellij |
| Shell | Fish + Nushell | Fish + Nushell |
| Terminal | Ghostty | Ghostty |
| VPN | Tailscale | Tailscale |
| Window Manager | PopShell | Yabai |
TODO PICTURE
Most of the packages / programs used are installed and configured using home manager.
βββ core.nix # shared packages
βββ darwin.nix # MacOS specific config
βββ linux.nix # NixOS specific config
βββ programs # complex or optional config
βββ ...To evaluate and list installed packages run:
nix eval .#nixosConfigurations.nixos.config.home-manager.users.<USERNAME>.home.packages --json | jq- home-manager
- nix-darwin
- sops-nix
βββ darwin
β βββ apps.nix # system packages & Homebrew
β βββ system.nix # system settings & MacOS-defaults
βββ linux
βββ configuration.nix # system settings
βββ hardware-configuration.nix # auto generatedTo evaluate the packages installed system-wide:
nix eval .#darwinConfigurations.<HOST>.config.environment.systemPackages --json | jqNeoVim is configured directly in this repo and symlinked to
$XDG_CONFIG_HOME/nvim when built.
// TODO PICTURE
Nvim config can be found here => ./dotfiles/nvim/
Ghostty enabled using home-manager
Currently there are some build issues on darwin,
so on darwin, Ghostty is install using Homebrew
and only configured by home-manager
./home/programs/ghostty.nix
Fish enabled using home-manager
On darwin, the default shell needs to be updated using
chsh -s /etc/profiles/per-user/hest/bin/fish
Plugins:
Nushell - WIP
I manage the secrets used in this repository using Sops-Nix. The secrets are encrypted and then stored in a private repository that is then used as a flake input.
All the secrets are encrypted using age and the secrets can only be decrypted host specific keys, that needs to be generated before initial setup.
For the initial setup a new private repo is used.
Following this blog post the first step is to create a host specific age key file that is used encrypt/decrypt.
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt # generate key
age-keygen -y ~/.config/sops/age/keys.txt # fetch public keyTo generate secrets, sops need a blueprint file to know what to do:
In the private repo create .sops.yaml
keys:
- &host1 <YOUR PUBLIC KEY>
creation_rules:
- path_regex: secrets.yaml$
key_groups:
- age:
- *host1Once the age file and sops blueprint is in place, modifying sops secrets are done using the sops CLI
# if sops is not installed yet
nix-shell -p sops --run "sops secrets.yaml"
# if sops already in place
sops secrets.yamlThis will open a decrypted secrets.yaml file that can be edited freely.
On closing the file, sops will re-encrypt the file, making it safe to store/send.
To use sops secrets in the flake, the first step is to import the sops module as well as the private repo as a flake.
flake.nix
inputs = {
sops-nix.url = "github:Mic92/sops-nix";
dot-secrets = {
url = "git+ssh://[email protected]/HestHub/dot-secrets.git";
flake = false;
};
};
...
# include sops module in home manager
home-manager.darwinModules.home-manager
{
...
home-manager.sharedModules = [
sops-nix.homeManagerModules.sops
];
...
}Then in the home-manager config, sops can be used to pick out
and decrypt any defined secrets.
Sops will create new files with the content found in the secrets.yaml file
sops = {
# select key to use for decryption
age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
# select file to decrypt from secrets repo
defaultSopsFile = "${inputs.dot-secrets}/secrets.yaml";
secrets = {
# create new file from the secret used
"ssh/key".path = "${config.home.homeDirectory}/.ssh/id_X";
};
};To allow a new host to decrypt the secrets, it has to be added as a new sops recipient
keys:
- &host1 <YOUR PUBLIC KEY>
- &host2 <SECOND PUBLIC KEY>
creation_rules:
- path_regex: secrets.yaml$
key_groups:
- age: [*host1, *host2]With the new host key in place, sops updatekeys secrets.yaml
will add host2 key as a new recipient
Another popular, possibly simpler solution is to use Agenix to manage secrets. Sops demands a somewhat more complex initial setup, but once in place, the workflow it quite simple.
The primary reason Sops is used over Agenix is due to some rumblings online that Agenix needs some workarounds to work well on Darwin.
This might be old hat and not applicable anymore, but Sops seemed to be the safe choice for Darwin.
π΄ IMPORTANT: Do not try to deploy this flake as is β It will not succeed. This flake contains my hardware configuration, and requires my private secrets repository using Sops-Nix to deploy. Only use this repo as a reference to build your own setup
If you like to deploy a flake like this, read through the code and pick out the pieces that seems relevant and create your own flake, or just fork it and remove anything not relevant. Most important parts to remove is the hardware-configuration for NixOS, the secrets management in home manager and swap host-names and user-names.
NixOS:
# clone repo
git clone https://github.com/HestHub/nixos.git
# fetch tools
nix-shell -p age just
# create new age key
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
age-keygen -y ~/.config/sops/age/keys.txt
# (Move key to secret repo & add as recipient)
# rebuild system
sudo nixos-rebuild switch --flake .#<HOSTNAME>
# or deploy via `just`(a command runner with similar syntax to make) & Justfile
nix-shell -p just
just build
MacOS:
#install Xcode
xcode-select --install
# Install nix (Say NO to install determinate)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# clone repo
git clone https://github.com/HestHub/nixos.git
# fetch tools
nix-shell -p age just
# create new age key
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
age-keygen -y ~/.config/sops/age/keys.txt
# (Move key to secret repo & add as recipient)
# Deploy Dariwn config
just build
- Nushell
- Disko
- Cleanup
- CI
- Move scripts to repo
- Security hardening
- adding server to combined config
- expanding secrets management
Good reads and dotfiles that inspired me: