ITADN
George-Miao/nix-config
George-Miao/nix-config · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md

Nix Config

This is my personal NixOS configuration using Nix flakes. The README is mainly generated by AI for future myself because I'm forgetful.

Architecture

This configuration uses a modular architecture built on top of flake-parts:

Directory Structure

  • /flake.nix: Entry point for the flake, defines nixosConfigurations, darwinConfigurations, and deploy.nodes.
  • /unit: Modular configuration units that can be composed together.
    • /unit/default.nix: Collects and exports all units and presets.
    • /unit/home/*: Home-manager units for user-space configuration.
    • /unit/sys/*: System-level units (NixOS or nix-darwin).
    • /unit/preset: Predefined collections of units (bare, core, local, server, gui).
  • /system: OS-specific system configurations.
    • /system/shared: Shared configuration across all systems.
    • /system/darwin: macOS-specific configuration.
    • /system/nixos-desktop: NixOS desktop configuration.
    • /system/nixos-server: NixOS server configuration.
  • /machine: Machine-specific configurations.
    • Desktop machines: Atlas, Everest
    • Darwin machines: Fuji, Marcy
    • Servers: Colden, LUX, LAX, EWR, HEL, HND, YUL
    • Special: ProxmoxLXC (template for LXC containers), Minimum (minimal config)
  • /secrets: Encrypted secrets managed with git-crypt.
  • /static: Static files like GPG and SSH public keys.

Key Concepts

Units

Units (./unit/{home/*,sys/*}) are modules that can be imported directly. They are organized into:

  • Home units: User-space configuration
  • System units: OS-level configuration
  • Presets: Pre-composed collections of units for different use cases:
    • bare: Minimal CLI environment
    • core: Essential command-line tools
    • local: Full local development environment, shared across local NixOS and Darwin
    • server: Server-optimized configuration
    • gui: Desktop GUI applications, some are Linux specific

Systems

Systems (./system/*) import presets and system units, then add OS-specific but machine-agnostic configurations. They define the baseline for each operating system type (Darwin, NixOS Desktop, NixOS Server).

Machines

Machines (./machine/*) import their corresponding system configuration and add machine-specific settings like:

  • Hardware configuration
  • Hostname and networking
  • User accounts
  • Machine-specific services

Build Functions

The flake defines specialized builders:

  • mkDarwinSystem: Builds macOS systems using nix-darwin
  • mkLinuxDesktop: Builds NixOS desktop systems with GUI support
  • mkLinuxServer: Builds NixOS server systems
  • mkLinuxService: Builds specialized service containers for Proxmox LXC

External Inputs

  • nixpkgs: Tracks nixpkgs-unstable
  • home-manager: User environment management
  • nix-darwin: macOS support
  • flakes: Personal package overlay
  • rust-overlay: Rust toolchain management
  • disko: Declarative disk partitioning
  • deploy-rs: Remote deployment tool
  • lanzaboote: Secure boot support
  • zen-browser: Privacy-focused browser
  • nixos-generators: Generate various system images (e.g., Proxmox LXC)
  • vscode-server: Remote VS Code support

Usage

Local Activation

Just run rb anywhere.

Enter the development shell to make the pinned Infisical CLI available:

nix develop

Before rebuilding, rb fetches secrets with the Infisical CLI. Authenticate the CLI and link this directory to a project with infisical init (or provide the usual Infisical machine-identity environment variables). Dotted secret names form the Nix attribute path: for example, github.oauth_token becomes secrets.github.oauth_token. Infisical values override matching values from secrets/secrets.nix for that evaluation only.

The equivalent flake command is:

nix run .#activate

Both commands stream the root-folder export into a root-owned 0600 file inside a root-only temporary directory under /var/run. They invoke the rebuild with impure evaluation and remove the file and directory afterward.

Import a JSON object into Infisical with:

printf '%s\n' '{"github":{"oauth_token":"secret"}}' \
  | ./scripts/import-infisical-secrets.sh --env prod

Nested objects become dotted root-level secrets, so this example writes the Infisical secret github.oauth_token. Activation expands it back into a nested Nix attribute set. Every Infisical value is stored as JSON text, including quoted JSON strings, so activation can restore its exact type with fromjson. All values are staged in permission-restricted temporary files and sent in one infisical secrets set call using name=@file arguments.

Remote Deployment

Remote servers are deployed using deploy-rs:

deploy .#<machine-name>

Building Images

Generate a Proxmox LXC template:

nix build .#proxmox-lxc

Notes

  • Units (./unit/{home/*,sys/*}) are "bare" in the sense that they can output to flake directly, where Machines (./machine/*) are not because they are wrapped by system declarations, e.g., nixpkgs.lib.nixosSystem/nix-darwin.lib.darwinSystem.
  • Units are imported in flake.nix as unit.{home,sys}, in which home units are further collected into unit.preset.{bare,core,local,server,gui} to form five "profiles"; all of which are passed down to systems and machines config with specialArgs and home-manager.extraSpecialArgs.
  • Systems (./system) imports aforementioned "profiles" and sys units, then add machine-agnostic but os-dependent configurations.
  • Machines (./machine) imports corresponding systems and sys units, then add machine-specific configurations.
  • deploy-rs is used to push local changes to remote machines (configs live under .#deploy.nodes).
  • Secrets are managed with git-crypt and keys are encoded with base64. Decode with echo $KEY | base64 -d.

Invariants

  • This config MUST live under $HOME/.nix-config