This repository contains my personal Nix configuration for managing my Mac laptop and Linux home servers using a declarative, reproducible approach with Nix flakes.
This configuration manages:
- macOS laptop (cloudbank) - M-series Mac with nix-darwin
- Linux servers - Multiple headless NixOS home servers:
- ultraviolet, bluedesert, echelon
- Unified Configuration: Single repository managing both macOS and Linux systems
- Modular Design: Separated system-level and user-level configurations
- Consistent Theming: Catppuccin Mocha theme across all applications
- Custom Packages: Currently includes a customized Caddy web server
- Development Environment: Neovim, Git, Starship prompt, and modern CLI tools
- Simplified Architecture: Streamlined flake structure with minimal abstraction
- Devspace Development Environment: Persistent tmux-based remote development sessions
- Remote Link Opening: Seamless browser integration for SSH sessions
On the target machine, use the update alias or run directly:
# macOS
darwin-rebuild switch --flake ".#$(hostname -s)" --option warn-dirty false
# Linux
sudo nixos-rebuild switch --flake ".#$(hostname)" --option warn-dirty falsenix flake updatenix build .#myCaddy # Custom Caddy web serversudo ./scripts/flash-stygianlibrary.sh /dev/sdX # replace with your USB deviceThe script partitions the stick, installs the full stygianlibrary
closure directly onto it, and leaves the filesystems mounted at
/mnt/stygianlibrary. It creates a small unencrypted EFI partition plus a
LUKS2-encrypted volume that holds everything else, so you'll be prompted to set
the passphrase during flashing and again when the machine boots. It also clones
this repo via HTTPS into /mnt/stygianlibrary/persist/nix-config so the system
starts with the source on disk. After booting from the stick, you're already
running the production configuration; use your usual credentials or SSH keys the
same way you would on the deployed machine.
nix build .#egoengine
docker load < resultThe image loads into Docker as egoengine:<nix-hash>. Tag and push it to
ghcr.io/veraticus/nix-config/egoengine or run it locally for validation.
flake.nix- Main entry point and flake configurationhosts/- System-level configurations for each machinecommon.nix- Shared configuration for Linux servers (NFS mounts)
home-manager/- User-level dotfiles and application configscommon.nix- Shared configuration across all systemsaarch64-darwin.nix- macOS-specific user configurationheadless-x86_64-linux.nix- Linux server user configuration- Individual app modules (neovim, zsh, kitty, etc.)
pkgs/- Custom package definitionsoverlays/- Nixpkgs modificationssecrets/- Public keys
- Editor: Neovim with custom configuration
- Terminal: Kitty with Catppuccin theme
- Shell: Zsh with syntax highlighting and autosuggestions
- Version Control: Git
- AI Assistance: Claude Code (automatically installed via npm)
- Window Manager: Aerospace
- Package Management: Homebrew (declaratively managed)
- Kubernetes: k9s for cluster management
- File Sharing: NFS mounts to NAS
- Web Server: Custom Caddy build
- Simplified Flake Structure: Removed unnecessary helper functions and abstractions
- Unified Nixpkgs: Using nixpkgs-unstable as primary source
- Single Overlay: Consolidated all overlays into one default overlay
- Minimal Special Args: Only passing essential inputs and outputs
- Direct Home Manager Integration: Home Manager configured directly in flake.nix
To add a new system:
- Create a configuration in
hosts/<hostname>/ - Add to
flake.nixunder appropriate section (nixosConfigurations or darwinConfigurations) - Add hostname to the appropriate list in homeConfigurations
To add a new package:
- Create package in
pkgs/<name>/default.nix - Add to
pkgs/default.nix - Add to overlay in
overlays/default.nixif needed globally
The dev context system unifies the metadata that describes where a shell is running. Every session exports DEV_CONTEXT, DEV_CONTEXT_KIND, and an optional DEV_CONTEXT_ICON, and all UI surfaces read from those variables. Starship prompts, Kitty tab titles, tmux status lines, and mobile notifications now stay in sync regardless of whether the context came from tmux, Coder, or a plain host shell.
tmux-devspacewrapstmux new-session/attachand immediately setsDEV_CONTEXT,DEV_CONTEXT_KIND=tmux, plus whateverDEV_CONTEXT_ICONvalue the caller provides via--icon. LegacyTMUX_DEVSPACEvariables still exist for older scripts but should be treated as compatibility shims.t(defined inhome-manager/zsh/default.nix) is the main entry point. Runningtwith no arguments creates an auto-named context.t feature-login ☾sanitizes the label, records the icon, and spawns/attaches tofeature-login. Uset feature-login -- cargo watchto skip the icon while forwarding a command after--.- Planetary aliases (
mercury,venus,earth,mars,jupiter) remain for muscle memory on both the servers and macOS clients. Each alias now callst <planet> <icon>(ortmux-devspace attach --icon ...on macOS), so the icon travels with the context from the moment it is created. - On Coder,
CODER_WORKSPACE_NAMEseedsDEV_CONTEXTwithDEV_CONTEXT_KIND=coder, so prompts stay labeled even when tmux is not involved.
t # Create/switch to an auto-named context
t feature-login ☾ # Spawn or attach to feature-login with a moon icon
t feature-login -- cargo watch # Run a command without setting an icon
earth # Attach to the earth planetary context (via t earth ♁)
mars status # Invoke helper subcommands inside that context
devspace-status # List sessions on the current host (alias: ds)
dsl # Detailed tmux session listing
- During shell init we import tmux-provided context variables (when inside tmux), fall back to
CODER_WORKSPACE_NAME, and finally to the system hostname (DEV_CONTEXT_KIND=host). - Starship replaced the older devspace segment with a context-aware block that shows the icon and
DEV_CONTEXT. Coder contexts default to, tmux planetary contexts get their astronomical glyphs (☿♀♁♂♃), and non-planetary sessions display as● <label>. - Tmux titles now use the per-session option
@dev_contextso Kitty tabs, native terminal windows, and the macOS tab bar all render the same label. - The Codex
ntfynotifier includes the context string (and icon when present), so phone alerts point to the exact session that completed.
- Consistent naming flows through tmux, prompts, tab titles, and notification hooks.
- No reliance on tmux-only variables; any tool can opt-in by exporting
DEV_CONTEXTand friends. - Icons become optional metadata that travels with the session, enabling richer UI hints without heuristics.
Compatibility aliases and historical docs still reference “devspaces”, but new code and copy should prefer the “dev context” terminology.
When SSH'd into a server, links can be opened on your local Mac browser automatically. This is especially useful for AWS SSO authentication.
- The server sets
BROWSER=remote-link-open - When applications try to open URLs, they display as clickable links in Kitty
- Click the link in your terminal to open it in your Mac browser
# On the server
aws sso login # Will display a clickable authentication URL
remote-link-open https://example.com # Manually open a URLSee CLAUDE.md for detailed testing procedures. Quick summary:
# Validate configuration
nix flake check
# Preview changes
darwin-rebuild switch --flake ".#$(hostname -s)" --option warn-dirty false --dry-run
# Build specific components
nix build .#homeConfigurations."joshsymonds@$(hostname -s)".activationPackage