From 0cec50d6071d9d8da11b857cc4ce79cf98f33bed Mon Sep 17 00:00:00 2001 From: Elias Kohout Date: Tue, 7 Apr 2026 02:34:03 +0200 Subject: [PATCH] init by ai --- .gitignore | 22 ++ ARCHITECTURE.md | 390 +++++++++++++++++++++++ CUSTOMIZATION.md | 477 +++++++++++++++++++++++++++++ INDEX.md | 225 ++++++++++++++ QUICKREF.md | 141 +++++++++ README.md | 269 ++++++++++++++++ SETUP.md | 364 ++++++++++++++++++++++ flake.nix | 203 ++++++++++++ home/default.nix | 48 +++ home/modules/dev-tools.nix | 54 ++++ home/modules/editor.nix | 69 +++++ home/modules/example-template.nix | 56 ++++ home/modules/git.nix | 30 ++ home/modules/shell.nix | 40 +++ hosts/laptop/default.nix | 57 ++++ hosts/server/default.nix | 53 ++++ nixos/default.nix | 44 +++ nixos/modules/development.nix | 50 +++ nixos/modules/example-template.nix | 55 ++++ nixos/modules/secrets-example.nix | 69 +++++ nixos/modules/shell.nix | 28 ++ nixos/modules/system.nix | 25 ++ secrets/.sops.yaml | 34 ++ 23 files changed, 2803 insertions(+) create mode 100644 .gitignore create mode 100644 ARCHITECTURE.md create mode 100644 CUSTOMIZATION.md create mode 100644 INDEX.md create mode 100644 QUICKREF.md create mode 100644 README.md create mode 100644 SETUP.md create mode 100644 flake.nix create mode 100644 home/default.nix create mode 100644 home/modules/dev-tools.nix create mode 100644 home/modules/editor.nix create mode 100644 home/modules/example-template.nix create mode 100644 home/modules/git.nix create mode 100644 home/modules/shell.nix create mode 100644 hosts/laptop/default.nix create mode 100644 hosts/server/default.nix create mode 100644 nixos/default.nix create mode 100644 nixos/modules/development.nix create mode 100644 nixos/modules/example-template.nix create mode 100644 nixos/modules/secrets-example.nix create mode 100644 nixos/modules/shell.nix create mode 100644 nixos/modules/system.nix create mode 100644 secrets/.sops.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68dc93b --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Secrets (encrypted with sops, but don't auto-commit) +/secrets/secrets.yaml + +# System files +.DS_Store +*.swp +*~ +.vscode/ + +# Temporary files +*.tmp +.#* + +# Nix artifacts +result +result-* +.envrc +.direnv/ + +# Development +.idea/ +*.iml diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..7c74745 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,390 @@ +# Architecture & Design Principles + +An overview of how your portable NixOS configuration is structured and why. + +## Core Design Goals + +1. **Portability**: Deploy to new machines, existing NixOS, or non-NixOS with minimal effort +2. **Modularity**: Enable/disable features independently without tight coupling +3. **Reproducibility**: Flakes + lock files ensure identical environments across machines +4. **Maintainability**: Clear separation of concerns (system vs home, shared vs per-machine) +5. **Secrets Management**: Encrypted, portable secrets with sops-nix +6. **Scalability**: Easy to add new machines and modules + +## Architecture Overview + +``` +nix-los/ +├── flake.nix # Single source of truth for all configurations +│ # Defines: inputs, outputs, configurations +│ +├── hosts/ # Per-machine specific overrides +│ ├── laptop/ # Machine-specific hardware, features +│ └── server/ # (template for new machines) +│ +├── nixos/ # System-level modules (NixOS only) +│ ├── default.nix # Imports all modules +│ └── modules/ # Toggleable features +│ ├── system.nix # Users, sudo, locale +│ ├── development.nix # Languages, tools +│ ├── shell.nix # Shell config +│ └── secrets-example.nix (inactive) +│ +├── home/ # User-level configuration (portable) +│ ├── default.nix # Imports all modules, can run standalone +│ └── modules/ # User-level features +│ ├── shell.nix # Zsh, direnv, starship +│ ├── editor.nix # Neovim, VSCode +│ ├── git.nix # Git configuration +│ └── dev-tools.nix # Tmux, utilities +│ +├── secrets/ # Encrypted credentials +│ ├── .sops.yaml # Encryption keys (DO NOT COMMIT UNENCRYPTED) +│ └── secrets.yaml # Encrypted secrets +│ +├── flake.lock # Pinned versions (COMMIT THIS) +└── docs/ + ├── README.md # Getting started + ├── SETUP.md # Detailed setup instructions + ├── QUICKREF.md # Command reference + ├── CUSTOMIZATION.md # Extension patterns + └── ARCHITECTURE.md # This file +``` + +## Data Flow + +### On a NixOS System + +``` +┌─────────────────────────────────────────┐ +│ flake.nix (configuration) │ +│ - Defines all inputs (nixpkgs, etc) │ +│ - Specifies nixosConfigurations │ +└──────────────────┬──────────────────────┘ + │ + ┌──────────┴──────────┬─────────────────┐ + │ │ │ + ┌────▼────┐ ┌─────▼──────┐ ┌─────▼──────┐ + │ hosts/* │ │ nixos/* │ │ home/* │ + │(device) │ ──────► │(system cfg)│ │(user cfg) │ + └────┬────┘ └─────┬──────┘ └─────┬──────┘ + │ │ │ + └────────────────────┼─────────────────┘ + │ + ┌────────────▼──────────────┐ + │ nixos-rebuild switch │ + │ (applies both system+home)│ + └───────────┬────────────────┘ + │ + ┌───────────────────┴───────────────────┐ + │ │ + ┌────▼──────────────┐ ┌──────────────▼─────┐ + │ NixOS System │ │ Home Manager │ + │ /etc/nixos/* │ │ ~/.config/* │ + │ Services, kernel │ │ Packages, dotfiles │ + └───────────────────┘ └────────────────────┘ +``` + +### On Non-NixOS System + +``` +┌──────────────────────────────────────┐ +│ flake.nix (homeConfigurations only) │ +└──────────────────┬───────────────────┘ + │ + ┌──────────▼──────────────┐ + │ home/* (user config) │ + └──────────┬───────────────┘ + │ + ┌──────────▼──────────────────┐ + │ home-manager switch --flake │ + └──────────┬───────────────────┘ + │ + ┌──────────▼──────────────────┐ + │ Home Manager │ + │ ~/.config, ~/.local/share │ + │ Packages, dotfiles │ + └────────────────────────────┘ +``` + +## Module Design Pattern + +Each module follows this pattern for maximum flexibility: + +```nix +{ config, lib, pkgs, ... }: + +{ + # 1. Define options (schema) + options.custom.feature = { + enable = lib.mkEnableOption "Feature"; + setting1 = lib.mkOption { /* ... */ }; + }; + + # 2. Conditionally implement + config = let + cfg = config.custom.feature; + in lib.mkIf cfg.enable { + # Implementation here + environment.systemPackages = [ /* ... */ ]; + }; +} +``` + +**Why this pattern:** +- ✅ **Declarative**: Clear what can be configured +- ✅ **Composable**: Modules don't interfere +- ✅ **Overridable**: Host can override any setting +- ✅ **Conditional**: Only included when enabled + +## Separation of Concerns + +### System Level (nixos/) - Run once, affects all users + +- OS-level packages (compilers, tools) +- Services (SSH, web servers) +- Bootloader, kernel, hardware +- User creation and permissions +- Firewall, networking +- System-wide environment variables + +**When to put config here:** +- Affects the entire system +- Required by multiple users +- Needs root/sudo privileges + +### User Level (home/) - Per-user, portable + +- Shell configuration and aliases +- Editor settings and plugins +- User-installed packages +- Dotfiles (~/.config/*) +- Environment variables (user-specific) +- Git, SSH client configuration + +**When to put config here:** +- Only one user needs it +- Doesn't require system privileges +- Configurable per-user +- Want to port to non-NixOS systems + +## Configuration Hierarchy + +Settings are applied in this order (later overrides earlier): + +1. **nixos/default.nix** - Base system defaults +2. **nixos/modules/*.nix** - System feature modules +3. **hosts/hostname/default.nix** - Machine-specific overrides +4. **home/default.nix** - User base defaults +5. **home/modules/*.nix** - User feature modules + +Example with `custom.development.languages`: + +```nix +# Start: undefined + +# nixos/modules/development.nix: +# options.custom.development.languages = lib.mkOption { default = []; ... }; + +# hosts/laptop/default.nix: +custom.development.languages = [ "rust" "python" ]; # Override + +# Result: [ "rust" "python" ] +``` + +## Flakes Architecture + +### Inputs (Dependencies) + +```nix +inputs = { + nixpkgs = "..."; # Stable packages + nixpkgs-unstable = "..."; # Cutting-edge packages + home-manager = "..."; # User config management + sops-nix = "..."; # Secrets management + disko = "..."; # Disk partitioning +}; +``` + +**Why these inputs:** +- **nixpkgs + unstable**: Mix stable (secure) with latest (features) +- **home-manager**: User config separate from system +- **sops-nix**: Encrypted secrets, portable +- **disko**: Declarative disk setup for new machines + +### Outputs (What's available) + +```nix +outputs = { + nixosConfigurations = { + laptop = nixosSystem { ... }; # Full system config + server = nixosSystem { ... }; + }; + homeConfigurations = { + "myuser@linux" = homeManagerConfiguration { ... }; # Standalone HM + }; + devShells = { + default = mkShell { ... }; # Development environment + }; + apps = { + installer = { ... }; # Bootstrap helper + }; +} +``` + +## Secrets Flow + +``` +secrets/ +├── .sops.yaml # Key configuration (WHO can decrypt) +└── secrets.yaml (encrypted) + │ + ├─ SSH keys + ├─ API tokens + └─ Passwords + +When applied: + │ + ▼ +Sops decrypts (using ~/.config/sops/age/keys.txt) + │ + ▼ +sops.secrets.* paths available in Nix + │ + ▼ +Placed in /run/secrets/* at boot + │ + ▼ +Referenced in system/home config +``` + +**Key insight**: Secrets are encrypted on disk, decrypted at boot, never stored in nix store in plaintext. + +## Multi-Machine Scaling + +To support N machines: + +1. Add new host in `hosts/newhost/default.nix` +2. Register in `flake.nix` under `nixosConfigurations.newhost` +3. Deploy with: `sudo nixos-rebuild switch --flake .#newhost` + +Each machine: +- Shares `nixos/` modules +- Shares `home/` modules +- Has unique `hosts/` overrides +- Uses same `secrets.yaml` (all machines can decrypt) + +``` +Common Base Per-Machine Override +───────────── ────────────────── +nixos/default.nix → hosts/laptop/default.nix +nixos/modules/ → (machine-specific features) +home/modules/ → (shared everywhere) +``` + +## Update Strategy + +``` +Stable ← └─ Pinned via flake.lock + │ + ├─ Low risk, predictable + └─ Most system components + +Unstable → Override in modules when needed + │ + ├─ Fast-moving + └─ For specific packages (bleeding edge editor, tools) +``` + +Update process: +```bash +# Pin current state +git commit flake.lock + +# Update specific input +nix flake update nixpkgs + +# Test +sudo nixos-rebuild test --flake .#laptop + +# Deploy +sudo nixos-rebuild switch --flake .#laptop + +# Save new state +git commit flake.lock +``` + +## Extension Points + +### Add Feature: Create a new module + +1. Create `nixos/modules/myfeature.nix` or `home/modules/myfeature.nix` +2. Follow module pattern (options + config) +3. Import in `nixos/default.nix` or `home/default.nix` +4. Enable in host config: `custom.myfeature.enable = true` + +### Add Machine: Copy host template + +1. Create `hosts/newmachine/default.nix` +2. Customize for that machine +3. Add to `flake.nix` under `nixosConfigurations` +4. Deploy with `sudo nixos-rebuild switch --flake .#newmachine` + +### Add Dependency: Update flake inputs + +1. Edit `flake.nix` inputs section +2. Run `nix flake update` +3. Commit `flake.lock` + +### Add Secret: Edit secrets.yaml + +1. Run `sops secrets/secrets.yaml` +2. Add key-value pair +3. Reference in module with `config.sops.secrets."key".path` + +## Testing & Safety + +### Before Deploying + +```bash +nix flake check # Syntax validation +nix flake show # Check all outputs +sudo nixos-rebuild test # Build without activating +``` + +### Rollback if Issues + +```bash +# NixOS (automatic previous generation) +sudo nixos-rebuild --rollback switch + +# Home Manager (manual) +home-manager switch --flake .#myuser@linux ~/.local/state/home-manager/previous +``` + +### Validate Changes + +```bash +# What changed? +sudo nixos-rebuild diff --flake .#laptop + +# What will happen? +sudo nixos-rebuild test --flake .#laptop + +# Apply +sudo nixos-rebuild switch --flake .#laptop +``` + +## Performance Considerations + +- **Flakes**: Slow evaluation (1-2 seconds) but reproducible +- **Modularity**: More files but faster edits +- **Secrets**: Decryption only at boot (fast) +- **Unstable**: More binary cache misses (compilation time) + +## See Also + +- **README.md** - Getting started +- **SETUP.md** - Step-by-step installation +- **QUICKREF.md** - Common commands +- **CUSTOMIZATION.md** - Extension patterns diff --git a/CUSTOMIZATION.md b/CUSTOMIZATION.md new file mode 100644 index 0000000..3fe7d14 --- /dev/null +++ b/CUSTOMIZATION.md @@ -0,0 +1,477 @@ +# Customization Guide + +Advanced customization patterns for your portable NixOS setup. + +## Creating Custom Modules + +### Pattern 1: Language-Specific Development Environment + +Create `nixos/modules/languages/rust.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom.languages.rust.enable = lib.mkEnableOption "Rust development"; + + config = lib.mkIf config.custom.languages.rust.enable { + environment.systemPackages = with pkgs; [ + rustup + cargo-edit + cargo-deny + rust-analyzer + ]; + }; +} +``` + +Use in `hosts/laptop/default.nix`: +```nix +custom.languages.rust.enable = true; +``` + +### Pattern 2: Per-Machine Overrides + +In `nixos/default.nix`: +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom = { + isLaptop = lib.mkOption { type = lib.types.bool; default = false; }; + isServer = lib.mkOption { type = lib.types.bool; default = false; }; + }; + + config = { + # Settings that only apply to laptops + power.powertop.enable = lib.mkIf config.custom.isLaptop true; + services.thermald.enable = lib.mkIf config.custom.isLaptop true; + }; +} +``` + +In `hosts/laptop/default.nix`: +```nix +custom.isLaptop = true; +``` + +### Pattern 3: Conditional Package Sets + +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom.tools.enable = lib.mkEnableOption "Extra tools"; + + config = lib.mkIf config.custom.tools.enable { + environment.systemPackages = with pkgs; [ + # Always included + git + curl + + # Only if GUI is available + (lib.optionals (config.custom.hasGui) [ + firefox + vlc + ]) + + # Only on laptops + (lib.optionals config.custom.isLaptop [ + powertop + upower + ]) + ]; + }; +} +``` + +## Common Customizations + +### Add Docker/Podman Support + +Edit `nixos/modules/development.nix`: + +```nix +virtualisation.podman = { + enable = true; + dockerCompat = true; # Alias docker → podman +}; + +virtualisation.docker.enable = lib.mkDefault false; +``` + +### Add Kubernetes Tools + +In `nixos/modules/development.nix`: + +```nix +languagePackages = { + # ... existing languages + kubernetes = with pkgs; [ kubectl helm kustomize ]; +}; +``` + +Use in host: +```nix +custom.development.languages = [ "rust" "kubernetes" ]; +``` + +### Add Desktop Environment + +Create `nixos/modules/desktop.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom.desktop = { + enable = lib.mkEnableOption "Desktop environment"; + environment = lib.mkOption { + type = lib.types.enum [ "gnome" "kde" "xfce" ]; + default = "gnome"; + }; + }; + + config = let + cfg = config.custom.desktop; + in lib.mkIf cfg.enable { + services.xserver.enable = true; + services.xserver.displayManager.gdm.enable = cfg.environment == "gnome"; + services.xserver.desktopManager.gnome.enable = cfg.environment == "gnome"; + + # Similar for KDE, XFCE... + }; +} +``` + +Use in host: +```nix +custom.desktop.enable = true; +custom.desktop.environment = "gnome"; +``` + +### Add SSH Server + +Edit `nixos/modules/system.nix`: + +```nix +services.openssh = { + enable = lib.mkDefault false; + ports = [ 22 ]; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + }; +}; +``` + +Enable in specific host: +```nix +# hosts/server/default.nix +services.openssh.enable = true; +``` + +### Add Nginx Web Server + +Create `nixos/modules/web.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom.web.enable = lib.mkEnableOption "Web server"; + + config = lib.mkIf config.custom.web.enable { + services.nginx = { + enable = true; + virtualHosts."localhost" = { + listen = [{ addr = "127.0.0.1"; port = 8080; }]; + locations."/".root = "/var/www"; + }; + }; + }; +} +``` + +### Add PostgreSQL Database + +Create `nixos/modules/database.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom.database.postgres.enable = lib.mkEnableOption "PostgreSQL"; + + config = lib.mkIf config.custom.database.postgres.enable { + services.postgresql = { + enable = true; + ensureDatabases = [ "dev" ]; + ensureUsers = [{ + name = "dev"; + ensureDBOwnership = true; + }]; + }; + }; +} +``` + +Enable in host: +```nix +custom.database.postgres.enable = true; +``` + +### Add Docker Containers for Services + +Create `nixos/modules/containers.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + virtualisation.podman.enable = true; + + # Define containers to auto-start + virtualisation.podman.containers = { + redis = { + image = "redis:latest"; + ports = [ "6379:6379" ]; + autoStart = lib.mkDefault false; + }; + }; +} +``` + +## Home Manager Customizations + +### Add Starship Configuration + +Edit `home/modules/shell.nix`: + +```nix +programs.starship = { + enable = true; + settings = { + add_newline = true; + character = { + success_symbol = "[➜](bold green)"; + error_symbol = "[➜](bold red)"; + }; + rust = { + disabled = false; + symbol = "🦀 "; + }; + }; +}; +``` + +### Add Zsh Plugins + +Edit `home/modules/shell.nix`: + +```nix +programs.zsh.plugins = [ + { + name = "zsh-autosuggestions"; + src = pkgs.fetchFromGitHub { /* ... */ }; + } + { + name = "powerlevel10k"; + src = pkgs.fetchFromGitHub { /* ... */ }; + file = "powerlevel10k.zsh-theme"; + } +]; +``` + +### Add VSCode Configuration + +Edit `home/modules/editor.nix`: + +```nix +programs.vscode = { + enable = true; + extensions = with pkgs.vscode-extensions; [ + ms-python.python + rust-lang.rust-analyzer + hashicorp.terraform + ]; + userSettings = { + "editor.fontSize" = 14; + "editor.formatOnSave" = true; + "python.linting.enabled" = true; + }; +}; +``` + +### Add SSH Configuration + +Create `home/modules/ssh.nix`: + +```nix +{ config, pkgs, ... }: + +{ + programs.ssh = { + enable = true; + matchBlocks = { + "github.com" = { + host = "github.com"; + user = "git"; + identityFile = "~/.ssh/github"; + identitiesOnly = true; + }; + "*.example.com" = { + user = "myuser"; + identityFile = "~/.ssh/work"; + forwardAgent = true; + }; + }; + }; +} +``` + +Import in `home/default.nix`: +```nix +imports = [ + ./modules/ssh.nix +]; +``` + +### Add Tmux Configuration + +Edit `home/modules/dev-tools.nix`: + +```nix +programs.tmux = { + enable = true; + mouse = true; + baseIndex = 1; + keyMode = "vi"; + + plugins = with pkgs.tmuxPlugins; [ + sensible + vim-tmux-navigator + resurrect + ]; + + extraConfig = '' + # Custom keybindings + bind -n M-h select-pane -L + bind -n M-j select-pane -D + bind -n M-k select-pane -U + bind -n M-l select-pane -R + ''; +}; +``` + +## Integration Patterns + +### Using Unstable Packages Everywhere + +In `home/modules/editor.nix`, use unstable neovim: + +```nix +{ pkgs, pkgs-unstable, ... }: + +{ + programs.neovim = { + enable = true; + package = pkgs-unstable.neovim; + # ... + }; +} +``` + +### Conditional Configuration Based on Hardware + +In `hosts/laptop/default.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + # Laptop-specific + services.power-profiles-daemon.enable = true; + services.logind.lidSwitchExternalPower = "ignore"; + + # Wireless + networking.wireless.enable = true; + + # Battery + systemd.services.battery-monitor = { + description = "Monitor battery health"; + wantedBy = [ "multi-user.target" ]; + script = "${pkgs.acpi}/bin/acpi"; + }; +} +``` + +### Using Secrets in Home Manager + +In `home/modules/example.nix`: + +```nix +{ config, sops-nix, ... }: + +{ + imports = [ sops-nix.homeManagerModules.sops ]; + + sops.defaultSopsFile = ../../secrets/secrets.yaml; + + sops.secrets."api/myapi" = { + path = "%r/myapi"; # In ~/.config/sops-nix + }; + + # Use in programs + home.sessionVariables.MY_API_KEY = config.sops.secrets."api/myapi".path; +} +``` + +## Testing Changes Safely + +```bash +# Build without applying +home-manager build --flake .#myusername@linux + +# Check what will change +sudo nixos-rebuild test --flake .#laptop # Activates but doesn't add to boot + +# Compare with current +sudo nixos-rebuild diff --flake .#laptop + +# Rollback if something breaks +nixos-rebuild --rollback switch # NixOS +home-manager switch --flake .#myusername@linux ~/.local/state/home-manager/current # HM +``` + +## Performance Optimization + +### Selective Updates + +Update only specific inputs: +```bash +nix flake update nixpkgs +nix flake update home-manager +``` + +### Parallel Builds + +In `flake.nix`, speed up evaluation: +```bash +NIX_BUILD_CORES=4 sudo nixos-rebuild switch --flake .#laptop +``` + +### Binary Cache + +Use nixpkgs binary cache: +```nix +# nixos/default.nix +nix = { + settings = { + substituters = [ "https://cache.nixos.org" ]; + trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypQMvvZN1FSVucqL2mGvhiqHIl8=" ]; + }; +}; +``` + +See QUICKREF.md for common operations reference. diff --git a/INDEX.md b/INDEX.md new file mode 100644 index 0000000..9db1c38 --- /dev/null +++ b/INDEX.md @@ -0,0 +1,225 @@ +# Project Index + +Quick reference to all files and their purposes. + +## Getting Started + +Start here in this order: + +1. **README.md** - Feature overview and quick start +2. **SETUP.md** - Step-by-step installation guide +3. **QUICKREF.md** - Command reference for daily use + +## Documentation + +- **README.md** - Overview, features, directory structure, usage patterns +- **SETUP.md** - Detailed setup from scratch, per-scenario instructions +- **QUICKREF.md** - Command reference, common tasks, one-liners +- **CUSTOMIZATION.md** - Advanced patterns, extension examples +- **ARCHITECTURE.md** - Design principles, data flow, scalability +- **INDEX.md** - This file + +## Configuration Files + +### Core Configuration + +- **flake.nix** - Main entry point + - Defines all inputs (nixpkgs, home-manager, sops-nix, disko) + - Specifies all outputs (nixosConfigurations, homeConfigurations) + - Includes development shell and installer app + - **Requires customization**: Replace `youruser` with actual username + +### Host Configurations (Per-Machine) + +- **hosts/laptop/default.nix** - Laptop configuration template + - Networking hostname + - Disko disk partitioning + - Development tools to enable + - **Requires customization**: Hostname, disk device, language selection + +- **hosts/server/default.nix** - Server configuration template + - Minimal development tools + - Same structure as laptop, customize as needed + +### NixOS System Modules (Shared) + +- **nixos/default.nix** - System configuration entry point + - Imports all modules + - System packages (git, curl, vim, htop) + - Nix settings, garbage collection, locale + - **Touch rarely**: Mostly imports + +- **nixos/modules/system.nix** - System base configuration + - User creation (currently `youruser` - customize) + - Sudo configuration + - System state version + - **Options exposed**: `custom.system.enable` + +- **nixos/modules/development.nix** - Development tools module + - Language-specific packages (rust, python, nodejs, go, ruby) + - Build tools (gcc, cmake, gdb, etc) + - Container support (docker/podman) + - **Options exposed**: `custom.development.enable`, `custom.development.languages` + - **Example**: Set `languages = [ "rust" "python" ]` to install + +- **nixos/modules/shell.nix** - Shell configuration + - Zsh, bash, fish support + - Starship prompt, direnv integration + - **Options exposed**: `custom.shell.enable`, `custom.shell.defaultShell` + +- **nixos/modules/secrets-example.nix** - Secrets integration example + - Shows how to use sops-nix for encrypted secrets + - NOT imported by default + - Uncomment in `nixos/default.nix` to enable + - Reference for managing SSH keys, API tokens, passwords + +- **nixos/modules/example-template.nix** - Template for new modules + - Shows the module pattern: options + config + - Copy and customize for new features + +### Home Manager User Configuration (Portable) + +- **home/default.nix** - User configuration entry point + - Imports all home modules + - Home username, home directory, stateVersion + - User-level packages (utilities, tools) + - Environment variables + - **Requires customization**: Username, email (in git.nix) + +- **home/modules/shell.nix** - Shell environment + - Zsh configuration (autosuggestion, syntax highlighting) + - Shell aliases (ls → exa, cat → bat) + - Starship prompt setup + - Direnv integration for per-project shells + - Zsh-z plugin for directory navigation + +- **home/modules/editor.nix** - Editor configuration + - Neovim as primary editor + - LSP setup (language servers) + - Plugins: telescope, lualine, treesitter, git integration + - Alternative: VSCode (commented out) + - **Note**: Basic config, customize for your needs + +- **home/modules/git.nix** - Git configuration + - Git username, email + - Default branch, pull strategy + - Common aliases (st, co, br, ci) + - **Requires customization**: Your name and email + +- **home/modules/dev-tools.nix** - Development utilities + - Debuggers (lldb, gdb) + - Version managers (fnm, pyenv) + - Build tools (cmake, ninja, meson) + - System utilities (tmux, htop, iotop) + - Container tools (podman, podman-compose) + - Tmux configuration with mouse support and vi keybindings + +- **home/modules/example-template.nix** - Template for new user modules + - Shows home-manager module pattern + - Copy and customize for new user features + +### Secrets Management + +- **secrets/.sops.yaml** - SOPS encryption configuration + - Specifies which keys can decrypt secrets + - Points to your age public key + - **Requires**: Replace placeholder with your actual age public key + +- **secrets/secrets.yaml** - Encrypted secrets file + - SSH keys, API tokens, passwords + - Encrypted with sops (safe to commit) + - **Usage**: Edit with `sops secrets/secrets.yaml` + - **Never**: Commit unencrypted version + +## Build & Deployment + +No separate deployment files needed - everything flows through flake.nix: + +``` +flake.nix + ├─ nixosConfigurations.laptop → Deploy with: sudo nixos-rebuild switch --flake .#laptop + ├─ homeConfigurations.youruser@linux → Deploy with: home-manager switch --flake .#youruser@linux + ├─ devShells.default → Enter with: nix develop + └─ apps.installer → Run with: nix run .#installer -- laptop +``` + +## Support Files + +- **.gitignore** - Prevents committing secrets, temp files, nix artifacts +- **flake.lock** - COMMIT THIS: Pins all dependencies for reproducibility + +## Quick Navigation + +### "I want to..." + +| Task | File | Line | Command | +|------|------|------|---------| +| **Change my hostname** | hosts/laptop/default.nix | 8 | `sed -i 's/laptop/myname/' ...` | +| **Change my username** | flake.nix | ~40, 70 | Global replace: `"youruser"` | +| **Add a programming language** | hosts/laptop/default.nix | 35 | Add to `languages = [...]` | +| **Install new system package** | nixos/default.nix | 14 | Add to `systemPackages` | +| **Install new user package** | home/default.nix | 16 | Add to `home.packages` | +| **Change default shell** | nixos/modules/shell.nix | 11 | Change `defaultShell = "fish"` | +| **Add SSH key to secrets** | secrets/secrets.yaml | 8 | `sops secrets/secrets.yaml` | +| **Use unstable package** | home/modules/dev-tools.nix | varies | Use `pkgs-unstable.package` | +| **Create a new module** | nixos/modules/example-template.nix | — | Copy template, customize | +| **Add a new machine** | hosts/ | — | `mkdir newhost && cp laptop/* newhost/` | + +## File Customization Checklist + +On first setup, customize these: + +- [ ] **flake.nix** - Replace all `youruser` (3 locations) +- [ ] **hosts/laptop/default.nix** - Set `networking.hostName`, verify `/dev/sda` disk +- [ ] **home/default.nix** - Set `home.username` +- [ ] **home/modules/git.nix** - Set `userName` and `userEmail` +- [ ] **secrets/.sops.yaml** - Add your age public key +- [ ] **secrets/secrets.yaml** - Add actual SSH keys and API tokens + +## File Statistics + +- **Documentation**: 6 files (README, SETUP, QUICKREF, CUSTOMIZATION, ARCHITECTURE, INDEX) +- **Configuration**: 1 core file (flake.nix) +- **System modules**: 5 files (default, system, development, shell, secrets-example) +- **Home modules**: 6 files (default, shell, editor, git, dev-tools, example-template) +- **Hosts**: 2 example files (laptop, server) +- **Secrets**: 2 files (.sops.yaml, secrets.yaml) +- **Support**: 2 files (.gitignore, flake.lock) + +Total: ~24 files, all under 500 lines each + +## Update Schedule + +### When to update inputs + +```bash +# Monthly (security patches) +nix flake update nixpkgs +sudo nixos-rebuild switch --flake .#laptop + +# Less frequently (minor version bumps) +nix flake update + +# Test before committing +nix flake check +sudo nixos-rebuild test --flake .#laptop +``` + +### When to add modules + +Add modules when: +- Feature can be enabled/disabled independently +- Reused across multiple machines +- Follows the options + config pattern + +## Related Resources + +- NixOS Manual: https://nixos.org/manual/nixos/stable +- Home Manager: https://nix-community.github.io/home-manager +- Nix Flakes: https://nix.dev/manual/nix/latest/command-ref/new-cli/nix3-flake +- sops-nix: https://github.com/mic92/sops-nix +- Disko: https://github.com/nix-community/disko + +--- + +**Next Step**: Read README.md for a feature overview, then SETUP.md for installation instructions. diff --git a/QUICKREF.md b/QUICKREF.md new file mode 100644 index 0000000..c16786a --- /dev/null +++ b/QUICKREF.md @@ -0,0 +1,141 @@ +# Quick Reference + +Common commands and patterns for your portable NixOS setup. + +## Deployment + +| Action | Command | +|--------|---------| +| **Rebuild NixOS** | `sudo nixos-rebuild switch --flake .#laptop` | +| **Rebuild Home** | `home-manager switch --flake .#myusername@linux` | +| **Both** | `sudo nixos-rebuild switch --flake .#laptop` + `home-manager switch --flake .#myusername@linux` | +| **Test (no apply)** | `sudo nixos-rebuild test --flake .#laptop` | +| **Activate Home (test)** | `home-manager build --flake .#myusername@linux` | +| **Check validity** | `nix flake check` | +| **Show outputs** | `nix flake show` | +| **Update inputs** | `nix flake update` | +| **Update one input** | `nix flake update nixpkgs` | + +## Secrets + +| Action | Command | +|--------|---------| +| **Generate age key** | `age-keygen -o -f ~/.config/sops/age/keys.txt` | +| **Get public key** | `age-keygen -y ~/.config/sops/age/keys.txt` | +| **Edit secrets** | `sops secrets/secrets.yaml` | +| **View secrets** | `sops -d secrets/secrets.yaml` | +| **Re-encrypt after .sops.yaml change** | `sops -e secrets/secrets.yaml > temp && mv temp secrets/secrets.yaml` | + +## Development + +| Action | Command | +|--------|---------| +| **Enter dev shell** | `nix develop` | +| **Format Nix files** | `nixpkgs-fmt .` | +| **Check for syntax errors** | `nix flake check` | +| **Evaluate flake** | `nix eval .#` | +| **Get derivation path** | `nix derivation show .#youruser@linux` | + +## Utilities + +| Action | Command | +|--------|---------| +| **List installed packages** | `nix-store -q --requisites /run/current-system` | +| **Find broken symlinks** | `nix store gc --print-roots` | +| **Clear old generations** | `sudo nix-collect-garbage -d` | +| **Clear user generations** | `nix-collect-garbage -d` | +| **Check disk usage** | `du -sh /nix` | + +## Files to Edit for Common Tasks + +| Task | File | +|------|------| +| **Change hostname** | `hosts/laptop/default.nix` (networking.hostName) | +| **Add system packages** | `nixos/default.nix` | +| **Add user packages** | `home/default.nix` | +| **Change shell** | `nixos/modules/shell.nix` (custom.shell.defaultShell) | +| **Enable languages** | `hosts/laptop/default.nix` (custom.development.languages) | +| **Add Git config** | `home/modules/git.nix` | +| **Customize Neovim** | `home/modules/editor.nix` | +| **Add SSH keys** | `secrets/secrets.yaml` (encrypted) | +| **Change username** | `flake.nix`, `home/default.nix`, `nixos/modules/system.nix` | + +## Enable Features by Module + +```bash +# Edit hosts/laptop/default.nix: + +# Development tools +custom.development.enable = true; +custom.development.languages = [ "rust" "python" "nodejs" "go" "ruby" ]; + +# Shell setup +custom.shell.enable = true; +custom.shell.defaultShell = "zsh"; # or bash, fish + +# System module +custom.system.enable = true; +``` + +## Debugging + +| Problem | Solution | +|---------|----------| +| **Can't find package** | Check nixpkgs: `nix search nixpkgs mycpackage` | +| **Module import error** | Check imports in default.nix: `nix flake check` | +| **Config won't build** | Get detailed error: `nix flake show 2>&1 \| tail -50` | +| **Secrets not decrypting** | Verify: `sops -d secrets/secrets.yaml` | +| **Home-manager conflicts** | Backup old config: `mv ~/.bashrc ~/.bashrc.bak` | +| **Stuck rebuild** | Kill and retry: `sudo killall nixos-rebuild` | + +## Git Workflow + +```bash +# After making changes: +git add -A +git commit -m "Update: description" +git push + +# On another machine: +git pull +sudo nixos-rebuild switch --flake .#laptop +``` + +## Multi-Machine Example + +```bash +# Add new host +mkdir -p hosts/workstation +cp hosts/laptop/default.nix hosts/workstation/default.nix + +# Add to flake.nix (copy laptop configuration block and update names) + +# Deploy to new machine +sudo nixos-rebuild switch --flake .#workstation +``` + +## One-Liner Installers + +```bash +# Fresh NixOS to existing machine +git clone ~/nix-config && cd ~/nix-config && sudo nixos-rebuild switch --flake .#laptop + +# Home manager on non-NixOS +curl https://nixos.org/channels/nixos-unstable/latest-nixos-*-linux/default.nix && \ + nix run home-manager -- init --switch --flake .#myusername@linux + +# Update everything +nix flake update && sudo nixos-rebuild switch --flake .#laptop && \ + home-manager switch --flake .#myusername@linux +``` + +## Tips + +- ✅ Always commit `flake.lock` for reproducibility +- ✅ Use `lib.mkDefault` for overridable settings +- ✅ Keep secrets encrypted with sops +- ✅ Test with `test` before `switch` +- ✅ Use `--build-on-remote` for slower machines +- ✅ Check `flake check` before rebuilding +- ✅ Keep separate host configs for different machines +- ✅ Use `home-manager generations` to rollback if needed diff --git a/README.md b/README.md new file mode 100644 index 0000000..a271dc3 --- /dev/null +++ b/README.md @@ -0,0 +1,269 @@ +# Portable NixOS Configuration + +A production-ready, modular NixOS + Home Manager setup with automatic disk partitioning, secrets management, and support for both new and existing systems. + +## Features + +- ✅ **Modular**: Configure system and home separately or together +- ✅ **Portable**: Works on new machines, existing NixOS, or non-NixOS (home-manager only) +- ✅ **Auto-partitioning**: Disko handles disk setup automatically +- ✅ **Secrets**: sops-nix for encrypted, portable secrets +- ✅ **Unstable packages**: Mix stable and unstable nixpkgs +- ✅ **Single command**: Deploy entire system with one command + +## Directory Structure + +``` +nix-config/ +├── flake.nix # Main entry point (inputs + outputs) +├── flake.lock # Pinned versions +├── hosts/ # Per-machine configs +│ ├── laptop/default.nix # Machine-specific settings +│ └── server/default.nix +├── nixos/ # Shared NixOS modules +│ ├── default.nix +│ └── modules/ +│ ├── system.nix # User creation, sudo +│ ├── development.nix # Languages, tools +│ └── shell.nix # Shell config +├── home/ # Shared Home Manager modules +│ ├── default.nix +│ └── modules/ +│ ├── shell.nix # Zsh + direnv +│ ├── editor.nix # Neovim/VSCode +│ ├── git.nix # Git config +│ └── dev-tools.nix # tmux, etc +├── secrets/ +│ ├── .sops.yaml # Encryption config +│ └── secrets.yaml # Encrypted secrets +└── README.md +``` + +## Quick Start + +### 1. Initial Setup + +```bash +# Clone repository +git clone nix-config +cd nix-config + +# Generate age keypair (one-time) +age-keygen -o -f ~/.config/sops/age/keys.txt + +# Update .sops.yaml with your public key +age-keygen -y ~/.config/sops/age/keys.txt +# Copy the output and update secrets/.sops.yaml +``` + +### 2. Personalize Your Config + +Edit these files to match your setup: + +**flake.nix:** +- Change `youruser` to your actual username (3 places) + +**hosts/laptop/default.nix:** +- Set `networking.hostName` +- Verify disk device (change `/dev/sda` if needed) + +**home/default.nix & home/modules/git.nix:** +- Set your username and email +- Customize home packages + +**secrets/secrets.yaml:** +- Add your SSH keys, API tokens, passwords + +### 3. Deploy to Existing NixOS + +```bash +# Rebuild the entire system +sudo nixos-rebuild switch --flake .#laptop + +# Or, just update home-manager +home-manager switch --flake .#youruser@linux +``` + +### 4. Deploy to New Machine (ISO Install) + +```bash +# Boot NixOS live ISO, then: +# (Option A) Manual installation +sudo nix run github:nix-community/disko -- --mode zap --flake .#laptop + +# (Option B) Automated with nixos-anywhere (from another machine) +nix run github:nix-community/nixos-anywhere -- --flake .#laptop root@192.168.1.100 + +# (Option C) One-liner installer +nix run .#installer -- laptop +``` + +### 5. Non-NixOS Machine (Home Manager Only) + +```bash +# Install home-manager and apply config +home-manager switch --flake .#youruser@linux + +# Or use the installer script +nix run .#installer -- laptop +``` + +## Usage Patterns + +### Rebuild After Changes + +```bash +# System + home +sudo nixos-rebuild switch --flake .#laptop + +# Just home-manager +home-manager switch --flake .#youruser@linux + +# Dry-run to see what changes +sudo nixos-rebuild test --flake .#laptop +``` + +### Manage Secrets + +```bash +# Edit encrypted secrets (requires age key) +sops secrets/secrets.yaml + +# Reference in NixOS config: +# sops.secrets."ssh/github_key".owner = "youruser"; +# sops.secrets."ssh/github_key".path = "/home/youruser/.ssh/github_key"; + +# Access in shell: +# cat ${config.sops.secrets."ssh/github_key".path} +``` + +### Enable/Disable Features + +Edit host config (e.g., `hosts/laptop/default.nix`): + +```nix +# Enable development tools for specific languages +custom.development.enable = true; +custom.development.languages = [ "rust" "python" "nodejs" ]; + +# Disable specific modules +custom.shell.enable = false; +``` + +### Add New Modules + +Create `nixos/modules/myfeature.nix`: + +```nix +{ config, lib, pkgs, ... }: + +{ + options.custom.myfeature = { + enable = lib.mkEnableOption "My feature"; + }; + + config = lib.mkIf config.custom.myfeature.enable { + # Your config here + }; +} +``` + +Then import in `nixos/default.nix`: +```nix +imports = [ ./modules/myfeature.nix ]; +``` + +### Development Shell + +```bash +# Load dev environment +nix flake show + +# Enter dev shell with all tools +nix develop +``` + +## Multi-Machine Setup + +To support multiple machines: + +1. Create new host: +```bash +mkdir -p hosts/newhost +cp hosts/laptop/default.nix hosts/newhost/default.nix +``` + +2. Edit `flake.nix` and add: +```nix +newhost = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { inherit sops-nix disko; pkgs-unstable = pkgs-unstable; }; + modules = [ + overlayUnstable + sops-nix.nixosModules.sops + disko.nixosModules.disko + ./hosts/newhost/default.nix + ./nixos/default.nix + home-manager.nixosModules.home-manager + { home-manager.users.youruser = import ./home/default.nix; } + ]; +}; +``` + +3. Deploy: +```bash +sudo nixos-rebuild switch --flake .#newhost +``` + +## Troubleshooting + +### Secrets decryption fails +```bash +# Check your age key exists +ls ~/.config/sops/age/keys.txt + +# Verify sops config +sops -d secrets/secrets.yaml + +# Regenerate .sops.yaml with your key +age-keygen -y ~/.config/sops/age/keys.txt +``` + +### Disko disk errors +```bash +# List available disks +lsblk + +# Manually run disko (test mode) +sudo nix run github:nix-community/disko -- --mode doit --flake .#laptop +``` + +### Home-manager import errors +```bash +# Check flake validity +nix flake check + +# Validate syntax +nix flake show +``` + +## Resources + +- [NixOS Manual](https://nixos.org/manual/nixos/stable/) +- [Home Manager](https://nix-community.github.io/home-manager/) +- [sops-nix Documentation](https://github.com/mic92/sops-nix) +- [disko](https://github.com/nix-community/disko) +- [Flakes Guide](https://nix.dev/manual/nix/latest/command-ref/new-cli/nix3-flake.html) + +## Tips for Portability + +1. **Keep secrets encrypted**: Always use sops, never commit plain text secrets +2. **Machine-specific overrides**: Use `lib.mkDefault` in shared modules +3. **Conditionally enable features**: Use `options` + `config = mkIf cfg.enable` +4. **Test before deploying**: Use `nixos-rebuild test` or `home-manager build` +5. **Version your flake**: Commit `flake.lock` for reproducibility +6. **Separate concerns**: System settings → nixos/, User env → home/ + +## License + +MIT diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 0000000..1d13a2d --- /dev/null +++ b/SETUP.md @@ -0,0 +1,364 @@ +# Setup Guide - Step by Step + +This guide walks you through setting up your portable NixOS configuration from scratch. + +## Prerequisites + +- **For new NixOS machines**: NixOS ISO boot media +- **For existing NixOS**: SSH access or local terminal +- **For non-NixOS**: curl, bash + +## Phase 1: Initialize Secrets (One-time) + +### Generate Your Age Key + +```bash +# Create age directory +mkdir -p ~/.config/sops/age + +# Generate keypair +age-keygen -o -f ~/.config/sops/age/keys.txt + +# Extract public key +age-keygen -y ~/.config/sops/age/keys.txt +# Output: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + +### Update Encryption Config + +Edit `secrets/.sops.yaml`: + +```yaml +keys: + - &users | + - -----BEGIN AGE PUBLIC KEY----- + age1YOUR_KEY_HERE_FROM_ABOVE + -----END AGE PUBLIC KEY----- +``` + +### Encrypt Your Secrets + +```bash +# First install sops and age +nix shell nixpkgs#sops nixpkgs#age + +# Edit secrets +sops secrets/secrets.yaml + +# Add your SSH keys, API keys, etc. +# File will be encrypted automatically on save +``` + +## Phase 2: Personalize Configuration + +### Step 1: Update flake.nix + +Replace `youruser` with your actual username: + +```bash +sed -i 's/youruser/myusername/g' flake.nix +sed -i 's/youruser/myusername/g' home/default.nix +``` + +### Step 2: Configure Your Laptop Host + +Edit `hosts/laptop/default.nix`: + +```nix +{ + networking.hostName = "mylaptop"; # Change this + + disko.devices = { + disk.main = { + type = "disk"; + device = "/dev/sda"; # Run 'lsblk' to find your disk + + # For NVMe: device = "/dev/nvme0n1"; + # For SATA: device = "/dev/sda"; + # For RAID: add multiple disks + }; + # ... rest stays the same + }; + + # Enable tools you want + custom.development.enable = true; + custom.development.languages = [ "rust" "python" "nodejs" ]; +} +``` + +### Step 3: Customize Home Configuration + +Edit `home/default.nix`: + +```nix +home.username = "myusername"; # Match your username +home.homeDirectory = "/home/myusername"; +``` + +Edit `home/modules/git.nix`: + +```nix +programs.git = { + enable = true; + userName = "Your Real Name"; + userEmail = "you@example.com"; + # ... rest of config +}; +``` + +## Phase 3: Deploy Strategy Based on Your Situation + +### Scenario A: Deploying to Existing NixOS + +```bash +# 1. Clone repo to your home directory +git clone ~/nix-config +cd ~/nix-config + +# 2. Test the configuration (dry-run) +sudo nixos-rebuild test --flake .#laptop + +# 3. If tests pass, apply the configuration +sudo nixos-rebuild switch --flake .#laptop + +# 4. Also apply home-manager +home-manager switch --flake .#myusername@linux +``` + +### Scenario B: Fresh NixOS Installation (with Auto-Partitioning) + +**On a machine running the NixOS ISO:** + +```bash +# 1. Boot NixOS live ISO +# 2. Connect to network (if needed) +# 3. Clone the repo (copy files via USB or git clone) + +nix flake update # Update to latest packages + +# Option 1: Use disko directly +sudo nix run github:nix-community/disko -- \ + --mode zap \ + --flake .#laptop + +# Option 2: Use nixos-anywhere from another machine +nix run github:nix-community/nixos-anywhere -- \ + --flake .#laptop \ + --build-on-remote \ + root@ + +# Option 3: Manual installation +# 1. Partition disk manually: `sudo fdisk /dev/sda` +# 2. Mount partitions: `sudo mount /dev/sda2 /mnt && sudo mount /dev/sda1 /mnt/boot` +# 3. Generate initial config: `sudo nixos-generate-config --root /mnt` +# 4. Copy your flake.nix to /mnt/etc/nixos/flake.nix +# 5. Install: `sudo nixos-install --flake .#laptop` +``` + +### Scenario C: Non-NixOS Machine (Linux/macOS) + +```bash +# 1. Install nix (if not present) +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \ + sh -s -- install + +# 2. Clone and apply home-manager +git clone ~/nix-config +cd ~/nix-config + +# 3. Install home-manager +nix run home-manager/release-24.11 -- init --switch + +# 4. Apply your config +home-manager switch --flake .#myusername@linux +``` + +## Phase 4: Verify Everything Works + +```bash +# Check flake validity +nix flake check + +# Inspect what will be built +nix flake show + +# Check secrets decryption (if using sops) +sops -d secrets/secrets.yaml + +# Verify home-manager config +home-manager packages 2>&1 | head -20 + +# Verify NixOS config (on NixOS machines) +sudo nixos-option system.nixos.version +``` + +## Phase 5: Enable Advanced Features (Optional) + +### Using Unstable Packages + +In any module, use unstable versions: + +```nix +# In home/modules/dev-tools.nix +home.packages = with pkgs; [ + stable_package + pkgs-unstable.latest_package +]; +``` + +### Adding Secrets to NixOS Config + +Create `nixos/modules/secrets.nix`: + +```nix +{ config, sops-nix, ... }: + +{ + imports = [ sops-nix.nixosModules.sops ]; + + sops.defaultSopsFile = ./secrets/secrets.yaml; + sops.age.keyFile = "/home/youruser/.config/sops/age/keys.txt"; + + sops.secrets."ssh/github_key" = { + owner = "youruser"; + group = "users"; + mode = "0600"; + }; + + # Use in config: + # environment.variables.GITHUB_SSH_KEY = "${config.sops.secrets."ssh/github_key".path}"; +} +``` + +### Custom Per-Language Development Shells + +Create `.envrc`: + +```bash +use flake + +# Per-project overrides +layout python +``` + +Then: + +```bash +direnv allow +``` + +## Common Customizations + +### Add a New Programming Language + +Edit `hosts/laptop/default.nix`: + +```nix +custom.development.languages = [ "rust" "python" "nodejs" "go" ]; +``` + +Supported: `rust`, `python`, `nodejs`, `go`, `ruby` (in `nixos/modules/development.nix`) + +### Change Default Shell + +Edit `nixos/modules/shell.nix`: + +```nix +custom.shell.defaultShell = "fish"; # or "bash" +``` + +### Add System Packages + +Edit `nixos/default.nix`: + +```nix +environment.systemPackages = with pkgs; [ + # ... existing packages + mynewtool +]; +``` + +### Add User Home Packages + +Edit `home/default.nix`: + +```nix +home.packages = with pkgs; [ + # ... existing packages + mynewtool +]; +``` + +## Rebuilding After Changes + +```bash +# After modifying any config: + +# 1. Check for syntax errors +nix flake check + +# 2. Test without committing +sudo nixos-rebuild test --flake .#laptop + +# 3. If happy, switch to new config +sudo nixos-rebuild switch --flake .#laptop + +# 4. Update lockfile with latest packages +nix flake update + +# 5. Commit changes +git add -A +git commit -m "Update: " +``` + +## Troubleshooting + +### "Bad substituter" errors + +```bash +# Clear cache +nix store gc + +# Update flake +nix flake update + +# Rebuild +sudo nixos-rebuild switch --flake .#laptop +``` + +### Secrets not decrypting + +```bash +# Verify key exists +ls ~/.config/sops/age/keys.txt + +# Check sops can find the key +sops -d secrets/secrets.yaml + +# Verify .sops.yaml has correct key +cat secrets/.sops.yaml +``` + +### Home-manager conflicts with existing config + +```bash +# Move old config +mv ~/.bashrc ~/.bashrc.bak +mv ~/.zshrc ~/.zshrc.bak + +# Apply home-manager +home-manager switch --flake .#myusername@linux + +# Merge manually if needed +cat ~/.bashrc.bak >> ~/.bashrc +``` + +## Next Steps + +1. **Commit to git**: Version your config +2. **Add to GitHub**: Make it portable between machines +3. **Customize modules**: Create your own in `nixos/modules/` +4. **Backup secrets**: Safely store your age key +5. **Document changes**: Update README as you customize + +See README.md for advanced usage patterns. diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..3fb8695 --- /dev/null +++ b/flake.nix @@ -0,0 +1,203 @@ +{ + description = "Portable NixOS + Home Manager configuration with sops secrets and disko"; + + inputs = { + # Core + nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; + + # Flakes + flake-utils.url = "github:numtide/flake-utils"; + + # Home Manager + home-manager = { + url = "github:nix-community/home-manager/release-24.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Secrets management + sops-nix = { + url = "github:mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Disk partitioning + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, nixpkgs-unstable, flake-utils, home-manager, sops-nix, disko }: + let + system = "x86_64-linux"; + + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + + pkgs-unstable = import nixpkgs-unstable { + inherit system; + config.allowUnfree = true; + }; + + # Utility to overlay unstable packages + overlayUnstable = final: prev: { + unstable = pkgs-unstable; + }; + + in { + + # ============================================ + # NixOS System Configurations + # ============================================ + + nixosConfigurations = { + + # Example: Laptop configuration + laptop = nixpkgs.lib.nixosSystem { + inherit system; + + specialArgs = { + inherit sops-nix disko; + pkgs-unstable = pkgs-unstable; + }; + + modules = [ + overlayUnstable + sops-nix.nixosModules.sops + disko.nixosModules.disko + + # Machine-specific config + ./hosts/laptop/default.nix + + # Shared system modules + ./nixos/default.nix + + # Home Manager integration + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.extraSpecialArgs = { + inherit sops-nix pkgs-unstable; + }; + home-manager.users.youruser = import ./home/default.nix; + } + ]; + }; + + # Example: Server configuration + server = nixpkgs.lib.nixosSystem { + inherit system; + + specialArgs = { + inherit sops-nix disko; + pkgs-unstable = pkgs-unstable; + }; + + modules = [ + overlayUnstable + sops-nix.nixosModules.sops + disko.nixosModules.disko + + ./hosts/server/default.nix + ./nixos/default.nix + + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.extraSpecialArgs = { + inherit sops-nix pkgs-unstable; + }; + home-manager.users.youruser = import ./home/default.nix; + } + ]; + }; + }; + + # ============================================ + # Home Manager Standalone (Non-NixOS systems) + # ============================================ + + homeConfigurations = { + "youruser@linux" = home-manager.lib.homeManagerConfiguration { + inherit pkgs; + extraSpecialArgs = { + pkgs-unstable = pkgs-unstable; + sops-nix = sops-nix; + }; + modules = [ + overlayUnstable + ./home/default.nix + ]; + }; + }; + + # ============================================ + # Development Shell + # ============================================ + + devShells.${system}.default = pkgs.mkShell { + buildInputs = with pkgs; [ + nix + nixpkgs-fmt + sops + age + disko + git + ]; + + shellHook = '' + echo "🔧 NixOS Configuration Development Shell" + echo "Available commands:" + echo " - nix flake check # Check flake validity" + echo " - nix flake show # Show all outputs" + echo " - sudo nixos-rebuild switch --flake .#hostname" + echo " - home-manager switch --flake .#youruser@linux" + echo " - sops secrets/secrets.yaml # Edit encrypted secrets" + ''; + }; + + # ============================================ + # Installer Script + # ============================================ + + apps.${system}.installer = { + type = "app"; + program = toString (pkgs.writeShellScript "installer" '' + set -e + + if [ -z "$1" ]; then + echo "Usage: nix run .#installer -- " + echo "Example: nix run .#installer -- laptop" + exit 1 + fi + + HOSTNAME=$1 + + echo "🚀 Bootstrapping NixOS: $HOSTNAME" + + # Check if on NixOS + if [ -f /etc/os-release ]; then + . /etc/os-release + if [ "$ID" = "nixos" ]; then + echo "✓ Running on NixOS" + sudo nixos-rebuild switch --flake ".#$HOSTNAME" + echo "✓ NixOS system configured" + else + echo "⚠ Not on NixOS - installing home-manager only" + home-manager switch --flake ".#youruser@linux" + echo "✓ Home manager configured" + fi + else + echo "⚠ Cannot determine OS" + exit 1 + fi + ''); + }; + + }; +} diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..da893ef --- /dev/null +++ b/home/default.nix @@ -0,0 +1,48 @@ +{ config, lib, pkgs, pkgs-unstable, ... }: + +{ + imports = [ + ./modules/shell.nix + ./modules/editor.nix + ./modules/git.nix + ./modules/dev-tools.nix + ]; + + # ============================================ + # Home Manager Shared Configuration + # ============================================ + + home.username = "youruser"; + home.homeDirectory = "/home/youruser"; + home.stateVersion = "24.11"; + + # Home-level packages + home.packages = with pkgs; [ + # Utilities + tree + unzip + zip + fzf + bat + exa + tldr + + # Unstable packages (if needed) + # pkgs-unstable.some-package + ]; + + # Environment variables + home.sessionVariables = { + EDITOR = "vim"; + PAGER = "less"; + }; + + # Home Manager should manage itself + programs.home-manager.enable = true; + + # Locale + home.language = { + base = "en_US.UTF-8"; + }; + +} diff --git a/home/modules/dev-tools.nix b/home/modules/dev-tools.nix new file mode 100644 index 0000000..b0f7e0a --- /dev/null +++ b/home/modules/dev-tools.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, pkgs-unstable, ... }: + +{ + # Development tools at user level + home.packages = with pkgs; [ + # Debuggers + lldb + gdb + + # Version managers + fnm # Node version manager + pyenv # Python version manager + + # Build tools + cmake + ninja + meson + + # System tools + tmux + htop + iotop + + # Container tools + podman + podman-compose + + # Cloud/Infrastructure + # terraform + # kubectl + # helm + + # Testing + # pytest # Python + # jest # JavaScript (via npm) + ]; + + # tmux configuration (optional) + programs.tmux = { + enable = true; + baseIndex = 1; + newSessionPath = "$HOME"; + shortcut = "a"; + + extraConfig = '' + # Enable mouse + set -g mouse on + + # Vi-like navigation + setw -g mode-keys vi + ''; + }; + +} diff --git a/home/modules/editor.nix b/home/modules/editor.nix new file mode 100644 index 0000000..aa4b6c3 --- /dev/null +++ b/home/modules/editor.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, pkgs-unstable, ... }: + +{ + # Neovim as primary editor + programs.neovim = { + enable = true; + defaultEditor = true; + + extraPackages = with pkgs; [ + ripgrep + fd + tree-sitter + ]; + + # Minimal LSP setup - expand as needed + plugins = with pkgs.vimPlugins; [ + # essentials + nvim-lspconfig + nvim-cmp + cmp-nvim-lsp + luasnip + friendly-snippets + + # ui improvements + telescope-nvim + telescope-fzf-native-nvim + lualine-nvim + nvim-web-devicons + nvim-tree-lua + + # treesitter + nvim-treesitter + nvim-treesitter-context + + # git integration + gitsigns-nvim + vim-fugitive + ]; + + # Basic init.lua configuration + extraConfig = '' + lua << EOF + -- Basic settings + vim.opt.number = true + vim.opt.relativenumber = true + vim.opt.expandtab = true + vim.opt.shiftwidth = 2 + vim.opt.tabstop = 2 + vim.opt.smartindent = true + + -- LSP + local lspconfig = require('lspconfig') + + -- Python + lspconfig.pyright.setup{} + + -- Rust + lspconfig.rust_analyzer.setup{} + + -- Node/JavaScript + lspconfig.ts_ls.setup{} + EOF + ''; + }; + + # Alternative: VS Code (uncomment if preferred) + # programs.vscode.enable = true; + +} diff --git a/home/modules/example-template.nix b/home/modules/example-template.nix new file mode 100644 index 0000000..e9c66fa --- /dev/null +++ b/home/modules/example-template.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: + +# Template for creating new Home Manager modules +# Copy this file and customize for your needs + +{ + options.programs.myapp = { + enable = lib.mkEnableOption "My application"; + + setting1 = lib.mkOption { + type = lib.types.str; + default = "default"; + description = "A configuration setting"; + }; + }; + + config = let + cfg = config.programs.myapp; + in lib.mkIf cfg.enable { + + # Home packages needed for this app + home.packages = with pkgs; [ + # myapp + ]; + + # Home Manager built-in programs and services + # Example: configure a program via home-manager + # programs.neovim.enable = true; + + # Create custom files in home directory + # home.file.".config/myapp/config.yaml".source = ./config.yaml; + + # Set environment variables + # home.sessionVariables = { + # MY_VAR = "value"; + # }; + + }; + +} + +# How to use this module: +# +# 1. Save this template as home/modules/myapp.nix +# +# 2. Import it in home/default.nix: +# imports = [ +# ./modules/myapp.nix +# ]; +# +# 3. Enable in home/default.nix: +# programs.myapp.enable = true; +# programs.myapp.setting1 = "custom value"; +# +# 4. Rebuild: +# home-manager switch --flake .#myusername@linux diff --git a/home/modules/git.nix b/home/modules/git.nix new file mode 100644 index 0000000..bfbdc61 --- /dev/null +++ b/home/modules/git.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +{ + programs.git = { + enable = true; + userName = "Your Name"; # TODO: Customize + userEmail = "your.email@example.com"; # TODO: Customize + + extraConfig = { + init.defaultBranch = "main"; + pull.rebase = true; + rebase.autoStash = true; + }; + + aliases = { + st = "status"; + co = "checkout"; + br = "branch"; + ci = "commit"; + unstage = "reset HEAD --"; + last = "log -1 HEAD"; + visual = "log --graph --oneline --all"; + }; + }; + + # GPG key signing (optional, uncomment if using) + # programs.gpg.enable = true; + # services.gpg-agent.enable = true; + +} diff --git a/home/modules/shell.nix b/home/modules/shell.nix new file mode 100644 index 0000000..aacf1aa --- /dev/null +++ b/home/modules/shell.nix @@ -0,0 +1,40 @@ +{ config, lib, pkgs, ... }: + +{ + programs.zsh = { + enable = true; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; + + initExtra = '' + # Custom shell initialization + eval "$(direnv hook zsh)" + eval "$(starship init zsh)" + ''; + + shellAliases = { + ls = "exa -l"; + la = "exa -la"; + tree = "exa --tree"; + cat = "bat"; + cd = "z"; + }; + + plugins = [ + { + name = "z"; + src = pkgs.fetchFromGitHub { + owner = "agkozak"; + repo = "zsh-z"; + rev = "v1.12.0"; + sha256 = "sha256-z7YhKUpn6uEEGT1iFSBpUG+w0D1M9YsvvZW8PwDh8T8="; + }; + } + ]; + }; + + programs.starship.enable = true; + programs.direnv.enable = true; + programs.direnv.nix-direnv.enable = true; + +} diff --git a/hosts/laptop/default.nix b/hosts/laptop/default.nix new file mode 100644 index 0000000..5c99a9c --- /dev/null +++ b/hosts/laptop/default.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, disko, sops-nix, ... }: + +{ + imports = [ + disko.nixosModules.disko + ]; + + # ============================================ + # Machine-Specific Configuration + # ============================================ + + networking.hostName = "laptop"; + networking.domain = ""; + + # Disko: Auto-partitioning configuration + # Customize for your disk layout (example: single SSD) + disko.devices = { + disk.main = { + type = "disk"; + device = "/dev/sda"; # Change to your disk + content = { + type = "gpt"; + partitions = { + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + + # Bootloader + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Hardware: auto-detect + hardware.enableAllFirmware = true; + + # Enable features specific to development + custom.development.enable = true; + custom.development.languages = [ "rust" "python" "nodejs" ]; + +} diff --git a/hosts/server/default.nix b/hosts/server/default.nix new file mode 100644 index 0000000..c6443d5 --- /dev/null +++ b/hosts/server/default.nix @@ -0,0 +1,53 @@ +{ config, lib, pkgs, disko, sops-nix, ... }: + +{ + imports = [ + disko.nixosModules.disko + ]; + + # ============================================ + # Server-Specific Configuration + # ============================================ + + networking.hostName = "server"; + networking.domain = ""; + + # Disko: Server disk layout (example: mirror for RAID) + disko.devices = { + disk.main = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + + # Bootloader + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Minimal development on servers + custom.development.enable = true; + custom.development.languages = [ "python" ]; + +} diff --git a/nixos/default.nix b/nixos/default.nix new file mode 100644 index 0000000..087bfc1 --- /dev/null +++ b/nixos/default.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, pkgs-unstable, ... }: + +{ + imports = [ + ./modules/system.nix + ./modules/development.nix + ./modules/shell.nix + ]; + + # ============================================ + # Shared NixOS Configuration + # ============================================ + + # System packages available to all users + environment.systemPackages = with pkgs; [ + git + curl + wget + vim + htop + ]; + + # Nix settings + nix = { + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + }; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + # System-wide locale + i18n.defaultLocale = "en_US.UTF-8"; + time.timeZone = "UTC"; + + # Networking basics + networking.useDHCP = lib.mkDefault true; + networking.networkmanager.enable = lib.mkDefault false; + +} diff --git a/nixos/modules/development.nix b/nixos/modules/development.nix new file mode 100644 index 0000000..0540cf8 --- /dev/null +++ b/nixos/modules/development.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, pkgs-unstable, ... }: + +{ + options.custom.development = { + enable = lib.mkEnableOption "Development tools"; + languages = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Programming languages to install (rust, python, nodejs, go, etc)"; + }; + }; + + config = let + cfg = config.custom.development; + + languagePackages = { + rust = with pkgs; [ rustup cargo-deny cargo-edit ]; + python = with pkgs; [ python3 python3Packages.pip python3Packages.virtualenv ]; + nodejs = with pkgs; [ nodejs npm pnpm ]; + go = with pkgs; [ go golangci-lint ]; + ruby = with pkgs; [ ruby bundler ]; + }; + + selectedPackages = + lib.concatMap (lang: languagePackages.${lang} or []) cfg.languages; + + in lib.mkIf cfg.enable { + + # Core development tools + environment.systemPackages = with pkgs; [ + git + git-lfs + gnumake + pkg-config + gcc + clang + cmake + gdb + ripgrep + fd + jq + yq-go + ] ++ selectedPackages; + + # Enable container support (optional) + virtualisation.docker.enable = true; + virtualisation.docker.enableOnBoot = false; + + }; +} diff --git a/nixos/modules/example-template.nix b/nixos/modules/example-template.nix new file mode 100644 index 0000000..d0afa36 --- /dev/null +++ b/nixos/modules/example-template.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +# Template for creating new NixOS modules +# Copy this file and customize for your needs + +{ + options.custom.example = { + enable = lib.mkEnableOption "Example feature"; + + # Add more options as needed + setting1 = lib.mkOption { + type = lib.types.str; + default = "default value"; + description = "Description of setting1"; + }; + + setting2 = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "A list of values"; + }; + }; + + config = let + cfg = config.custom.example; + in lib.mkIf cfg.enable { + + # Your configuration here + environment.systemPackages = with pkgs; [ + # Add packages needed for this feature + ]; + + # Other NixOS configuration + # services.myservice.enable = true; + + }; + +} + +# How to use this module: +# +# 1. Save this template as nixos/modules/myfeature.nix +# +# 2. Import it in nixos/default.nix: +# imports = [ +# ./modules/myfeature.nix +# ]; +# +# 3. Enable in host config (hosts/laptop/default.nix): +# custom.myfeature.enable = true; +# custom.myfeature.setting1 = "my value"; +# custom.myfeature.setting2 = [ "value1" "value2" ]; +# +# 4. Rebuild: +# sudo nixos-rebuild switch --flake .#laptop diff --git a/nixos/modules/secrets-example.nix b/nixos/modules/secrets-example.nix new file mode 100644 index 0000000..e49ea88 --- /dev/null +++ b/nixos/modules/secrets-example.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, sops-nix, ... }: + +# Example: How to use sops-nix for secrets management +# This module is NOT imported by default - uncomment in nixos/default.nix to use + +{ + imports = [ sops-nix.nixosModules.sops ]; + + # Point to your encrypted secrets file + sops.defaultSopsFile = ../../../secrets/secrets.yaml; + + # Age key location (sops-nix will decrypt using this) + sops.age.keyFile = "/home/youruser/.config/sops/age/keys.txt"; + + # Define which secrets to decrypt and where + sops.secrets = { + # SSH keys + "ssh/github_key" = { + owner = "youruser"; + group = "users"; + mode = "0600"; + # Decrypted to: /run/secrets/ssh/github_key + }; + + # API keys + "api_keys/example_api" = { + owner = "youruser"; + group = "users"; + mode = "0600"; + }; + + # Passwords (less recommended, use SSH keys when possible) + "passwords/example_password" = { + owner = "youruser"; + group = "users"; + mode = "0600"; + }; + }; + + # Example: Use decrypted secret in environment variable + environment.variables = { + # GITHUB_SSH_KEY = "${config.sops.secrets."ssh/github_key".path}"; + }; + + # Example: Copy secret to user home (for Git, SSH, etc.) + system.activationScripts.installSecrets = lib.stringAfter [ "users" ] '' + mkdir -p /home/youruser/.ssh + cp ${config.sops.secrets."ssh/github_key".path} /home/youruser/.ssh/github + chown youruser:users /home/youruser/.ssh/github + chmod 0600 /home/youruser/.ssh/github + ''; + +} + +# Usage in other modules: +# +# To use decrypted secrets in other config files, reference like: +# ${config.sops.secrets."ssh/github_key".path} +# +# Example in Git config: +# programs.git.extraConfig = { +# core.sshCommand = "ssh -i ${config.sops.secrets."ssh/github_key".path}"; +# }; +# +# Example in home-manager: +# programs.ssh.matchBlocks.github = { +# host = "github.com"; +# identityFile = "${config.sops.secrets."ssh/github_key".path}"; +# }; diff --git a/nixos/modules/shell.nix b/nixos/modules/shell.nix new file mode 100644 index 0000000..c32d133 --- /dev/null +++ b/nixos/modules/shell.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +{ + options.custom.shell = { + enable = lib.mkEnableOption "Shell configuration" // { default = true; }; + defaultShell = lib.mkOption { + type = lib.types.str; + default = "zsh"; + description = "Default shell (bash, zsh, fish)"; + }; + }; + + config = let + cfg = config.custom.shell; + in lib.mkIf cfg.enable { + + programs.zsh.enable = cfg.defaultShell == "zsh"; + programs.bash.enable = true; + programs.fish.enable = cfg.defaultShell == "fish"; + + # Common shell packages + environment.systemPackages = with pkgs; [ + starship + direnv + ]; + + }; +} diff --git a/nixos/modules/system.nix b/nixos/modules/system.nix new file mode 100644 index 0000000..e84ec67 --- /dev/null +++ b/nixos/modules/system.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: + +{ + options.custom.system = { + enable = lib.mkEnableOption "Custom system module" // { default = true; }; + }; + + config = lib.mkIf config.custom.system.enable { + # System-wide settings + system.stateVersion = "24.11"; + + # Users + users.users.youruser = { + isNormalUser = true; + extraGroups = [ "wheel" "docker" ]; + shell = pkgs.zsh; + }; + + # Sudo + security.sudo.enable = true; + + # SSH (disabled by default, enable in host config if needed) + services.openssh.enable = lib.mkDefault false; + }; +} diff --git a/secrets/.sops.yaml b/secrets/.sops.yaml new file mode 100644 index 0000000..0d32dd1 --- /dev/null +++ b/secrets/.sops.yaml @@ -0,0 +1,34 @@ +# SOPS configuration for secrets management +# https://github.com/mozilla/sops + +keys: + - &users | + - -----BEGIN AGE PUBLIC KEY----- + Your-Age-Public-Key-Here + -----END AGE PUBLIC KEY----- + + # SSH key-based decryption (recommended for machines) + - &machines | + - -----BEGIN AGE PUBLIC KEY----- + Laptop-Host-Key-Public-Key-Here + -----END AGE PUBLIC KEY----- + +creation_rules: + # Production secrets + - path_regex: ^secrets\.yaml$ + key_groups: + - age: + - *users + - *machines + +# For first-time setup: +# 1. Generate your age keypair: +# age-keygen -o -f ~/.config/sops/age/keys.txt +# +# 2. Extract your public key: +# age-keygen -y ~/.config/sops/age/keys.txt +# +# 3. Replace "Your-Age-Public-Key-Here" with the output +# +# 4. For machine-specific keys, use SSH: +# ssh-keyscan hostname | ssh-to-age -private-key-file ~/.config/sops/age/keys.txt