This repository contains my personal system configurations for multiple machines using Nix, managed through the Den aspect-oriented configuration framework.
- harmony (x86_64-linux): Home server running media services, Minecraft servers, and infrastructure
- melaan (x86_64-linux): Framework laptop with GNOME desktop
- OMARSHAL-M-2FD2 (aarch64-darwin): MacBook with development environment
- omarshal@dev203.meraki.com (x86_64-linux): Standalone Home Manager config reusing the
oscaraspect for a work machine
- Nix with flakes enabled
- Appropriate system (NixOS, macOS, or Linux for home-manager only)
git clone https://github.com/OscarMarshall/dotfiles.git
cd dotfilesNixOS systems (harmony, melaan):
sudo nixos-rebuild switch --flake .#<hostname>macOS systems (OMARSHAL-M-2FD2):
darwin-rebuild switch --flake .#OMARSHAL-M-2FD2Standalone Home Manager (omarshal@dev203.meraki.com):
home-manager switch --flake .#"omarshal@dev203.meraki.com"# nix flake check currently fails due to cross-architecture issues
# Use platform-specific builds instead:
nix build .#nixosConfigurations.harmony.config.system.build.toplevel
nix build .#nixosConfigurations.melaan.config.system.build.toplevel
nix build .#darwinConfigurations.OMARSHAL-M-2FD2.config.system.build.toplevel
# Show available outputs
nix flake show
# Format code
nix fmtThis repository uses Den, an aspect-oriented configuration system built on flake-parts. Configuration is organized into composable aspects:
modules/aspects/hosts/: Host-specific configurations (one aspect per host)modules/aspects/users/: User-specific configurations (one aspect per user)modules/aspects/my/: Reusable service and feature aspects (~55 total)modules/aspects/defaults.nix: Default includes applied to all configurations
Each aspect can provide configuration for different targets using these classes:
os: Applies to both NixOS and Darwin (avoids duplicating identical config innixosanddarwin)nixos: NixOS-specific configuration onlydarwin: macOS (nix-darwin) specific configuration onlyhomeManager: Home Manager configuration (cross-platform user environment)hmLinux/hmDarwin: Platform-specific Home Manager classes forwarded intohomeManagerbymodules/aspects/defaults.nix
Each host declares which services and features to enable:
# modules/aspects/hosts/harmony/harmony.nix
den.aspects.harmony = {
includes = with my; [
nginx
(minecraft-servers { administrators = [ "oscar" ]; })
(qbittorrent { administrators = [ "oscar" ]; })
plex
# ... more aspects
];
};Each user declares their environment and applications:
# modules/aspects/users/oscar/oscar.nix
den.aspects.oscar = { host, lib, ... }: {
user.description = "Oscar Marshall";
includes = [
my.emacs
my.git
] ++ lib.optionals (host.graphical or false) [ my.discord my.ghostty ];
};Use an aspect function signature ({ host, lib, ... }:) when you need context-aware conditional logic.
- Media: Plex, Radarr, Sonarr, Prowlarr, Unpackerr, Autobrr, Cross-seed
- Downloads: qBittorrent (via Gluetun VPN)
- Gaming: Minecraft servers
- Infrastructure: Nginx reverse proxy with Let's Encrypt, Samba file sharing, ZFS storage
- GNOME on melaan (Wayland, via NixOS)
- macOS desktop: Fonts, Homebrew-based applications, and Nix-managed development environment on OMARSHAL-M-2FD2
- Applications: Emacs, Ghostty terminal, Zen Browser, Discord, Steam, Krita, PrusaSlicer
- Framework laptop support via nixos-hardware
- Emacs with doom configuration
- Git with per-machine configuration
- GPG and SSH setup
- Shell: Fish shell via Home Manager
Secrets are managed with ragenix (age encryption) extended by
agenix-rekey. A YubiKey acts as the single master identity; host keys are
derived automatically. Primitive secrets are encrypted to the YubiKey. Mark a primitive secret intermediary = true
only if it is exclusively consumed by generators (never referenced directly by services). Template secrets (env files,
JSON configs) are generated from primitives and then rekeyed per host.
The dev shell (automatically activated by direnv via the .envrc in the repo root) provides the
agenix CLI tool from agenix-rekey, which is the single script needed to add/update/generate/rekey secrets.
Note: Editing primitive secrets, running
agenix generate, and runningagenix rekeyrequire physical YubiKey access and must be performed by a human.
# Edit or create a primitive secret (human only — requires YubiKey)
agenix edit secrets/<name>.age
# Generate template secrets from primitives (human only — requires YubiKey)
agenix generate
git add secrets/generated/
# Rekey all secrets for all hosts and commit (human only — requires YubiKey)
agenix rekey -a
git add secrets/rekeyed/harmony/
git add secrets/rekeyed/melaan/- Primitive secrets (
secrets/*.age): encrypted to the YubiKey master identity. Addintermediary = trueonly if the secret is exclusively consumed by generators. - Template secrets: generated from primitives by
agenix generateintosecrets/generated/, then rekeyed per host viaagenix rekey -aintosecrets/rekeyed/<hostname>/. secretsclass: use in host/user/service aspects to declare secrets — preferred over settingage.secretsdirectly. Forwarded toage.secretson all platforms (NixOS, Darwin, Home Manager) bydefaults.nix.nixosSecretsclass: used in user/host aspects for NixOS-only secrets (e.g. hashed passwords). Forwarded only tonixos.age.secrets, never to Darwin or Home Manager configs. Prefersecretsunless the secret must be excluded from non-NixOS hosts.
Each host that consumes rekeyed secrets must declare age.rekey.hostPubkey in its host aspect.
GitHub automation:
- Dependabot handles GitHub Actions and Nix (
flake.lock) updates. - Dependabot PRs are automatically set to auto-merge once required checks pass.
- Renovate is kept only for Docker image updates referenced from Nix files.
nix flake updatenix flake update <input-name>The flake.nix is auto-generated by flake-file. After modifying inputs in
modules/inputs.nix:
nix run .#write-flake- Create
modules/aspects/my/<service>.nix - Define the aspect (with parameters if needed)
- Include in host's aspect:
modules/aspects/hosts/<hostname>/<hostname>.nix
- Create
modules/aspects/hosts/<hostname>/<hostname>.nix - Add a NixOS
hardware-configuration.nixfor the host - Declare the host in
modules/den.nix
- Create
modules/aspects/hosts/<hostname>/<hostname>.nix - Configure the host-specific nix-darwin options in your aspect
- Declare the host in
modules/den.nix
- Create
modules/aspects/users/<username>/<username>.nix - Add user to host declarations in
modules/den.nix
- Den Documentation - Aspect system patterns and usage
- Dendritic Template - Template this repo is based on
- NixOS Manual - NixOS configuration reference
- Home Manager Manual - Home Manager options
- nix-darwin Manual - macOS system configuration
This is a personal configuration repository. Feel free to use it as reference or template for your own configurations.