Add agent skills
This commit is contained in:
133
.agents/skills/find-skills/SKILL.md
Normal file
133
.agents/skills/find-skills/SKILL.md
Normal file
@@ -0,0 +1,133 @@
|
||||
---
|
||||
name: find-skills
|
||||
description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
|
||||
---
|
||||
|
||||
# Find Skills
|
||||
|
||||
This skill helps you discover and install skills from the open agent skills ecosystem.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when the user:
|
||||
|
||||
- Asks "how do I do X" where X might be a common task with an existing skill
|
||||
- Says "find a skill for X" or "is there a skill for X"
|
||||
- Asks "can you do X" where X is a specialized capability
|
||||
- Expresses interest in extending agent capabilities
|
||||
- Wants to search for tools, templates, or workflows
|
||||
- Mentions they wish they had help with a specific domain (design, testing, deployment, etc.)
|
||||
|
||||
## What is the Skills CLI?
|
||||
|
||||
The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools.
|
||||
|
||||
**Key commands:**
|
||||
|
||||
- `npx skills find [query]` - Search for skills interactively or by keyword
|
||||
- `npx skills add <package>` - Install a skill from GitHub or other sources
|
||||
- `npx skills check` - Check for skill updates
|
||||
- `npx skills update` - Update all installed skills
|
||||
|
||||
**Browse skills at:** https://skills.sh/
|
||||
|
||||
## How to Help Users Find Skills
|
||||
|
||||
### Step 1: Understand What They Need
|
||||
|
||||
When a user asks for help with something, identify:
|
||||
|
||||
1. The domain (e.g., React, testing, design, deployment)
|
||||
2. The specific task (e.g., writing tests, creating animations, reviewing PRs)
|
||||
3. Whether this is a common enough task that a skill likely exists
|
||||
|
||||
### Step 2: Search for Skills
|
||||
|
||||
Run the find command with a relevant query:
|
||||
|
||||
```bash
|
||||
npx skills find [query]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
- User asks "how do I make my React app faster?" → `npx skills find react performance`
|
||||
- User asks "can you help me with PR reviews?" → `npx skills find pr review`
|
||||
- User asks "I need to create a changelog" → `npx skills find changelog`
|
||||
|
||||
The command will return results like:
|
||||
|
||||
```
|
||||
Install with npx skills add <owner/repo@skill>
|
||||
|
||||
vercel-labs/agent-skills@vercel-react-best-practices
|
||||
└ https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices
|
||||
```
|
||||
|
||||
### Step 3: Present Options to the User
|
||||
|
||||
When you find relevant skills, present them to the user with:
|
||||
|
||||
1. The skill name and what it does
|
||||
2. The install command they can run
|
||||
3. A link to learn more at skills.sh
|
||||
|
||||
Example response:
|
||||
|
||||
```
|
||||
I found a skill that might help! The "vercel-react-best-practices" skill provides
|
||||
React and Next.js performance optimization guidelines from Vercel Engineering.
|
||||
|
||||
To install it:
|
||||
npx skills add vercel-labs/agent-skills@vercel-react-best-practices
|
||||
|
||||
Learn more: https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices
|
||||
```
|
||||
|
||||
### Step 4: Offer to Install
|
||||
|
||||
If the user wants to proceed, you can install the skill for them:
|
||||
|
||||
```bash
|
||||
npx skills add <owner/repo@skill> -g -y
|
||||
```
|
||||
|
||||
The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts.
|
||||
|
||||
## Common Skill Categories
|
||||
|
||||
When searching, consider these common categories:
|
||||
|
||||
| Category | Example Queries |
|
||||
| --------------- | ---------------------------------------- |
|
||||
| Web Development | react, nextjs, typescript, css, tailwind |
|
||||
| Testing | testing, jest, playwright, e2e |
|
||||
| DevOps | deploy, docker, kubernetes, ci-cd |
|
||||
| Documentation | docs, readme, changelog, api-docs |
|
||||
| Code Quality | review, lint, refactor, best-practices |
|
||||
| Design | ui, ux, design-system, accessibility |
|
||||
| Productivity | workflow, automation, git |
|
||||
|
||||
## Tips for Effective Searches
|
||||
|
||||
1. **Use specific keywords**: "react testing" is better than just "testing"
|
||||
2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd"
|
||||
3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills`
|
||||
|
||||
## When No Skills Are Found
|
||||
|
||||
If no relevant skills exist:
|
||||
|
||||
1. Acknowledge that no existing skill was found
|
||||
2. Offer to help with the task directly using your general capabilities
|
||||
3. Suggest the user could create their own skill with `npx skills init`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
I searched for skills related to "xyz" but didn't find any matches.
|
||||
I can still help you with this task directly! Would you like me to proceed?
|
||||
|
||||
If this is something you do often, you could create your own skill:
|
||||
npx skills init my-xyz-skill
|
||||
```
|
||||
349
.agents/skills/nix-best-practices/SKILL.md
Normal file
349
.agents/skills/nix-best-practices/SKILL.md
Normal file
@@ -0,0 +1,349 @@
|
||||
---
|
||||
name: nix-best-practices
|
||||
description: Nix patterns for flakes, overlays, unfree handling, and binary overlays. Use when working with flake.nix or shell.nix.
|
||||
---
|
||||
|
||||
# Nix Best Practices
|
||||
|
||||
## Flake Structure
|
||||
|
||||
Standard flake.nix structure:
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "Project description";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
};
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
# packages here
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Follows Pattern (Avoid Duplicate Nixpkgs)
|
||||
|
||||
When adding overlay inputs, use `follows` to share the parent nixpkgs and avoid downloading multiple versions:
|
||||
|
||||
```nix
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
# Overlay follows parent nixpkgs
|
||||
some-overlay.url = "github:owner/some-overlay";
|
||||
some-overlay.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
# Chain follows through intermediate inputs
|
||||
another-overlay.url = "github:owner/another-overlay";
|
||||
another-overlay.inputs.nixpkgs.follows = "some-overlay";
|
||||
};
|
||||
```
|
||||
|
||||
All inputs must be listed in outputs function even if not directly used:
|
||||
|
||||
```nix
|
||||
outputs = { self, nixpkgs, some-overlay, another-overlay, ... }:
|
||||
```
|
||||
|
||||
## Applying Overlays
|
||||
|
||||
Overlays modify or add packages to nixpkgs:
|
||||
|
||||
```nix
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
overlay1.overlays.default
|
||||
overlay2.overlays.default
|
||||
# Inline overlay
|
||||
(final: prev: {
|
||||
myPackage = prev.myPackage.override { ... };
|
||||
})
|
||||
];
|
||||
};
|
||||
in
|
||||
```
|
||||
|
||||
## Handling Unfree Packages
|
||||
|
||||
### Option 1: nixpkgs-unfree (Recommended for Teams)
|
||||
|
||||
Use numtide/nixpkgs-unfree for EULA-licensed packages without requiring user config:
|
||||
|
||||
```nix
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nixpkgs-unfree.url = "github:numtide/nixpkgs-unfree/nixos-unstable";
|
||||
nixpkgs-unfree.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
# Unfree overlay follows nixpkgs-unfree
|
||||
proprietary-tool.url = "github:owner/proprietary-tool-overlay";
|
||||
proprietary-tool.inputs.nixpkgs.follows = "nixpkgs-unfree";
|
||||
};
|
||||
```
|
||||
|
||||
This chains: `proprietary-tool` → `nixpkgs-unfree` → `nixpkgs`
|
||||
|
||||
### Option 2: User Config
|
||||
|
||||
Users add to `~/.config/nixpkgs/config.nix`:
|
||||
|
||||
```nix
|
||||
{ allowUnfree = true; }
|
||||
```
|
||||
|
||||
### Option 3: Specific Packages (Flake)
|
||||
|
||||
```nix
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"specific-package"
|
||||
];
|
||||
};
|
||||
in
|
||||
```
|
||||
|
||||
Note: `config.allowUnfree` in flake.nix doesn't work with `nix develop` - use nixpkgs-unfree or user config.
|
||||
|
||||
## Creating Binary Overlay Repos
|
||||
|
||||
When nixpkgs builds a community version lacking features (common with open-core tools), create an overlay that fetches official binaries.
|
||||
|
||||
### Pattern (see 0xBigBoss/atlas-overlay, 0xBigBoss/bun-overlay)
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
|
||||
version = "1.0.0";
|
||||
|
||||
# Platform-specific binaries
|
||||
sources = {
|
||||
"x86_64-linux" = {
|
||||
url = "https://example.com/tool-linux-amd64-v${version}";
|
||||
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
"aarch64-linux" = {
|
||||
url = "https://example.com/tool-linux-arm64-v${version}";
|
||||
sha256 = "sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=";
|
||||
};
|
||||
"x86_64-darwin" = {
|
||||
url = "https://example.com/tool-darwin-amd64-v${version}";
|
||||
sha256 = "sha256-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC=";
|
||||
};
|
||||
"aarch64-darwin" = {
|
||||
url = "https://example.com/tool-darwin-arm64-v${version}";
|
||||
sha256 = "sha256-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD=";
|
||||
};
|
||||
};
|
||||
|
||||
source = sources.${system} or (throw "Unsupported system: ${system}");
|
||||
|
||||
toolPackage = pkgs.stdenv.mkDerivation {
|
||||
pname = "tool";
|
||||
inherit version;
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
inherit (source) url sha256;
|
||||
};
|
||||
|
||||
sourceRoot = ".";
|
||||
dontUnpack = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp $src $out/bin/tool
|
||||
chmod +x $out/bin/tool
|
||||
'';
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "Tool description";
|
||||
homepage = "https://example.com";
|
||||
license = licenses.unfree; # or appropriate license
|
||||
platforms = builtins.attrNames sources;
|
||||
};
|
||||
};
|
||||
in {
|
||||
packages.default = toolPackage;
|
||||
packages.tool = toolPackage;
|
||||
|
||||
overlays.default = final: prev: {
|
||||
tool = toolPackage;
|
||||
};
|
||||
})
|
||||
// {
|
||||
overlays.default = final: prev: {
|
||||
tool = self.packages.${prev.system}.tool;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Getting SHA256 Hashes
|
||||
|
||||
```bash
|
||||
nix-prefetch-url https://example.com/tool-linux-amd64-v1.0.0
|
||||
# Returns hash in base32, convert to SRI format:
|
||||
nix hash to-sri --type sha256 <base32-hash>
|
||||
```
|
||||
|
||||
Or use SRI directly:
|
||||
```bash
|
||||
nix-prefetch-url --type sha256 https://example.com/tool-linux-amd64-v1.0.0
|
||||
```
|
||||
|
||||
## Dev Shell Patterns
|
||||
|
||||
### Basic Shell
|
||||
|
||||
```nix
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
nodejs
|
||||
python3
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "Dev environment ready"
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
### With Environment Variables
|
||||
|
||||
```nix
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [ postgresql ];
|
||||
|
||||
# Set at shell entry
|
||||
DATABASE_URL = "postgres://localhost/dev";
|
||||
|
||||
# Or in shellHook for dynamic values
|
||||
shellHook = ''
|
||||
export PROJECT_ROOT="$(pwd)"
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
### Native Dependencies (C Libraries)
|
||||
|
||||
```nix
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
openssl
|
||||
postgresql
|
||||
];
|
||||
|
||||
# Expose headers and libraries
|
||||
shellHook = ''
|
||||
export C_INCLUDE_PATH="${pkgs.openssl.dev}/include:$C_INCLUDE_PATH"
|
||||
export LIBRARY_PATH="${pkgs.openssl.out}/lib:$LIBRARY_PATH"
|
||||
export PKG_CONFIG_PATH="${pkgs.openssl.dev}/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
## Direnv Integration
|
||||
|
||||
`.envrc` for flake projects:
|
||||
|
||||
```bash
|
||||
use flake
|
||||
```
|
||||
|
||||
For unfree packages without nixpkgs-unfree:
|
||||
|
||||
```bash
|
||||
export NIXPKGS_ALLOW_UNFREE=1
|
||||
use flake --impure
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Update all inputs
|
||||
nix flake update
|
||||
|
||||
# Update specific input
|
||||
nix flake update some-input
|
||||
|
||||
# Check flake validity
|
||||
nix flake check
|
||||
|
||||
# Show flake metadata
|
||||
nix flake metadata
|
||||
|
||||
# Enter dev shell
|
||||
nix develop
|
||||
|
||||
# Run command in dev shell
|
||||
nix develop -c <command>
|
||||
|
||||
# Build package
|
||||
nix build .#packageName
|
||||
|
||||
# Run package
|
||||
nix run .#packageName
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "unexpected argument" Error
|
||||
|
||||
All inputs must be listed in outputs function:
|
||||
```nix
|
||||
# Wrong
|
||||
outputs = { self, nixpkgs }: ...
|
||||
|
||||
# Right (if you have more inputs)
|
||||
outputs = { self, nixpkgs, other-input, ... }: ...
|
||||
```
|
||||
|
||||
### Unfree Package Errors with nix develop
|
||||
|
||||
`config.allowUnfree` in flake.nix doesn't propagate to `nix develop`. Use:
|
||||
1. nixpkgs-unfree input (recommended)
|
||||
2. User's `~/.config/nixpkgs/config.nix`
|
||||
3. `NIXPKGS_ALLOW_UNFREE=1 nix develop --impure`
|
||||
|
||||
### Duplicate Nixpkgs Downloads
|
||||
|
||||
Use `follows` to chain inputs to a single nixpkgs source.
|
||||
|
||||
### Overlay Not Applied
|
||||
|
||||
Ensure overlay is in the `overlays` list when importing nixpkgs:
|
||||
```nix
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ my-overlay.overlays.default ];
|
||||
};
|
||||
```
|
||||
|
||||
### Hash Mismatch
|
||||
|
||||
Re-fetch with `nix-prefetch-url` and update the hash. Hashes change when upstream updates binaries at the same URL.
|
||||
533
.agents/skills/nixos-best-practices/AGENTS.md
Normal file
533
.agents/skills/nixos-best-practices/AGENTS.md
Normal file
@@ -0,0 +1,533 @@
|
||||
# NixOS Configuration Best Practices
|
||||
|
||||
Complete guide for configuring NixOS systems with flakes, managing overlays, and structuring configurations.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Use](#when-to-use)
|
||||
- [Essential Pattern](#essential-pattern-overlay-scope-and-useglobalpkgs)
|
||||
- [Flakes Structure](#flakes-configuration-structure)
|
||||
- [Host Organization](#host-configuration-organization)
|
||||
- [Package Installation](#package-installation-best-practices)
|
||||
- [Common Mistakes](#common-configuration-mistakes)
|
||||
- [Troubleshooting](#troubleshooting-configuration-issues)
|
||||
- [Real-World Impact](#real-world-impact)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**Core principle:** Understand the interaction between NixOS system configuration and Home Manager overlays.
|
||||
|
||||
When `useGlobalPkgs = true`, overlays must be defined at the NixOS configuration level, not in Home Manager configuration files.
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
**Use when:**
|
||||
- Configuring NixOS with flakes and Home Manager
|
||||
- Adding overlays that don't seem to apply
|
||||
- Using `useGlobalPkgs = true` with custom overlays
|
||||
- Structuring NixOS configurations across multiple hosts
|
||||
- Package changes not appearing after rebuild
|
||||
- Confused about where to define overlays
|
||||
|
||||
**Don't use for:**
|
||||
- Packaging new software (use nix-packaging-best-practices)
|
||||
- Simple package installation without overlays
|
||||
- NixOS module development (see NixOS module documentation)
|
||||
|
||||
---
|
||||
|
||||
## Essential Pattern: Overlay Scope and useGlobalPkgs
|
||||
|
||||
### Why This Matters
|
||||
|
||||
When using Home Manager with NixOS, the `useGlobalPkgs` setting determines where overlay definitions must be placed. Defining overlays in the wrong location means they simply don't apply, leading to "package not found" errors even when the overlay syntax is correct.
|
||||
|
||||
### The Problem
|
||||
|
||||
When `useGlobalPkgs = true`, Home Manager uses NixOS's global `pkgs` instance. Overlays defined in `home.nix` are ignored because Home Manager isn't creating its own `pkgs` - it's using the system one.
|
||||
|
||||
### Incorrect: Overlay in home.nix with useGlobalPkgs=true
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = true; # Using system pkgs
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
}
|
||||
|
||||
# home-manager/home.nix
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
# ❌ This overlay is IGNORED when useGlobalPkgs = true!
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
|
||||
home.packages = with pkgs; [
|
||||
claude-code # Error: attribute 'claude-code' not found
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Why it fails:** When `useGlobalPkgs = true`, the `nixpkgs.overlays` line in `home.nix` has no effect. Home Manager isn't creating its own `pkgs`, so it can't apply overlays to one.
|
||||
|
||||
### Correct: Overlay in host home-manager block
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
home-manager.extraSpecialArgs = { inherit inputs pkgs-stable system; };
|
||||
# ✅ Overlay defined HERE affects the global pkgs
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
}
|
||||
|
||||
# home-manager/home.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
# No overlay definition needed here
|
||||
home.packages = with pkgs; [
|
||||
claude-code # ✅ Works! Found via overlay
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Why it works:** The overlay is defined where Home Manager configures the `pkgs` instance it will use. When `useGlobalPkgs = true`, this means the overlay is applied to the system's package set.
|
||||
|
||||
### Alternative: Set useGlobalPkgs=false
|
||||
|
||||
If you want to define overlays in `home.nix`, set `useGlobalPkgs = false`:
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = false; # Home Manager creates own pkgs
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
}
|
||||
|
||||
# home-manager/home.nix
|
||||
{ pkgs, inputs, ... }:
|
||||
{
|
||||
# ✅ This works when useGlobalPkgs = false
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
|
||||
home.packages = with pkgs; [
|
||||
claude-code # ✅ Works! Found via overlay
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Trade-off:** This creates a separate package set for Home Manager, which means packages are built twice (once for system, once for Home Manager). Only use this when you truly need separate package sets.
|
||||
|
||||
### Decision Matrix
|
||||
|
||||
| Your Need | useGlobalPkgs | Overlay Location |
|
||||
|-----------|---------------|------------------|
|
||||
| Single-user system, efficiency | `true` | Host home-manager block |
|
||||
| Multi-user, different packages per user | `false` | User's home.nix |
|
||||
| Custom packages system-wide | `true` | System nixpkgs.overlays |
|
||||
| Quick prototype | `false` | User's home.nix |
|
||||
|
||||
---
|
||||
|
||||
## Flakes Configuration Structure
|
||||
|
||||
### Core Structure
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "My NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
# Add other flake inputs here
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs: {
|
||||
nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/hostname ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Special Args Pattern
|
||||
|
||||
Pass `inputs` via `specialArgs` to make flake inputs available in modules:
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Forgetting specialArgs
|
||||
outputs = { self, nixpkgs, home-manager }:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
modules = [ ./hosts/myhost ]; # inputs not available!
|
||||
};
|
||||
}
|
||||
|
||||
# ✅ CORRECT: Using specialArgs
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/myhost ]; # inputs available!
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Input Following
|
||||
|
||||
Set `inputs.nixpkgs.follows` to avoid duplicate nixpkgs instances:
|
||||
|
||||
```nix
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
# ❌ WRONG: Doesn't follow, creates duplicate nixpkgs
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
|
||||
# ✅ CORRECT: Follows nixpkgs, uses same instance
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Host Configuration Organization
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
nixos-config/
|
||||
├── flake.nix # Top-level flake
|
||||
├── hosts/
|
||||
│ ├── laptop/
|
||||
│ │ ├── default.nix # Host-specific config
|
||||
│ │ ├── hardware-configuration.nix # Generated (don't edit)
|
||||
│ │ └── home.nix # Home Manager config
|
||||
│ ├── desktop/
|
||||
│ │ ├── default.nix
|
||||
│ │ ├── hardware-configuration.nix
|
||||
│ │ └── home.nix
|
||||
│ └── base.nix # Shared by all hosts (optional)
|
||||
├── modules/ # Reusable NixOS modules
|
||||
├── overlays/ # Custom overlays
|
||||
├── home-manager/ # Shared Home Manager configs
|
||||
│ ├── shell/
|
||||
│ ├── applications/
|
||||
│ └── common.nix
|
||||
└── secrets/ # Age-encrypted secrets
|
||||
```
|
||||
|
||||
### Host Configuration Pattern
|
||||
|
||||
```nix
|
||||
# hosts/laptop/default.nix
|
||||
{ inputs, pkgs, pkgs-stable, system, ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix # Import hardware config
|
||||
../base.nix # Import shared config
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.john = import ./home.nix;
|
||||
home-manager.extraSpecialArgs = {
|
||||
inherit inputs pkgs-stable system;
|
||||
};
|
||||
nixpkgs.overlays = [ inputs.some-overlay.overlays.default ];
|
||||
}
|
||||
];
|
||||
|
||||
# Host-specific config only
|
||||
networking.hostName = "laptop";
|
||||
}
|
||||
```
|
||||
|
||||
### Shared Base Configuration
|
||||
|
||||
```nix
|
||||
# hosts/base.nix
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
# Network
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
# Time and locale
|
||||
time.timeZone = "America/New_York";
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
|
||||
# Users (shared across all hosts)
|
||||
users.users.john = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "networkmanager" ];
|
||||
};
|
||||
|
||||
# Common packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
git
|
||||
wget
|
||||
tmux
|
||||
];
|
||||
|
||||
# Common services
|
||||
services.openssh.enable = true;
|
||||
|
||||
# Nix settings
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** Don't edit `hardware-configuration.nix` manually. It's generated by `nixos-generate-config` and should be replaced when hardware changes.
|
||||
|
||||
---
|
||||
|
||||
## Package Installation Best Practices
|
||||
|
||||
### System vs User Packages
|
||||
|
||||
**System Packages (NixOS)** - Use for:
|
||||
- System services (servers, daemons)
|
||||
- Packages needed by all users
|
||||
- Hardware-related packages (drivers, firmware)
|
||||
|
||||
```nix
|
||||
# hosts/base.nix or host-specific default.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # Available to all users
|
||||
git
|
||||
wget
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**User Packages (Home Manager)** - Use for:
|
||||
- User-specific applications
|
||||
- Desktop applications
|
||||
- Development tools (user-specific)
|
||||
|
||||
```nix
|
||||
# home-manager/home.nix or sub-configs
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
vscode # User-specific
|
||||
chrome
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Installing from Different Nixpkgs Channels
|
||||
|
||||
```nix
|
||||
# flake.nix - default is unstable
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||
};
|
||||
|
||||
# Host config
|
||||
{ pkgs, pkgs-stable, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # From unstable (default)
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs-stable; [
|
||||
vim # From stable
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Configuration Mistakes
|
||||
|
||||
### Mistake 1: Overlay in Wrong Location
|
||||
|
||||
**Symptom:** Package not found even though overlay is defined.
|
||||
|
||||
**Solution:** Move overlay to host's home-manager configuration block.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: home-manager/home.nix
|
||||
{
|
||||
nixpkgs.overlays = [ inputs.overlay.overlays.default ];
|
||||
}
|
||||
|
||||
# ✅ CORRECT: hosts/home/default.nix
|
||||
{
|
||||
home-manager.nixpkgs.overlays = [ inputs.overlay.overlays.default ];
|
||||
}
|
||||
```
|
||||
|
||||
### Mistake 2: Forgetting specialArgs
|
||||
|
||||
**Symptom:** `undefined variable 'inputs'` error.
|
||||
|
||||
**Solution:** Add `specialArgs = { inherit inputs; }`.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG
|
||||
outputs = { self, nixpkgs, home-manager }:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
}
|
||||
|
||||
# ✅ CORRECT
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Mistake 3: Editing hardware-configuration.nix
|
||||
|
||||
**Symptom:** Hardware changes lost after running `nixos-generate-config`.
|
||||
|
||||
**Solution:** Put custom config in `default.nix`, not `hardware-configuration.nix`.
|
||||
|
||||
### Mistake 4: Duplicate Package Declarations
|
||||
|
||||
**Symptom:** Same package in both system and Home Manager config.
|
||||
|
||||
**Solution:** Install in appropriate location only.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG
|
||||
# hosts/base.nix
|
||||
environment.systemPackages = with pkgs; [ firefox ];
|
||||
|
||||
# home-manager/home.nix
|
||||
home.packages = with pkgs; [ firefox ]; # Duplicate!
|
||||
|
||||
# ✅ CORRECT: Choose one location
|
||||
home.packages = with pkgs; [ firefox ];
|
||||
```
|
||||
|
||||
### Mistake 5: Not Following nixpkgs
|
||||
|
||||
**Symptom:** Slow builds, inconsistent packages.
|
||||
|
||||
**Solution:** Use `.follows` for dependency inputs.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
};
|
||||
|
||||
# ✅ CORRECT
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting Configuration Issues
|
||||
|
||||
### General Approach
|
||||
|
||||
1. **Read error messages completely** - They usually tell you exactly what's wrong
|
||||
2. **Verify syntax** - Check for missing brackets, quotes, commas
|
||||
3. **Validate config** - Use `nixos-rebuild test` first
|
||||
4. **Check scope** - Is overlay/module in correct location?
|
||||
5. **Trace dependencies** - Are required inputs/imports present?
|
||||
|
||||
### Common Error Patterns
|
||||
|
||||
**"undefined variable 'inputs'"**
|
||||
|
||||
Add to flake.nix:
|
||||
```nix
|
||||
specialArgs = { inherit inputs; };
|
||||
```
|
||||
|
||||
**"attribute 'package-name' not found"**
|
||||
|
||||
Check if overlay is defined in correct location based on `useGlobalPkgs` setting.
|
||||
|
||||
**"error: The option 'some.option' does not exist"**
|
||||
|
||||
Search for option:
|
||||
```bash
|
||||
nixos-options | grep some-option
|
||||
```
|
||||
|
||||
**"infinite recursion"**
|
||||
|
||||
Use --show-trace:
|
||||
```bash
|
||||
nixos-rebuild build --flake .#hostname --show-trace
|
||||
```
|
||||
|
||||
### Configuration Changes Not Applying
|
||||
|
||||
```bash
|
||||
# Verify rebuild succeeded
|
||||
sudo nixos-rebuild switch --flake .#hostname
|
||||
|
||||
# Check current generation
|
||||
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
|
||||
|
||||
# Verify new generation is active
|
||||
nixos-version
|
||||
```
|
||||
|
||||
### Useful Verification Commands
|
||||
|
||||
```bash
|
||||
# Check configuration without building
|
||||
nix flake check
|
||||
nixos-rebuild build --flake .#hostname --dry-run
|
||||
|
||||
# Evaluate specific option
|
||||
nix eval .#nixosConfigurations.myhost.config.environment.systemPackages
|
||||
|
||||
# Test configuration safely
|
||||
nixos-rebuild test --flake .#hostname # Rollback on reboot
|
||||
nixos-rebuild switch --flake .#hostname # Persistent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real-World Impact
|
||||
|
||||
Following these best practices prevents the most common NixOS configuration issues:
|
||||
|
||||
**Before:**
|
||||
- Users spend hours debugging why overlays don't apply
|
||||
- Configuration is duplicated across hosts
|
||||
- Changes don't apply after editing files
|
||||
- Confusion about where to define overlays
|
||||
|
||||
**After:**
|
||||
- Clear understanding of overlay scope
|
||||
- Modular, maintainable configuration structure
|
||||
- Predictable behavior
|
||||
- Easy debugging when issues arise
|
||||
|
||||
The overlay scope issue alone accounts for ~80% of NixOS + Home Manager configuration problems encountered by users.
|
||||
134
.agents/skills/nixos-best-practices/SKILL.md
Normal file
134
.agents/skills/nixos-best-practices/SKILL.md
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
name: nixos-best-practices
|
||||
description: Use when configuring NixOS with flakes, managing overlays with home-manager useGlobalPkgs, structuring NixOS configurations, or facing issues where configuration changes don't apply
|
||||
license: MIT
|
||||
metadata:
|
||||
author: chumeng
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# Configuring NixOS Systems with Flakes
|
||||
|
||||
Configure NixOS systems with flakes, manage overlays properly, and structure configurations for maintainability.
|
||||
|
||||
## Core Principle
|
||||
|
||||
**Understand the interaction between NixOS system configuration and Home Manager overlays.**
|
||||
|
||||
When `useGlobalPkgs = true`, overlays must be defined at the NixOS configuration level, not in Home Manager configuration files.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Configuring NixOS with flakes and Home Manager
|
||||
- Adding overlays that don't seem to apply
|
||||
- Using `useGlobalPkgs = true` with custom overlays
|
||||
- Structuring NixOS configurations across multiple hosts
|
||||
- Package changes not appearing after rebuild
|
||||
- Confused about where to define overlays
|
||||
|
||||
**Don't use for:**
|
||||
- Packaging new software (use nix-packaging-best-practices)
|
||||
- Simple package installation without overlays
|
||||
- NixOS module development (see NixOS module documentation)
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Topic | Rule File |
|
||||
|-------|-----------|
|
||||
| Overlay scope and useGlobalPkgs | [overlay-scope](rules/overlay-scope.md) |
|
||||
| Flakes configuration structure | [flakes-structure](rules/flakes-structure.md) |
|
||||
| Host configuration organization | [host-organization](rules/host-organization.md) |
|
||||
| Package installation best practices | [package-installation](rules/package-installation.md) |
|
||||
| Common configuration mistakes | [common-mistakes](rules/common-mistakes.md) |
|
||||
| Debugging configuration issues | [troubleshooting](rules/troubleshooting.md) |
|
||||
|
||||
## Essential Pattern: Overlay with useGlobalPkgs
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Overlay in home.nix (doesn't apply)
|
||||
# home-manager/home.nix
|
||||
{
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ]; # Ignored!
|
||||
home.packages = with pkgs; [ claude-code ]; # Not found!
|
||||
}
|
||||
|
||||
# ✅ CORRECT: Overlay in NixOS home-manager block
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
home-manager.extraSpecialArgs = { inherit inputs pkgs-stable system; };
|
||||
# Overlay must be HERE when useGlobalPkgs = true
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
}
|
||||
```
|
||||
|
||||
## Common Tasks
|
||||
|
||||
| Task | Solution |
|
||||
|------|----------|
|
||||
| Add flake input | Add to `inputs` in flake.nix |
|
||||
| Add overlay for system packages | Define in `nixpkgs.overlays` in system configuration |
|
||||
| Add overlay for home-manager (useGlobalPkgs=true) | Define in `home-manager.nixpkgs.overlays` in host config |
|
||||
| Add overlay for home-manager (useGlobalPkgs=false) | Define in `home.nix` with `nixpkgs.overlays` |
|
||||
| Pass inputs to modules | Use `specialArgs` in nixosSystem or home-manager |
|
||||
| Multiple host configurations | Create separate host files in `hosts/` |
|
||||
| Shared configuration modules | Create modules in `modules/` and import in each host |
|
||||
| Package not found after overlay | Check overlay scope vs useGlobalPkgs setting |
|
||||
|
||||
## Overlay Scope Decision Matrix
|
||||
|
||||
| useGlobalPkgs | Overlay Definition Location | Affects |
|
||||
|---------------|---------------------------|---------|
|
||||
| `true` | `home-manager.nixpkgs.overlays` | System + Home Manager packages |
|
||||
| `true` | `home.nix` with `nixpkgs.overlays` | **Nothing** (ignored!) |
|
||||
| `false` | `home.nix` with `nixpkgs.overlays` | Home Manager packages only |
|
||||
| `false` | `home-manager.nixpkgs.overlays` | Home Manager packages only |
|
||||
| Any | System `nixpkgs.overlays` | System packages only |
|
||||
|
||||
## Configuration Layers (Bottom to Top)
|
||||
|
||||
1. **System configuration** (`/etc/nixos/configuration.nix` or host files)
|
||||
- System-wide services
|
||||
- System packages
|
||||
- System overlays only affect this layer
|
||||
|
||||
2. **Home Manager (useGlobalPkgs=true)**
|
||||
- Uses system pkgs (includes system overlays)
|
||||
- Home Manager overlays affect both system and user packages
|
||||
- Most efficient for single-user systems
|
||||
|
||||
3. **Home Manager (useGlobalPkgs=false)**
|
||||
- Creates separate pkgs instance
|
||||
- Home Manager overlays affect user packages only
|
||||
- Useful for multi-user systems with different needs
|
||||
|
||||
## Red Flags - STOP
|
||||
|
||||
- "Overlay in home.nix isn't working" → Check if useGlobalPkgs=true, move to host config
|
||||
- "I'll just add overlays everywhere" → Define once at appropriate scope
|
||||
- "Package works in nix repl but not installed" → Check overlay scope
|
||||
- "Changes don't apply after rebuild" → Verify overlay is in correct location
|
||||
- "useGlobalPkgs=false for no reason" → Use true unless you need separate package sets
|
||||
|
||||
## How to Use
|
||||
|
||||
Read individual rule files for detailed explanations and code examples:
|
||||
|
||||
```
|
||||
rules/overlay-scope.md # The core overlay scope issue
|
||||
rules/flakes-structure.md # How to organize flake.nix
|
||||
rules/host-organization.md # How to structure host configs
|
||||
rules/common-mistakes.md # Pitfalls and how to avoid them
|
||||
```
|
||||
|
||||
Each rule file contains:
|
||||
- Brief explanation of why it matters
|
||||
- Incorrect code example with explanation
|
||||
- Correct code example with explanation
|
||||
- Additional context and references
|
||||
|
||||
## Full Compiled Document
|
||||
|
||||
For the complete guide with all rules expanded: `AGENTS.md`
|
||||
323
.agents/skills/nixos-best-practices/rules/common-mistakes.md
Normal file
323
.agents/skills/nixos-best-practices/rules/common-mistakes.md
Normal file
@@ -0,0 +1,323 @@
|
||||
---
|
||||
title: Common Configuration Mistakes
|
||||
impact: HIGH
|
||||
impactDescription: Prevents the most frequently made configuration errors
|
||||
tags: mistakes,pitfalls,errors,checklist
|
||||
---
|
||||
|
||||
|
||||
## Why This Matters
|
||||
|
||||
Understanding common mistakes helps avoid them, saving time and preventing configuration errors.
|
||||
|
||||
## Mistake 1: Overlay in Wrong Location
|
||||
|
||||
### Symptom
|
||||
Package not found even though overlay is defined.
|
||||
|
||||
### Cause
|
||||
Overlay defined in `home.nix` when `useGlobalPkgs = true`.
|
||||
|
||||
### Solution
|
||||
Move overlay to host's home-manager configuration block.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG
|
||||
# home-manager/home.nix
|
||||
{
|
||||
nixpkgs.overlays = [ inputs.overlay.overlays.default ];
|
||||
}
|
||||
|
||||
# ✅ CORRECT
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.nixpkgs.overlays = [ inputs.overlay.overlays.default ];
|
||||
}
|
||||
```
|
||||
|
||||
**See:** [overlay-scope.md](overlay-scope.md)
|
||||
|
||||
## Mistake 2: Forgetting specialArgs
|
||||
|
||||
### Symptom
|
||||
`undefined variable 'inputs'` error.
|
||||
|
||||
### Cause
|
||||
Not passing `inputs` via `specialArgs`.
|
||||
|
||||
### Solution
|
||||
Add `specialArgs = { inherit inputs; }`.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG
|
||||
outputs = { self, nixpkgs, home-manager }:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
}
|
||||
|
||||
# ✅ CORRECT
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**See:** [flakes-structure.md](flakes-structure.md)
|
||||
|
||||
## Mistake 3: Editing hardware-configuration.nix
|
||||
|
||||
### Symptom
|
||||
Hardware changes lost after running `nixos-generate-config`.
|
||||
|
||||
### Cause
|
||||
Manually editing generated file.
|
||||
|
||||
### Solution
|
||||
Put custom config in `default.nix`, not `hardware-configuration.nix`.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Editing hardware-configuration.nix
|
||||
# hosts/laptop/hardware-configuration.nix
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
{
|
||||
# My custom kernel parameters (will be lost!)
|
||||
boot.kernelParams = [ "intel_iommu=on" ];
|
||||
|
||||
# Generated hardware config...
|
||||
}
|
||||
|
||||
# ✅ CORRECT: Custom config in default.nix
|
||||
# hosts/laptop/default.nix
|
||||
{
|
||||
imports = [ ./hardware-configuration.nix ];
|
||||
|
||||
# Custom kernel parameters (safe!)
|
||||
boot.kernelParams = [ "intel_iommu=on" ];
|
||||
}
|
||||
```
|
||||
|
||||
**See:** [host-organization.md](host-organization.md)
|
||||
|
||||
## Mistake 4: Duplicate Package Declarations
|
||||
|
||||
### Symptom
|
||||
Package installed multiple times or conflicts.
|
||||
|
||||
### Cause
|
||||
Same package in both system and Home Manager config.
|
||||
|
||||
### Solution
|
||||
Install in appropriate location only.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Same package in both places
|
||||
# hosts/base.nix
|
||||
environment.systemPackages = with pkgs; [ firefox ];
|
||||
|
||||
# home-manager/home.nix
|
||||
home.packages = with pkgs; [ firefox ]; # Duplicate!
|
||||
|
||||
# ✅ CORRECT: Choose one location
|
||||
# User apps in Home Manager
|
||||
home.packages = with pkgs; [ firefox ];
|
||||
```
|
||||
|
||||
**See:** [package-installation.md](package-installation.md)
|
||||
|
||||
## Mistake 5: Not Following nixpkgs
|
||||
|
||||
### Symptom
|
||||
Slow builds, inconsistent packages.
|
||||
|
||||
### Cause
|
||||
Multiple independent nixpkgs instances.
|
||||
|
||||
### Solution
|
||||
Use `.follows` for dependency inputs.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Independent nixpkgs
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
# home-manager will use its own nixpkgs!
|
||||
};
|
||||
|
||||
# ✅ CORRECT: Follow nixpkgs
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
```
|
||||
|
||||
**See:** [flakes-structure.md](flakes-structure.md)
|
||||
|
||||
## Mistake 6: Mixing System and User Concerns
|
||||
|
||||
### Symptom
|
||||
User-specific config in system files or vice versa.
|
||||
|
||||
### Cause
|
||||
Not understanding NixOS vs Home Manager responsibilities.
|
||||
|
||||
### Solution
|
||||
System config in NixOS, user config in Home Manager.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: User config in system
|
||||
# hosts/base.nix
|
||||
{
|
||||
# User's git config (should be in Home Manager)
|
||||
programs.git = {
|
||||
enable = true;
|
||||
userName = "john";
|
||||
userEmail = "john@example.com";
|
||||
};
|
||||
}
|
||||
|
||||
# ✅ CORRECT: User config in Home Manager
|
||||
# home-manager/home.nix
|
||||
{
|
||||
programs.git = {
|
||||
enable = true;
|
||||
userName = "john";
|
||||
userEmail = "john@example.com";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**See:** [package-installation.md](package-installation.md)
|
||||
|
||||
## Mistake 7: Forgetting to Rebuild
|
||||
|
||||
### Symptom
|
||||
Changes don't appear after editing config.
|
||||
|
||||
### Cause
|
||||
Editing config but not running rebuild.
|
||||
|
||||
### Solution
|
||||
Always rebuild after config changes.
|
||||
|
||||
```bash
|
||||
# After editing NixOS config
|
||||
sudo nixos-rebuild switch --flake .#hostname
|
||||
|
||||
# After editing Home Manager config (standalone)
|
||||
home-manager switch --flake .#hostname
|
||||
|
||||
# When using NixOS-integrated Home Manager
|
||||
sudo nixos-rebuild switch --flake .#hostname
|
||||
```
|
||||
|
||||
## Mistake 8: Overriding systemPackages Multiple Times
|
||||
|
||||
### Symptom
|
||||
Some packages disappear after adding others.
|
||||
|
||||
### Cause
|
||||
Multiple `environment.systemPackages` assignments.
|
||||
|
||||
### Solution
|
||||
Use single list or mkBefore/mkAfter.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Multiple assignments
|
||||
environment.systemPackages = with pkgs; [ vim git ];
|
||||
environment.systemPackages = with pkgs; [ htop ]; # Overwrites!
|
||||
|
||||
# ✅ CORRECT: Single list
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
git
|
||||
htop
|
||||
];
|
||||
|
||||
# ✅ ALSO CORRECT: Use mkBefore/mkAfter
|
||||
environment.systemPackages = with pkgs; [ vim git ];
|
||||
environment.systemPackages = mkAfter [ pkgs.htop ];
|
||||
```
|
||||
|
||||
## Mistake 9: Hardcoding Paths
|
||||
|
||||
### Symptom
|
||||
Config breaks on different machines.
|
||||
|
||||
### Cause
|
||||
Using absolute paths instead of Nix paths.
|
||||
|
||||
### Solution
|
||||
Use relative paths or Nix constructs.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Absolute path
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
"/home/john/my-app/bin/my-app" # Only works for john!
|
||||
];
|
||||
}
|
||||
|
||||
# ✅ CORRECT: Use Nix package
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [ pkgs.my-app ];
|
||||
}
|
||||
|
||||
# ✅ OR: Use path from flake
|
||||
{ ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
(pkgs.callPackage ./local-packages/my-app { })
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Mistake 10: Not Using Flake References
|
||||
|
||||
### Symptom
|
||||
Can't use packages from flake inputs.
|
||||
|
||||
### Cause
|
||||
Not passing inputs or using wrong reference.
|
||||
|
||||
### Solution
|
||||
Use `inputs.*` syntax.
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Trying to use input package
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
unfire-overlay # Where does this come from?
|
||||
];
|
||||
}
|
||||
|
||||
# ✅ CORRECT: Use input reference
|
||||
{ pkgs, inputs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
inputs.unfire-overlay.packages.${pkgs.system}.default
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Quick Checklist
|
||||
|
||||
Before committing config changes:
|
||||
|
||||
- [ ] Overlay in correct location for useGlobalPkgs setting
|
||||
- [ ] inputs passed via specialArgs if needed
|
||||
- [ ] Not editing hardware-configuration.nix
|
||||
- [ ] No duplicate package declarations
|
||||
- [ ] Following nixpkgs for dependency inputs
|
||||
- [ ] System config separate from user config
|
||||
- [ ] Tested with rebuild
|
||||
- [ ] Using Nix paths, not absolute paths
|
||||
- [ ] Correct input references for flake packages
|
||||
188
.agents/skills/nixos-best-practices/rules/flakes-structure.md
Normal file
188
.agents/skills/nixos-best-practices/rules/flakes-structure.md
Normal file
@@ -0,0 +1,188 @@
|
||||
---
|
||||
title: Flakes Configuration Structure
|
||||
impact: CRITICAL
|
||||
impactDescription: Foundation of flake-based NixOS configurations
|
||||
tags: flakes,special-args,inputs,multiple-hosts
|
||||
---
|
||||
|
||||
|
||||
## Why This Matters
|
||||
|
||||
A well-structured flake.nix makes it easy to manage multiple hosts, share common configurations, and maintain the codebase. Poor structure leads to duplication and confusion.
|
||||
|
||||
## Core Structure
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "My NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
# Add other flake inputs here
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs: {
|
||||
nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/hostname ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Special Args Pattern
|
||||
|
||||
Pass `inputs` via `specialArgs` to make flake inputs available in modules:
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Forgetting specialArgs
|
||||
outputs = { self, nixpkgs, home-manager }:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
modules = [ ./hosts/myhost ]; # inputs not available!
|
||||
};
|
||||
}
|
||||
|
||||
# ✅ CORRECT: Using specialArgs
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/myhost ]; # inputs available!
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Then use in modules:
|
||||
|
||||
```nix
|
||||
# hosts/myhost/default.nix
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
# Can now use inputs.*
|
||||
imports = [
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Input Following
|
||||
|
||||
Set `inputs.nixpkgs.follows` to avoid duplicate nixpkgs instances:
|
||||
|
||||
```nix
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
# ❌ WRONG: Doesn't follow, creates duplicate nixpkgs
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
|
||||
# ✅ CORRECT: Follows nixpkgs, uses same instance
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
```
|
||||
|
||||
## Multiple Hosts Pattern
|
||||
|
||||
```nix
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs: {
|
||||
# Define multiple hosts
|
||||
nixosConfigurations.laptop = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/laptop ];
|
||||
};
|
||||
|
||||
nixosConfigurations.desktop = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/desktop ];
|
||||
};
|
||||
|
||||
nixosConfigurations.server = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/server ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## System-Specific Packages
|
||||
|
||||
Pass system-specific args like `pkgs-stable`:
|
||||
|
||||
```nix
|
||||
outputs = { self, nixpkgs, nixpkgs-stable, home-manager, ... }@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
in
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = {
|
||||
inherit inputs system;
|
||||
pkgs-stable = import inputs.nixpkgs-stable {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Usage in host config:
|
||||
|
||||
```nix
|
||||
# hosts/myhost/default.nix
|
||||
{ inputs, pkgs, pkgs-stable, system, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
unstable-package # From nixos-unstable
|
||||
];
|
||||
|
||||
# Or use stable version
|
||||
environment.systemPackages = with pkgs-stable; [
|
||||
stable-package
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
1. **Not using @inputs pattern**: Forgetting to capture all inputs in a set makes it impossible to reference new inputs without updating the function signature.
|
||||
|
||||
2. **Missing specialArgs**: Inputs won't be available in modules without `specialArgs = { inherit inputs; }`.
|
||||
|
||||
3. **Hardcoded system**: Avoid hardcoding `x86_64-linux` multiple times. Define once and reuse.
|
||||
|
||||
4. **Not following nixpkgs**: Leads to multiple nixpkgs evaluations, slower builds, and potential inconsistencies.
|
||||
|
||||
## Quick Template
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
# Add more inputs here
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs: {
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
system = "x86_64-linux";
|
||||
pkgs-stable = import inputs.nixpkgs-stable {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
296
.agents/skills/nixos-best-practices/rules/host-organization.md
Normal file
296
.agents/skills/nixos-best-practices/rules/host-organization.md
Normal file
@@ -0,0 +1,296 @@
|
||||
---
|
||||
title: Host Configuration Organization
|
||||
impact: HIGH
|
||||
impactDescription: Prevents configuration chaos across multiple hosts
|
||||
tags: hosts,modules,base-config,directory-structure
|
||||
---
|
||||
|
||||
|
||||
## Why This Matters
|
||||
|
||||
Proper host configuration organization prevents duplication, makes maintenance easier, and ensures consistency across multiple machines.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
nixos-config/
|
||||
├── flake.nix # Top-level flake
|
||||
├── hosts/
|
||||
│ ├── laptop/
|
||||
│ │ ├── default.nix # Host-specific config
|
||||
│ │ ├── hardware-configuration.nix # Generated (don't edit)
|
||||
│ │ └── home.nix # Home Manager config
|
||||
│ ├── desktop/
|
||||
│ │ ├── default.nix
|
||||
│ │ ├── hardware-configuration.nix
|
||||
│ │ └── home.nix
|
||||
│ └── base.nix # Shared by all hosts (optional)
|
||||
├── modules/ # Reusable NixOS modules
|
||||
├── overlays/ # Custom overlays
|
||||
├── home-manager/ # Shared Home Manager configs
|
||||
│ ├── shell/
|
||||
│ ├── applications/
|
||||
│ └── common.nix
|
||||
└── secrets/ # Age-encrypted secrets
|
||||
```
|
||||
|
||||
## Host Configuration Pattern
|
||||
|
||||
### Incorrect: Everything in one file
|
||||
|
||||
```nix
|
||||
# hosts/laptop/default.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
# Hardware config (copied from hardware-configuration.nix)
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" ];
|
||||
# ... 50 lines of hardware config ...
|
||||
|
||||
# Network config
|
||||
networking.hostName = "laptop";
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
# User config
|
||||
users.users.john = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "networkmanager" ];
|
||||
};
|
||||
|
||||
# Packages
|
||||
environment.systemPackages = with pkgs; [ vim git wget ];
|
||||
|
||||
# Services
|
||||
services.openssh.enable = true;
|
||||
|
||||
# Home Manager
|
||||
imports = [
|
||||
./home.nix # Or inline the entire home config
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Problems:**
|
||||
- Hardware config duplicated (should import hardware-configuration.nix)
|
||||
- User config duplicated across hosts
|
||||
- No shared configuration
|
||||
- Hard to maintain
|
||||
|
||||
### Correct: Modular structure
|
||||
|
||||
```nix
|
||||
# hosts/laptop/default.nix
|
||||
{ inputs, pkgs, pkgs-stable, system, ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix # Import hardware config
|
||||
../base.nix # Import shared config
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.john = import ./home.nix;
|
||||
home-manager.extraSpecialArgs = {
|
||||
inherit inputs pkgs-stable system;
|
||||
};
|
||||
nixpkgs.overlays = [ inputs.some-overlay.overlays.default ];
|
||||
}
|
||||
];
|
||||
|
||||
# Host-specific config only
|
||||
networking.hostName = "laptop";
|
||||
}
|
||||
```
|
||||
|
||||
## Shared Base Configuration
|
||||
|
||||
```nix
|
||||
# hosts/base.nix
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
# Network
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
# Time and locale
|
||||
time.timeZone = "America/New_York";
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
|
||||
# Users (shared across all hosts)
|
||||
users.users.john = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "networkmanager" ];
|
||||
};
|
||||
|
||||
# Common packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
git
|
||||
wget
|
||||
tmux
|
||||
];
|
||||
|
||||
# Common services
|
||||
services.openssh.enable = true;
|
||||
|
||||
# Nix settings
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
}
|
||||
```
|
||||
|
||||
## Hardware Configuration
|
||||
|
||||
```nix
|
||||
# hosts/laptop/default.nix
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix # Generated by nixos-generate-config
|
||||
../base.nix
|
||||
# ...
|
||||
];
|
||||
|
||||
networking.hostName = "laptop";
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** Don't edit `hardware-configuration.nix` manually. It's generated by `nixos-generate-config` and should be replaced when hardware changes.
|
||||
|
||||
## Home Manager Configuration
|
||||
|
||||
### Host-specific home.nix
|
||||
|
||||
```nix
|
||||
# hosts/laptop/home.nix
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
../../home-manager/shell
|
||||
../../home-manager/applications
|
||||
../../home-manager/common.nix
|
||||
];
|
||||
|
||||
# Host-specific user config
|
||||
home.packages = with pkgs; [
|
||||
laptop-specific-package
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Shared Home Manager configs
|
||||
|
||||
```nix
|
||||
# home-manager/shell/default.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./fish
|
||||
./neovim
|
||||
./git
|
||||
];
|
||||
}
|
||||
|
||||
# home-manager/common.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
jq
|
||||
ripgrep
|
||||
fzf
|
||||
];
|
||||
|
||||
programs.git.enable = true;
|
||||
programs.git.userName = "John Doe";
|
||||
programs.git.userEmail = "john@example.com";
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Hosts Example
|
||||
|
||||
```nix
|
||||
# flake.nix
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs: {
|
||||
nixosConfigurations.laptop = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/laptop ];
|
||||
};
|
||||
|
||||
nixosConfigurations.desktop = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/desktop ];
|
||||
};
|
||||
|
||||
nixosConfigurations.server = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [ ./hosts/server ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Each host uses the same `base.nix` but can override settings:
|
||||
|
||||
```nix
|
||||
# hosts/server/default.nix
|
||||
{ ... }:
|
||||
{
|
||||
imports = [ ../base.nix ./hardware-configuration.nix ];
|
||||
|
||||
# Override time zone for server
|
||||
time.timeZone = "UTC";
|
||||
|
||||
# Add server-specific packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
htop
|
||||
iotop
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Module Pattern
|
||||
|
||||
For reusable functionality, create modules:
|
||||
|
||||
```nix
|
||||
# modules/docker.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
enableOnBoot = true;
|
||||
};
|
||||
|
||||
users.users.john.extraGroups = [ "docker" ];
|
||||
}
|
||||
```
|
||||
|
||||
Use in host config:
|
||||
|
||||
```nix
|
||||
# hosts/laptop/default.nix
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
../base.nix
|
||||
../../modules/docker # Import module
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
1. **Editing hardware-configuration.nix**: Changes are lost when regenerating. Put host-specific config in `default.nix` instead.
|
||||
|
||||
2. **Duplicating config across hosts**: Use `base.nix` or modules for shared configuration.
|
||||
|
||||
3. **Not separating host-specific and user-specific**: Keep host config in `hosts/*/default.nix`, user config in `home.nix` or `home-manager/`.
|
||||
|
||||
4. **Mixing concerns**: Don't put shell config in system packages. Use Home Manager for user-level packages.
|
||||
|
||||
## Quick Checklist
|
||||
|
||||
- [ ] Each host imports hardware-configuration.nix
|
||||
- [ ] Shared config in base.nix or modules
|
||||
- [ ] Home Manager configured in host file
|
||||
- [ ] Host-specific settings only in host's default.nix
|
||||
- [ ] User config in home.nix or home-manager/
|
||||
- [ ] No duplication of hardware config
|
||||
- [ ] No duplication of user config
|
||||
132
.agents/skills/nixos-best-practices/rules/overlay-scope.md
Normal file
132
.agents/skills/nixos-best-practices/rules/overlay-scope.md
Normal file
@@ -0,0 +1,132 @@
|
||||
---
|
||||
title: Overlay Scope and useGlobalPkgs
|
||||
impact: CRITICAL
|
||||
impactDescription: The most common issue: overlays don't apply with useGlobalPkgs=true
|
||||
tags: overlay,useglobalpkgs,home-manager,scope
|
||||
---
|
||||
|
||||
|
||||
## Why This Matters
|
||||
|
||||
When using Home Manager with NixOS, the `useGlobalPkgs` setting determines where overlay definitions must be placed. Defining overlays in the wrong location means they simply don't apply, leading to "package not found" errors even when the overlay syntax is correct.
|
||||
|
||||
## The Problem
|
||||
|
||||
When `useGlobalPkgs = true`, Home Manager uses NixOS's global `pkgs` instance. Overlays defined in `home.nix` are ignored because Home Manager isn't creating its own `pkgs` - it's using the system one.
|
||||
|
||||
## Incorrect: Overlay in home.nix with useGlobalPkgs=true
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = true; # Using system pkgs
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
}
|
||||
|
||||
# home-manager/home.nix
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{
|
||||
# ❌ This overlay is IGNORED when useGlobalPkgs = true!
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
|
||||
home.packages = with pkgs; [
|
||||
claude-code # Error: attribute 'claude-code' not found
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Why it fails:** When `useGlobalPkgs = true`, the `nixpkgs.overlays` line in `home.nix` has no effect. Home Manager isn't creating its own `pkgs`, so it can't apply overlays to one.
|
||||
|
||||
## Correct: Overlay in host home-manager block
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
home-manager.extraSpecialArgs = { inherit inputs pkgs-stable system; };
|
||||
# ✅ Overlay defined HERE affects the global pkgs
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
}
|
||||
|
||||
# home-manager/home.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
# No overlay definition needed here
|
||||
home.packages = with pkgs; [
|
||||
claude-code # ✅ Works! Found via overlay
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Why it works:** The overlay is defined where Home Manager configures the `pkgs` instance it will use. When `useGlobalPkgs = true`, this means the overlay is applied to the system's package set.
|
||||
|
||||
## Alternative: Set useGlobalPkgs=false
|
||||
|
||||
If you want to define overlays in `home.nix`, set `useGlobalPkgs = false`:
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
home-manager.useGlobalPkgs = false; # Home Manager creates own pkgs
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.chumeng = import ./home.nix;
|
||||
}
|
||||
|
||||
# home-manager/home.nix
|
||||
{ pkgs, inputs, ... }:
|
||||
{
|
||||
# ✅ This works when useGlobalPkgs = false
|
||||
nixpkgs.overlays = [ inputs.claude-code.overlays.default ];
|
||||
|
||||
home.packages = with pkgs; [
|
||||
claude-code # ✅ Works! Found via overlay
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**Trade-off:** This creates a separate package set for Home Manager, which means packages are built twice (once for system, once for Home Manager). Only use this when you truly need separate package sets.
|
||||
|
||||
## Decision Matrix
|
||||
|
||||
| Your Need | useGlobalPkgs | Overlay Location |
|
||||
|-----------|---------------|------------------|
|
||||
| Single-user system, efficiency | `true` | Host home-manager block |
|
||||
| Multi-user, different packages per user | `false` | User's home.nix |
|
||||
| Custom packages system-wide | `true` | System nixpkgs.overlays |
|
||||
| Quick prototype | `false` | User's home.nix |
|
||||
|
||||
## Verification
|
||||
|
||||
After adding an overlay, verify it works:
|
||||
|
||||
```bash
|
||||
# Build the configuration
|
||||
nixos-rebuild build --flake .#hostname
|
||||
|
||||
# Check if package is available
|
||||
./result/sw/bin/package-name --version
|
||||
|
||||
# Or use nix repl to verify
|
||||
nix repl
|
||||
nix-repl> :l flake.nix
|
||||
nix-repl> homeConfigs.hostname.config.home-manager.users.username.pkgs.package-name
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
1. **Adding overlay both places**: Don't define the same overlay in both host config AND home.nix. It will apply twice and may cause conflicts.
|
||||
|
||||
2. **Forgetting to pass inputs**: If your overlay needs `inputs.*`, ensure `inputs` is in `extraSpecialArgs`:
|
||||
```nix
|
||||
home-manager.extraSpecialArgs = { inherit inputs; };
|
||||
```
|
||||
|
||||
3. **Not rebuilding system**: Overlays defined in host config require full system rebuild, not just `home-manager switch`.
|
||||
|
||||
## References
|
||||
|
||||
- [Home Manager Manual - useGlobalPkgs](https://nix-community.github.io/home-manager/options.html#opt-home-manager.useGlobalPkgs)
|
||||
- [NixOS Manual - Overlays](https://nixos.org/manual/nixos/stable/options#opt-nixpkgs.overlays)
|
||||
@@ -0,0 +1,264 @@
|
||||
---
|
||||
title: Package Installation Best Practices
|
||||
impact: HIGH
|
||||
impactDescription: Avoids conflicts and confusion about where to install packages
|
||||
tags: packages,system,user,home-manager
|
||||
---
|
||||
|
||||
|
||||
## Why This Matters
|
||||
|
||||
Knowing where and how to install packages prevents conflicts, ensures proper updates, and maintains separation between system and user packages.
|
||||
|
||||
## System vs User Packages
|
||||
|
||||
### System Packages (NixOS)
|
||||
|
||||
Use for:
|
||||
- System services (servers, daemons)
|
||||
- Packages needed by all users
|
||||
- Hardware-related packages (drivers, firmware)
|
||||
- System-wide utilities
|
||||
|
||||
```nix
|
||||
# hosts/base.nix or host-specific default.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # Available to all users
|
||||
git
|
||||
wget
|
||||
tmux
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### User Packages (Home Manager)
|
||||
|
||||
Use for:
|
||||
- User-specific applications
|
||||
- Desktop applications
|
||||
- Development tools (user-specific)
|
||||
- Shell configurations
|
||||
|
||||
```nix
|
||||
# home-manager/home.nix or sub-configs
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
vscode # User-specific
|
||||
chrome
|
||||
slack
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Installing from Different Nixpkgs Channels
|
||||
|
||||
### Using unstable packages
|
||||
|
||||
```nix
|
||||
# flake.nix - default is unstable
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||
};
|
||||
|
||||
# Host config
|
||||
{ pkgs, pkgs-stable, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # From unstable (default)
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs-stable; [
|
||||
vim # From stable
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Using overlays for custom packages
|
||||
|
||||
```nix
|
||||
# hosts/home/default.nix
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
inputs.custom-overlay.overlays.default
|
||||
];
|
||||
}
|
||||
|
||||
# Now packages from overlay are available
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
custom-package # From overlay
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Conditional Package Installation
|
||||
|
||||
### Based on host
|
||||
|
||||
```nix
|
||||
# hosts/laptop/default.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
powertop # Laptop-specific
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Based on GUI environment
|
||||
|
||||
```nix
|
||||
# hosts/base.nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs;
|
||||
(if config.services.xserver.enable then [
|
||||
firefox
|
||||
dmenu
|
||||
] else [
|
||||
tmux
|
||||
htop
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### Based on architecture
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs;
|
||||
(if pkgs.system == "x86_64-linux" then [
|
||||
docker-compose
|
||||
] else [
|
||||
podman
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Wrapper Scripts
|
||||
|
||||
Modify package behavior with wrappers:
|
||||
|
||||
```nix
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
(symlinkJoin {
|
||||
name = "google-chrome-with-flags";
|
||||
paths = [ google-chrome ];
|
||||
buildInputs = [ makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/google-chrome-stable \
|
||||
--add-flags "--disable-gpu" \
|
||||
--add-flags "--disable-features=UseChromeOSDirectVideoDecoder"
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
### Installing user packages system-wide
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: User-specific package in system config
|
||||
environment.systemPackages = with pkgs; [
|
||||
vscode # Should be in Home Manager
|
||||
slack # Should be in Home Manager
|
||||
];
|
||||
|
||||
# ✅ CORRECT: User packages in Home Manager
|
||||
# home-manager/home.nix
|
||||
home.packages = with pkgs; [
|
||||
vscode
|
||||
slack
|
||||
];
|
||||
```
|
||||
|
||||
### Installing packages in wrong location
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: System package in Home Manager
|
||||
# home-manager/home.nix
|
||||
home.packages = with pkgs; [
|
||||
docker # Should be system package (needs service)
|
||||
];
|
||||
|
||||
# ✅ CORRECT: System package in system config
|
||||
# hosts/base.nix
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker
|
||||
];
|
||||
virtualisation.docker.enable = true;
|
||||
```
|
||||
|
||||
### Not using lists for multiple packages
|
||||
|
||||
```nix
|
||||
# ❌ WRONG: Individual statements
|
||||
environment.systemPackages = [ pkgs.vim ];
|
||||
environment.systemPackages = [ pkgs.git ]; # Overwrites previous!
|
||||
|
||||
# ✅ CORRECT: Single list
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
git
|
||||
];
|
||||
```
|
||||
|
||||
## Package Updates
|
||||
|
||||
### Update all packages
|
||||
|
||||
```bash
|
||||
nix flake update
|
||||
nixos-rebuild switch --flake .#hostname
|
||||
```
|
||||
|
||||
### Update specific input
|
||||
|
||||
```bash
|
||||
nix flake lock update-input nixpkgs
|
||||
nixos-rebuild switch --flake .#hostname
|
||||
```
|
||||
|
||||
### Pin to specific version
|
||||
|
||||
```nix
|
||||
# flake.nix
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; # Pinned to release
|
||||
# Or specific commit:
|
||||
# nixpkgs.url = "github:nixos/nixpkgs/a1b2c3d...";
|
||||
};
|
||||
```
|
||||
|
||||
## Finding Packages
|
||||
|
||||
```bash
|
||||
# Search for package
|
||||
nix search nixpkgs package-name
|
||||
|
||||
# Get package info
|
||||
nix eval nixpkgs#legacyPackages.x86_64-linux.package-name.meta.description
|
||||
|
||||
# Check what package provides a file
|
||||
nix-locate bin/vim
|
||||
```
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Package Type | Location | Example |
|
||||
|-------------|----------|---------|
|
||||
| System service | system config | `virtualisation.docker.enable = true` |
|
||||
| System utility | system config | `environment.systemPackages = [ vim ]` |
|
||||
| User app | Home Manager | `home.packages = [ vscode ]` |
|
||||
| Development tool | Either (user usually) | `home.packages = [ nodejs ]` |
|
||||
| Driver/firmware | system config | `hardware.graphics.enable = true` |
|
||||
326
.agents/skills/nixos-best-practices/rules/troubleshooting.md
Normal file
326
.agents/skills/nixos-best-practices/rules/troubleshooting.md
Normal file
@@ -0,0 +1,326 @@
|
||||
---
|
||||
title: Troubleshooting Configuration Issues
|
||||
impact: MEDIUM
|
||||
impactDescription: Systematic debugging approach for configuration issues
|
||||
tags: debugging,errors,troubleshooting,verification
|
||||
---
|
||||
|
||||
|
||||
## Why This Matters
|
||||
|
||||
Knowing how to systematically debug NixOS configurations saves hours of frustration and prevents making random changes hoping something works.
|
||||
|
||||
## General Approach
|
||||
|
||||
Follow this order when debugging:
|
||||
|
||||
1. **Read error messages completely** - They usually tell you exactly what's wrong
|
||||
2. **Verify syntax** - Check for missing brackets, quotes, commas
|
||||
3. **Validate config** - Use `nixos-rebuild test` first
|
||||
4. **Check scope** - Is overlay/module in correct location?
|
||||
5. **Trace dependencies** - Are required inputs/imports present?
|
||||
|
||||
## Common Error Patterns
|
||||
|
||||
### "undefined variable 'inputs'"
|
||||
|
||||
**Cause:** `inputs` not passed via `specialArgs`.
|
||||
|
||||
**Fix:**
|
||||
```nix
|
||||
# flake.nix
|
||||
outputs = { self, nixpkgs, ... }@inputs:
|
||||
{
|
||||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs; }; # Add this
|
||||
modules = [ ./hosts/myhost ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### "attribute 'package-name' not found"
|
||||
|
||||
**Cause:** Package doesn't exist, or overlay not applied.
|
||||
|
||||
**Debug:**
|
||||
```bash
|
||||
# Check if package exists in nixpkgs
|
||||
nix search nixpkgs package-name
|
||||
|
||||
# Check if overlay is defined
|
||||
nix eval .#nixosConfigurations.myhost.config.nixpkgs.overlays
|
||||
|
||||
# Verify package in your config's pkgs
|
||||
nix repl
|
||||
nix-repl> :l flake.nix
|
||||
nix-repl> myhost.config.environment.systemPackages
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- If overlay issue: Move to correct location (see [overlay-scope.md](overlay-scope.md))
|
||||
- If missing package: Use correct package name or add overlay
|
||||
|
||||
### "error: The option 'some.option' does not exist"
|
||||
|
||||
**Cause:** Typo in option name, or option not available in your nixpkgs version.
|
||||
|
||||
**Debug:**
|
||||
```bash
|
||||
# Search for option
|
||||
nixos-options | grep some-option
|
||||
|
||||
# Check option in current config
|
||||
nix eval .#nixosConfigurations.myhost.config.some.option
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- Check option name spelling
|
||||
- Verify nixpkgs version has this option
|
||||
- Read option documentation for correct usage
|
||||
|
||||
### "infinite recursion"
|
||||
|
||||
**Cause:** Circular dependency in config.
|
||||
|
||||
**Debug:**
|
||||
```bash
|
||||
# Use --show-trace to see where
|
||||
nixos-rebuild build --flake .#hostname --show-trace
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- Look for mutual dependencies
|
||||
- Use `mkBefore`/`mkAfter` for ordering
|
||||
- Break circular reference
|
||||
|
||||
### "hash mismatch" in flake.lock
|
||||
|
||||
**Cause:** Local changes or outdated lock file.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Update flake lock
|
||||
nix flake update
|
||||
|
||||
# Or update specific input
|
||||
nix flake lock update-input nixpkgs
|
||||
```
|
||||
|
||||
## Overlay Not Applied
|
||||
|
||||
**Symptom:** Package from overlay not found.
|
||||
|
||||
**Debug steps:**
|
||||
|
||||
1. Check overlay definition:
|
||||
```bash
|
||||
nix eval .#nixosConfigurations.myhost.config.nixpkgs.overlays
|
||||
```
|
||||
|
||||
2. Check overlay location:
|
||||
```bash
|
||||
# If useGlobalPkgs = true, overlay should be here:
|
||||
grep -r "nixpkgs.overlays" hosts/myhost/default.nix
|
||||
|
||||
# NOT here:
|
||||
grep -r "nixpkgs.overlays" home-manager/home.nix
|
||||
```
|
||||
|
||||
3. Verify overlay input:
|
||||
```bash
|
||||
nix flake metadata
|
||||
# Look for your overlay input
|
||||
```
|
||||
|
||||
**Fix:** See [overlay-scope.md](overlay-scope.md)
|
||||
|
||||
## Configuration Changes Not Applying
|
||||
|
||||
**Symptom:** Edit config, rebuild, but nothing changes.
|
||||
|
||||
**Debug steps:**
|
||||
|
||||
1. Verify rebuild ran successfully:
|
||||
```bash
|
||||
sudo nixos-rebuild switch --flake .#hostname
|
||||
# Look for "success" message
|
||||
```
|
||||
|
||||
2. Check current generation:
|
||||
```bash
|
||||
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
|
||||
```
|
||||
|
||||
3. Verify new generation is active:
|
||||
```bash
|
||||
sudo nixos-version
|
||||
# Should show timestamp of recent rebuild
|
||||
```
|
||||
|
||||
4. Check if option actually changed:
|
||||
```bash
|
||||
nix eval .#nixosConfigurations.myhost.config.some.option
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- Ensure rebuild succeeded
|
||||
- Check if service needs restart: `systemctl restart service-name`
|
||||
- For Home Manager: `home-manager switch` (or `sudo nixos-rebuild switch` if integrated)
|
||||
|
||||
## Build Fails with "store collision"
|
||||
|
||||
**Symptom:** Multiple packages trying to write to same path.
|
||||
|
||||
**Cause:** Usually duplicate package declarations or conflicting modules.
|
||||
|
||||
**Fix:**
|
||||
- Remove duplicate package declarations
|
||||
- Check for conflicting modules
|
||||
- Use `--show-trace` to identify conflicting packages
|
||||
|
||||
## Verification Commands
|
||||
|
||||
### Check configuration without building
|
||||
|
||||
```bash
|
||||
# Check syntax
|
||||
nix flake check
|
||||
|
||||
# Dry run build
|
||||
nixos-rebuild build --flake .#hostname --dry-run
|
||||
|
||||
# Evaluate specific option
|
||||
nix eval .#nixosConfigurations.myhost.config.environment.systemPackages
|
||||
```
|
||||
|
||||
### Test configuration safely
|
||||
|
||||
```bash
|
||||
# Build without activating
|
||||
nixos-rebuild build --flake .#hostname
|
||||
|
||||
# Test configuration (rollback on reboot)
|
||||
nixos-rebuild test --flake .#hostname
|
||||
|
||||
# Switch (persistent)
|
||||
nixos-rebuild switch --flake .#hostname
|
||||
```
|
||||
|
||||
### Compare generations
|
||||
|
||||
```bash
|
||||
# List system generations
|
||||
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
|
||||
|
||||
# List Home Manager generations
|
||||
home-manager generations
|
||||
|
||||
# Compare configurations
|
||||
sudo nix diff-closures /nix/var/nix/profiles/system-*-link
|
||||
```
|
||||
|
||||
## Useful Tools
|
||||
|
||||
### nix repl
|
||||
|
||||
```bash
|
||||
nix repl
|
||||
nix-repl> :l flake.nix # Load flake
|
||||
nix-repl> myhost.config.environment.systemPackages # Access config
|
||||
nix-repl> :b myhost.config.system.build.toplevel # Build
|
||||
```
|
||||
|
||||
### nixos-version
|
||||
|
||||
```bash
|
||||
# Check current system version
|
||||
nixos-version
|
||||
|
||||
# Should show something like:
|
||||
# 25.05.20250123.abc1234
|
||||
```
|
||||
|
||||
### journalctl
|
||||
|
||||
```bash
|
||||
# Check service logs for failures
|
||||
sudo journalctl -xe
|
||||
|
||||
# Check NixOS rebuild logs
|
||||
sudo journalctl -u nixos-rebuild
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
When asking for help, provide:
|
||||
|
||||
1. **Full error message** (not just "it doesn't work")
|
||||
2. **Minimal reproducible example**
|
||||
3. **NixOS version**: `nixos-version`
|
||||
4. **Relevant config files**
|
||||
5. **What you've tried**
|
||||
6. **Expected vs actual behavior**
|
||||
|
||||
Useful commands:
|
||||
```bash
|
||||
# Show system info
|
||||
nixos-version
|
||||
uname -a
|
||||
|
||||
# Show flake info
|
||||
nix flake metadata
|
||||
|
||||
# Export config for sharing
|
||||
nixos-rebuild build --flake .#hostname
|
||||
nix-store -qR result > system-closure
|
||||
```
|
||||
|
||||
## Common Debugging Workflows
|
||||
|
||||
### Package not found
|
||||
|
||||
```bash
|
||||
# 1. Search for package
|
||||
nix search nixpkgs package-name
|
||||
|
||||
# 2. Check if it's available for your system
|
||||
nix eval nixpkgs#legacyPackages.x86_64-linux.package-name
|
||||
|
||||
# 3. Check your overlays
|
||||
nix eval .#nixosConfigurations.myhost.config.nixpkgs.overlays
|
||||
|
||||
# 4. Check if overlay provides it
|
||||
nix eval .#packages.x86_64-linux.package-name
|
||||
```
|
||||
|
||||
### Overlay not applying
|
||||
|
||||
```bash
|
||||
# 1. Verify overlay is defined
|
||||
grep -r "overlays" hosts/myhost/
|
||||
|
||||
# 2. Check useGlobalPkgs setting
|
||||
grep "useGlobalPkgs" hosts/myhost/default.nix
|
||||
|
||||
# 3. Evaluate overlay
|
||||
nix eval .#nixosConfigurations.myhost.config.nixpkgs.overlays
|
||||
|
||||
# 4. Test package directly
|
||||
nix build .#packages.x86_64-linux.package-name
|
||||
```
|
||||
|
||||
### Service not starting
|
||||
|
||||
```bash
|
||||
# 1. Check service status
|
||||
systemctl status service-name
|
||||
|
||||
# 2. View service logs
|
||||
journalctl -xeu service-name
|
||||
|
||||
# 3. Check service config
|
||||
nixos-rebuild build --flake .#hostname --show-trace
|
||||
|
||||
# 4. Test service manually
|
||||
/path/to/service-binary --verbose
|
||||
```
|
||||
1
.roo/skills/find-skills
Symbolic link
1
.roo/skills/find-skills
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.agents/skills/find-skills
|
||||
1
.roo/skills/nix-best-practices
Symbolic link
1
.roo/skills/nix-best-practices
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.agents/skills/nix-best-practices
|
||||
1
.roo/skills/nixos-best-practices
Symbolic link
1
.roo/skills/nixos-best-practices
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.agents/skills/nixos-best-practices
|
||||
Reference in New Issue
Block a user