init by ai

This commit is contained in:
2026-04-07 02:34:03 +02:00
commit 0cec50d607
23 changed files with 2803 additions and 0 deletions

22
.gitignore vendored Normal file
View File

@@ -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

390
ARCHITECTURE.md Normal file
View File

@@ -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

477
CUSTOMIZATION.md Normal file
View File

@@ -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.

225
INDEX.md Normal file
View File

@@ -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.

141
QUICKREF.md Normal file
View File

@@ -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 <repo> ~/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

269
README.md Normal file
View File

@@ -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 <your-repo> 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

364
SETUP.md Normal file
View File

@@ -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 <your-repo> ~/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@<your-target-ip>
# 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 <your-repo> ~/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: <description of changes>"
```
## 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.

203
flake.nix Normal file
View File

@@ -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 -- <hostname>"
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
'');
};
};
}

48
home/default.nix Normal file
View File

@@ -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";
};
}

View File

@@ -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
'';
};
}

69
home/modules/editor.nix Normal file
View File

@@ -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;
}

View File

@@ -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

30
home/modules/git.nix Normal file
View File

@@ -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;
}

40
home/modules/shell.nix Normal file
View File

@@ -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;
}

57
hosts/laptop/default.nix Normal file
View File

@@ -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" ];
}

53
hosts/server/default.nix Normal file
View File

@@ -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" ];
}

44
nixos/default.nix Normal file
View File

@@ -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;
}

View File

@@ -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;
};
}

View File

@@ -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

View File

@@ -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}";
# };

28
nixos/modules/shell.nix Normal file
View File

@@ -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
];
};
}

25
nixos/modules/system.nix Normal file
View File

@@ -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;
};
}

34
secrets/.sops.yaml Normal file
View File

@@ -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