Compare commits
1 Commits
8b0eccc574
...
34043a7efc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34043a7efc |
@@ -1,32 +0,0 @@
|
|||||||
# This is an example configuration file
|
|
||||||
# To learn more, see the full config.yaml reference: https://docs.continue.dev/reference
|
|
||||||
name: ollama
|
|
||||||
version: 1.0.0
|
|
||||||
schema: v1
|
|
||||||
# Define which models can be used
|
|
||||||
# https://docs.continue.dev/customization/models
|
|
||||||
models:
|
|
||||||
- name: StarCoder2 Local
|
|
||||||
provider: ollama
|
|
||||||
model: starcoder2:7b
|
|
||||||
modelTimeout: "5s"
|
|
||||||
roles:
|
|
||||||
- autocomplete
|
|
||||||
autocompleteOptions:
|
|
||||||
useCache: true
|
|
||||||
useImports: true
|
|
||||||
useRecentlyEdited: true
|
|
||||||
- name: Nomic Embed Local
|
|
||||||
provider: ollama
|
|
||||||
model: nomic-embed-text:latest
|
|
||||||
roles:
|
|
||||||
- embed
|
|
||||||
- name: Autodetect
|
|
||||||
provider: ollama
|
|
||||||
model: AUTODETECT
|
|
||||||
defaultCompletionOptions:
|
|
||||||
contextLength: 64000
|
|
||||||
# MCP Servers that Continue can access
|
|
||||||
# https://docs.continue.dev/customization/mcp-tools
|
|
||||||
mcpServers:
|
|
||||||
- uses: anthropic/memory-mcp
|
|
||||||
698
.github/copilot-instructions.md
vendored
698
.github/copilot-instructions.md
vendored
@@ -1,698 +0,0 @@
|
|||||||
# Nix Dotfiles Repository Guide
|
|
||||||
|
|
||||||
This repository contains NixOS configurations for personal infrastructure. The setup is organized around a flake-based structure with per-system configurations and user-specific settings.
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
- `flake.nix` - Main flake definition with inputs and outputs
|
|
||||||
- `systems/` - Per-system configurations (e.g., `artemision`, `palatine-hill`)
|
|
||||||
- `users/` - Per-user configurations using home-manager
|
|
||||||
- `modules/` - Reusable Nix modules for common services
|
|
||||||
- `lib/` - Custom Nix library functions
|
|
||||||
- `hydra/` - Hydra CI/CD configuration
|
|
||||||
- `secrets/` - SOPS encrypted secrets
|
|
||||||
|
|
||||||
## Key Concepts
|
|
||||||
|
|
||||||
### System Configuration
|
|
||||||
|
|
||||||
Each system has its own directory under `systems/` containing:
|
|
||||||
|
|
||||||
- `configuration.nix` - Main system configuration
|
|
||||||
- Component modules (audio.nix, desktop.nix, etc.)
|
|
||||||
- Hardware-specific configurations
|
|
||||||
|
|
||||||
### User Configuration
|
|
||||||
|
|
||||||
User configurations are in `users/<username>/`:
|
|
||||||
|
|
||||||
- `home.nix` - Home-manager configuration using `home.packages` and imports
|
|
||||||
- `secrets.yaml` - SOPS-encrypted secrets using age encryption
|
|
||||||
- `non-server.nix` - Desktop-specific configurations
|
|
||||||
|
|
||||||
### Nix Patterns
|
|
||||||
|
|
||||||
1. **Module-based approach**: Uses Nix modules for organizing configuration
|
|
||||||
1. **Home-manager integration**: User environment managed via home-manager
|
|
||||||
1. **SOPS secrets**: Secrets managed with SOPS and age encryption
|
|
||||||
1. **Flake-based**: Uses flakes for reproducible builds and development environments
|
|
||||||
1. **Multi-system support**: Supports multiple machines with different configurations
|
|
||||||
1. **Dynamic configuration generation**: Modules in the `modules/` directory are automatically imported into all systems (can be overridden per system). New systems are automatically discovered by `genSystems()`
|
|
||||||
|
|
||||||
### Modern Nix Features
|
|
||||||
|
|
||||||
This repository uses modern Nix features including:
|
|
||||||
|
|
||||||
- **Flakes**: Enabled via `flake` experimental feature
|
|
||||||
- **Nix Command**: Enabled via `nix-command` experimental feature
|
|
||||||
- **Blake3 Hashes**: Enabled via `blake3-hashes` experimental feature
|
|
||||||
- **Git Hashing**: Enabled via `git-hashing` experimental feature
|
|
||||||
- **Verified Fetches**: Enabled via `verified-fetches` experimental feature
|
|
||||||
|
|
||||||
### Key Commands
|
|
||||||
|
|
||||||
- `nh os switch` - Apply system configuration (using nix-community/nh)
|
|
||||||
- `nh home switch` - Apply user configuration (using nix-community/nh)
|
|
||||||
- `nh os build` - Build a specific system (using nix-community/nh)
|
|
||||||
- `nix build .#<system>` - Build a specific system
|
|
||||||
- `nix run .#<system>` - Run a specific system
|
|
||||||
- `nix flake update` - Update flake inputs
|
|
||||||
|
|
||||||
### Development Workflow
|
|
||||||
|
|
||||||
1. Make changes to system or user configuration
|
|
||||||
1. Test with `nh os switch` or `nh home switch`
|
|
||||||
1. For CI/CD, Hydra automatically builds and tests changes
|
|
||||||
1. Secrets are managed with SOPS and age keys
|
|
||||||
|
|
||||||
### Important Files
|
|
||||||
|
|
||||||
- `flake.nix` - Main entry point for the flake
|
|
||||||
- `systems/artemision/configuration.nix` - Example system configuration
|
|
||||||
- `users/alice/home.nix` - Example user configuration
|
|
||||||
- `modules/base.nix` - Base module with common settings
|
|
||||||
- `hydra/jobsets.nix` - Hydra CI configuration
|
|
||||||
|
|
||||||
### External Dependencies
|
|
||||||
|
|
||||||
- NixOS unstable channel
|
|
||||||
- Nixpkgs unstable channel
|
|
||||||
- SOPS for secrets management
|
|
||||||
- age for encryption
|
|
||||||
- home-manager for user environments
|
|
||||||
- nh (nix-community/nh) for simplified Nix operations
|
|
||||||
|
|
||||||
### Nix MCP Server
|
|
||||||
|
|
||||||
- Use the nix MCP server for looking up package names and options
|
|
||||||
- Specify `unstable` channel if the channel is specifiable (e.g., for `pkgs.<package-name>`)
|
|
||||||
|
|
||||||
## Dynamic Configuration System (lib/systems.nix)
|
|
||||||
|
|
||||||
This repository automatically generates NixOS system configurations based on the folder structure. Understanding how `constructSystem` and `genSystems` work is essential when adding new systems or global modules.
|
|
||||||
|
|
||||||
### How Configuration Generation Works
|
|
||||||
|
|
||||||
The process happens in three stages:
|
|
||||||
|
|
||||||
**Stage 1: Discovery** (`flake.nix` → `genSystems`)
|
|
||||||
|
|
||||||
- `flake.nix` calls `genSystems inputs outputs src (src + "/systems")`
|
|
||||||
- `genSystems` scans the `systems/` directory and lists all subdirectories
|
|
||||||
- Each subdirectory name becomes a system hostname (e.g., `artemision`, `palatine-hill`)
|
|
||||||
|
|
||||||
**Stage 2: Parameter Loading** (`genSystems` reads `default.nix`)
|
|
||||||
|
|
||||||
- For each discovered system, `genSystems` imports `systems/<hostname>/default.nix`
|
|
||||||
- This file exports parameters for `constructSystem` like:
|
|
||||||
- `users = [ "alice" ]` — which users to create
|
|
||||||
- `home = true` — enable home-manager
|
|
||||||
- `sops = true` — enable secret decryption
|
|
||||||
- `server = true/false` — machine role
|
|
||||||
- `modules = [ ... ]` — additional system-specific modules
|
|
||||||
|
|
||||||
**Stage 3: Assembly** (`constructSystem` assembles the full config)
|
|
||||||
|
|
||||||
- Loads essential system files: `hardware.nix`, `configuration.nix`
|
|
||||||
- Auto-imports all `.nix` files from `modules/` directory via `lib.adev.fileList`
|
|
||||||
- Conditionally loads home-manager, SOPS, and user configs based on parameters
|
|
||||||
- Merges everything into a complete NixOS system configuration
|
|
||||||
|
|
||||||
### Key Functions in lib/systems.nix
|
|
||||||
|
|
||||||
| Function | Purpose | Called By |
|
|
||||||
|----------|---------|-----------|
|
|
||||||
| `genSystems` | Scans `systems/` directory and creates configs for each subdirectory | `flake.nix` |
|
|
||||||
| `constructSystem` | Assembles a single NixOS system with all modules and configs | `genSystems` |
|
|
||||||
| `genHome` | Imports home-manager configs for specified users | `constructSystem` |
|
|
||||||
| `genSops` | Imports SOPS-encrypted secrets for users | `constructSystem` |
|
|
||||||
| `genUsers` | Imports user account configs from `users/<username>/` | `constructSystem` |
|
|
||||||
| `genHostName` | Creates hostname attribute set | `constructSystem` |
|
|
||||||
| `genWrapper` | Conditionally applies generator functions | `constructSystem` |
|
|
||||||
|
|
||||||
### Special Arguments Passed to All Configs
|
|
||||||
|
|
||||||
These are available in `configuration.nix`, `hardware.nix`, and all modules:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, lib, inputs, outputs, server, system, ... }:
|
|
||||||
```
|
|
||||||
|
|
||||||
- `config` — NixOS configuration options
|
|
||||||
- `pkgs` — Nix packages (nixpkgs)
|
|
||||||
- `lib` — Nix library functions (extended with `lib.adev`)
|
|
||||||
- `inputs` — Flake inputs (nixpkgs, home-manager, sops-nix, etc.)
|
|
||||||
- `outputs` — Flake outputs (for Hydra and other tools)
|
|
||||||
- `server` — Boolean: true for servers, false for desktops
|
|
||||||
- `system` — System architecture string (e.g., `"x86_64-linux"`)
|
|
||||||
|
|
||||||
## Adding a New NixOS System
|
|
||||||
|
|
||||||
### Step 1: Create the Directory Structure
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkdir -p systems/<new-hostname>
|
|
||||||
cd systems/<new-hostname>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 2: Create `default.nix` (System Parameters)
|
|
||||||
|
|
||||||
This file is automatically discovered and loaded by `genSystems`. It exports the parameters passed to `constructSystem`.
|
|
||||||
|
|
||||||
**Minimal example:**
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ inputs }:
|
|
||||||
{
|
|
||||||
# Required: List of users to create (must have entries in users/ directory)
|
|
||||||
users = [ "alice" ];
|
|
||||||
|
|
||||||
# Optional: Enable home-manager (default: true)
|
|
||||||
home = true;
|
|
||||||
|
|
||||||
# Optional: Enable SOPS secrets (default: true)
|
|
||||||
sops = true;
|
|
||||||
|
|
||||||
# Optional: Is this a server? Used to conditionally enable server features
|
|
||||||
server = false;
|
|
||||||
|
|
||||||
# Optional: System architecture (default: "x86_64-linux")
|
|
||||||
system = "x86_64-linux";
|
|
||||||
|
|
||||||
# Optional: System-specific modules (in addition to global modules/)
|
|
||||||
modules = [
|
|
||||||
# ./custom-service.nix
|
|
||||||
];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**See `systems/palatine-hill/default.nix` for a complex example with all options.**
|
|
||||||
|
|
||||||
### Step 3: Create `hardware.nix` (Hardware Configuration)
|
|
||||||
|
|
||||||
Generate this via:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo nixos-generate-config --show-hardware-config > systems/<new-hostname>/hardware.nix
|
|
||||||
```
|
|
||||||
|
|
||||||
This file typically includes:
|
|
||||||
|
|
||||||
- Boot configuration and bootloader
|
|
||||||
- Filesystem mounts and ZFS/LVM settings
|
|
||||||
- Hardware support (CPU, GPU, network drivers)
|
|
||||||
- Device-specific kernel modules
|
|
||||||
|
|
||||||
### Step 4: Create `configuration.nix` (System Configuration)
|
|
||||||
|
|
||||||
This is the main NixOS configuration file. Structure:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, lib, inputs, server, system, ... }:
|
|
||||||
{
|
|
||||||
# System hostname (usually matches directory name)
|
|
||||||
networking.hostName = "new-hostname";
|
|
||||||
|
|
||||||
# Desktop/desktop specific config
|
|
||||||
services.xserver.enable = !server;
|
|
||||||
|
|
||||||
# System packages
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
# ...
|
|
||||||
];
|
|
||||||
|
|
||||||
# Services to enable
|
|
||||||
services.openssh.enable = server;
|
|
||||||
|
|
||||||
# System-specific settings override global defaults
|
|
||||||
boot.kernelParams = [ "nomodeset" ];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 5: Add Optional Secrets
|
|
||||||
|
|
||||||
If the system has sensitive data:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create and encrypt secrets file
|
|
||||||
sops systems/<new-hostname>/secrets.yaml
|
|
||||||
|
|
||||||
# This will be automatically loaded by genSops if sops = true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 6: Add Optional System-Specific Modules
|
|
||||||
|
|
||||||
For system-specific functionality that shouldn't be global, create separate `.nix` files in the system directory:
|
|
||||||
|
|
||||||
```text
|
|
||||||
systems/<new-hostname>/
|
|
||||||
├── configuration.nix # Main config
|
|
||||||
├── default.nix
|
|
||||||
├── hardware.nix
|
|
||||||
├── secrets.yaml # (optional)
|
|
||||||
├── custom-service.nix # (optional) System-specific modules
|
|
||||||
├── networking.nix # (optional)
|
|
||||||
└── graphics.nix # (optional)
|
|
||||||
```
|
|
||||||
|
|
||||||
Reference these in `default.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ inputs }:
|
|
||||||
{
|
|
||||||
users = [ "alice" ];
|
|
||||||
modules = [
|
|
||||||
./custom-service.nix
|
|
||||||
./networking.nix
|
|
||||||
./graphics.nix
|
|
||||||
];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 7: Deploy the New System
|
|
||||||
|
|
||||||
The system is now automatically registered! Deploy with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build the new system
|
|
||||||
nix build .#<new-hostname>
|
|
||||||
|
|
||||||
# Or if you want to switch immediately
|
|
||||||
nh os switch
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding a Global Module to modules/
|
|
||||||
|
|
||||||
Global modules are automatically imported into all systems. No registration needed.
|
|
||||||
|
|
||||||
### Create a Module File
|
|
||||||
|
|
||||||
Add a new `.nix` file to the `modules/` directory. Example: `modules/my-service.nix`
|
|
||||||
|
|
||||||
### Module Structure
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, lib, inputs, server, ... }:
|
|
||||||
{
|
|
||||||
# Define configuration options for this module
|
|
||||||
options.myService = {
|
|
||||||
enable = lib.mkEnableOption "my service";
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 3000;
|
|
||||||
description = "Port for the service";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Actual configuration (conditional on enable option)
|
|
||||||
config = lib.mkIf config.myService.enable {
|
|
||||||
environment.systemPackages = [ pkgs.my-service ];
|
|
||||||
|
|
||||||
systemd.services.my-service = {
|
|
||||||
description = "My Service";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.my-service}/bin/my-service";
|
|
||||||
Restart = "always";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using mkIf, mkDefault, and mkForce
|
|
||||||
|
|
||||||
- **`mkIf`** — Conditionally apply config based on a boolean
|
|
||||||
|
|
||||||
```nix
|
|
||||||
config = lib.mkIf config.myService.enable { ... };
|
|
||||||
```
|
|
||||||
|
|
||||||
- **`mkDefault`** — Provide a default value that can be overridden
|
|
||||||
|
|
||||||
```nix
|
|
||||||
boot.kernelParams = lib.mkDefault [ "quiet" ];
|
|
||||||
```
|
|
||||||
|
|
||||||
- **`mkForce`** — Force a value, preventing other modules from overriding
|
|
||||||
|
|
||||||
```nix
|
|
||||||
services.openssh.enable = lib.mkForce true;
|
|
||||||
```
|
|
||||||
|
|
||||||
- **`mkEnableOption`** — Define an `enable` option with standard description
|
|
||||||
|
|
||||||
```nix
|
|
||||||
options.myService.enable = lib.mkEnableOption "my service";
|
|
||||||
```
|
|
||||||
|
|
||||||
### Disable a Global Module for a Specific System
|
|
||||||
|
|
||||||
To disable a module for one system, override it in that system's `configuration.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, lib, ... }:
|
|
||||||
{
|
|
||||||
# Disable the module entirely
|
|
||||||
myService.enable = false;
|
|
||||||
|
|
||||||
# Or override specific options
|
|
||||||
services.openssh.port = 2222;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Module Loading Order in constructSystem
|
|
||||||
|
|
||||||
Modules are applied in this order (later modules override earlier ones):
|
|
||||||
|
|
||||||
1. `inputs.nixos-modules.nixosModule` (SuperSandro2000's convenience functions)
|
|
||||||
1. `inputs.nix-index-database.nixosModules.nix-index`
|
|
||||||
1. Hostname attribute from `genHostName`
|
|
||||||
1. `hardware.nix` (hardware-specific config)
|
|
||||||
1. `configuration.nix` (main system config)
|
|
||||||
1. **System-specific modules** from `modules` parameter in `default.nix` (e.g., custom-service.nix)
|
|
||||||
1. **All `.nix` files from global `modules/` directory** (features enabled across all systems)
|
|
||||||
1. SOPS module (if `sops = true`)
|
|
||||||
1. Home-manager module (if `home = true`)
|
|
||||||
1. User configurations (if `users = [...]` and `home = true`)
|
|
||||||
|
|
||||||
Important: Global modules (step 7) are applied after system-specific configs, so they can't override those values unless using `mkForce`. System-specific modules take precedence over global ones.
|
|
||||||
|
|
||||||
## Common Tasks
|
|
||||||
|
|
||||||
### Enable a Feature Across All Systems
|
|
||||||
|
|
||||||
1. Create `modules/my-feature.nix` with `options.myFeature.enable`
|
|
||||||
1. Set the feature enabled in `configuration.nix` of systems that need it:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
myFeature.enable = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Or enable globally and disable selectively:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# In modules/my-feature.nix
|
|
||||||
config = lib.mkIf config.myFeature.enable {
|
|
||||||
# ...enabled by default
|
|
||||||
};
|
|
||||||
|
|
||||||
# In a system's configuration.nix
|
|
||||||
myFeature.enable = false; # Disable just for this system
|
|
||||||
```
|
|
||||||
|
|
||||||
### Add a New User to the System
|
|
||||||
|
|
||||||
1. Create user config: `users/<username>/default.nix` and `users/<username>/home.nix`
|
|
||||||
1. Update system's `default.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
users = [ "alice" "newuser" ];
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Create secrets: `sops users/<username>/secrets.yaml`
|
|
||||||
1. Redeploy: `nh os switch`
|
|
||||||
|
|
||||||
### Override a Module's Default Behavior
|
|
||||||
|
|
||||||
In any system's `configuration.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
# Disable a service that's enabled by default in a module
|
|
||||||
services.openssh.enable = false;
|
|
||||||
|
|
||||||
# Override module options
|
|
||||||
boot.kernelParams = [ "nomodeset" ];
|
|
||||||
|
|
||||||
# Add to existing lists
|
|
||||||
environment.systemPackages = [ pkgs.custom-tool ];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Which Modules Are Loaded
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List all module paths being loaded
|
|
||||||
nix eval .#nixosConfigurations.<hostname>.options --json | jq keys | head -20
|
|
||||||
|
|
||||||
# Evaluate a specific config value
|
|
||||||
nix eval .#nixosConfigurations.<hostname>.config.services.openssh.enable
|
|
||||||
```
|
|
||||||
|
|
||||||
### Validate Configuration Before Deploying
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check syntax and evaluate
|
|
||||||
nix flake check
|
|
||||||
|
|
||||||
# Build without switching
|
|
||||||
nix build .#<hostname>
|
|
||||||
|
|
||||||
# Preview what would change
|
|
||||||
nix build .#<hostname> && nix-diff /run/current-system ./result
|
|
||||||
```
|
|
||||||
|
|
||||||
## Secrets Management
|
|
||||||
|
|
||||||
SOPS (Secrets Operations) manages sensitive data like passwords and API keys. This repository uses age encryption with SOPS to encrypt secrets per system and per user.
|
|
||||||
|
|
||||||
### Directory Structure
|
|
||||||
|
|
||||||
Secrets are stored alongside their respective configs:
|
|
||||||
|
|
||||||
```text
|
|
||||||
systems/<hostname>/secrets.yaml # System-wide secrets
|
|
||||||
users/<username>/secrets.yaml # User-specific secrets
|
|
||||||
```
|
|
||||||
|
|
||||||
### Creating and Editing Secrets
|
|
||||||
|
|
||||||
**Create or edit a secrets file:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# For a system
|
|
||||||
sops systems/<hostname>/secrets.yaml
|
|
||||||
|
|
||||||
# For a user
|
|
||||||
sops users/<username>/secrets.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
SOPS will open your `$EDITOR` with decrypted content. When you save and exit, it automatically re-encrypts the file.
|
|
||||||
|
|
||||||
**Example secrets structure for a system:**
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# systems/palatine-hill/secrets.yaml
|
|
||||||
acme:
|
|
||||||
email: user@example.com
|
|
||||||
api_token: "secret-token-here"
|
|
||||||
postgresql:
|
|
||||||
password: "db-password"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Example secrets for a user:**
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# users/alice/secrets.yaml
|
|
||||||
# The user password is required
|
|
||||||
user-password: "hashed-password-here"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Accessing Secrets in Configuration
|
|
||||||
|
|
||||||
Secrets are made available via `config.sops.secrets` in modules and configurations:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# In a module or configuration.nix
|
|
||||||
{ config, lib, ... }:
|
|
||||||
{
|
|
||||||
# Reference a secret
|
|
||||||
services.postgresql.initialScript = ''
|
|
||||||
CREATE USER app WITH PASSWORD '${config.sops.secrets."postgresql/password".path}';
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Or use the secret directly if it supports content
|
|
||||||
systemd.services.my-app.serviceConfig = {
|
|
||||||
EnvironmentFiles = [ config.sops.secrets."api-token".path ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Merging Secrets Files
|
|
||||||
|
|
||||||
When multiple systems or users modify secrets, use the sops-mergetool to resolve conflicts:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Set up mergetool
|
|
||||||
git config merge.sopsmergetool.command "sops-mergetool-wrapper $BASE $CURRENT $OTHER $MERGED"
|
|
||||||
|
|
||||||
# Then during a merge conflict
|
|
||||||
git merge branch-name
|
|
||||||
|
|
||||||
# Git will use sops-mergetool to intelligently merge encrypted files
|
|
||||||
```
|
|
||||||
|
|
||||||
The repository includes helper scripts: `utils/sops-mergetool.sh` and `utils/sops-mergetool-new.sh`
|
|
||||||
|
|
||||||
### Adding a New Machine's Age Key
|
|
||||||
|
|
||||||
When adding a new system (`systems/<new-hostname>/`), you need to register its age encryption key:
|
|
||||||
|
|
||||||
1. Generate the key on the target machine (if using existing deployment) or during initial setup
|
|
||||||
1. Add the public key to `.sops.yaml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
keys:
|
|
||||||
- &artemision <age-key-for-artemision>
|
|
||||||
- &palatine-hill <age-key-for-palatine-hill>
|
|
||||||
- &new-hostname <age-key-for-new-hostname>
|
|
||||||
|
|
||||||
creation_rules:
|
|
||||||
- path_regex: 'systems/new-hostname/.*'
|
|
||||||
key_groups:
|
|
||||||
- age: *new-hostname
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Re-encrypt existing secrets with the new key:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sops updatekeys systems/new-hostname/secrets.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Real-World Examples
|
|
||||||
|
|
||||||
### Example 1: Adding a Feature to All Desktop Machines
|
|
||||||
|
|
||||||
Using `artemision` (desktop) as an example:
|
|
||||||
|
|
||||||
**Create `modules/gpu-optimization.nix`:**
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, lib, server, ... }:
|
|
||||||
{
|
|
||||||
options.gpu.enable = lib.mkEnableOption "GPU optimization";
|
|
||||||
|
|
||||||
config = lib.mkIf (config.gpu.enable && !server) {
|
|
||||||
# Desktop-only GPU settings
|
|
||||||
hardware.nvidia.open = true;
|
|
||||||
services.xserver.videoDrivers = [ "nvidia" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Enable in `systems/artemision/configuration.nix`:**
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
gpu.enable = true;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Deploy:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nix build .#artemision
|
|
||||||
nh os switch
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 2: Adding a Server Service to One System
|
|
||||||
|
|
||||||
Using `palatine-hill` (server) as an example:
|
|
||||||
|
|
||||||
**Create `systems/palatine-hill/postgresql-backup.nix`:**
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
systemd.timers.postgres-backup = {
|
|
||||||
description = "PostgreSQL daily backup";
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = "03:00";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.postgres-backup = {
|
|
||||||
description = "Backup PostgreSQL database";
|
|
||||||
script = ''
|
|
||||||
${pkgs.postgresql}/bin/pg_dumpall | gzip > /backups/postgres-$(date +%Y%m%d).sql.gz
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Reference in `systems/palatine-hill/default.nix`:**
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ inputs }:
|
|
||||||
{
|
|
||||||
users = [ "alice" ];
|
|
||||||
server = true;
|
|
||||||
modules = [
|
|
||||||
./postgresql-backup.nix
|
|
||||||
];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Deploy:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nix build .#palatine-hill
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 3: Disabling a Global Module for a Specific System
|
|
||||||
|
|
||||||
To disable `modules/steam.nix` on a server (`palatine-hill`) while it stays enabled on desktops:
|
|
||||||
|
|
||||||
**In `systems/palatine-hill/configuration.nix`:**
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
steam.enable = false; # Override the module option
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The module in `modules/steam.nix` should use:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
config = lib.mkIf config.steam.enable {
|
|
||||||
# steam configuration only if enabled
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Debugging & Validation
|
|
||||||
|
|
||||||
### Check Module Evaluation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# See which modules are loaded for a system
|
|
||||||
nix eval .#nixosConfigurations.artemision.config.environment.systemPackages --no-allocator
|
|
||||||
|
|
||||||
# Validate module option exists
|
|
||||||
nix eval .#nixosConfigurations.artemision.options.myService.enable
|
|
||||||
```
|
|
||||||
|
|
||||||
### Debug SOPS Secrets
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# View encrypted secrets (you must have the age key)
|
|
||||||
sops systems/palatine-hill/secrets.yaml
|
|
||||||
|
|
||||||
# Check if SOPS integration is working
|
|
||||||
nix eval .#nixosConfigurations.palatine-hill.config.sops.secrets --json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test Configuration Without Deploying
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Evaluate the entire configuration
|
|
||||||
nix eval .#nixosConfigurations.artemision --no-allocator
|
|
||||||
|
|
||||||
# Build (but don't activate)
|
|
||||||
nix build .#artemision
|
|
||||||
|
|
||||||
# Check for errors in the derivation
|
|
||||||
nix path-info ./result
|
|
||||||
```
|
|
||||||
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"davidanson.vscode-markdownlint"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -56,7 +56,7 @@ forEachSystem (
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
all
|
all
|
||||||
rule 'MD013', :tables => false, :line_length => 220
|
rule 'MD013', :tables => false
|
||||||
'').outPath;
|
'').outPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
24
flake.lock
generated
24
flake.lock
generated
@@ -76,11 +76,11 @@
|
|||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "pkgs/firefox-addons",
|
"dir": "pkgs/firefox-addons",
|
||||||
"lastModified": 1776052978,
|
"lastModified": 1775966594,
|
||||||
"narHash": "sha256-WR0Svwg/JreBNW006qjHET6RRRmmjWCMfrkS5JmDZK8=",
|
"narHash": "sha256-pnRtaqTr7ut8dz8b04OWAanUM4tGhDUJz8SWmeTRp7U=",
|
||||||
"owner": "rycee",
|
"owner": "rycee",
|
||||||
"repo": "nur-expressions",
|
"repo": "nur-expressions",
|
||||||
"rev": "6c0e7f01d9315f4806a187c2ec58d0f3b6961876",
|
"rev": "000d1d2322d28fa0a51b8db9f85a227aa5413b52",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -240,11 +240,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776046499,
|
"lastModified": 1775983377,
|
||||||
"narHash": "sha256-Wzc4nn07/0RL21ypPHRzNDQZcjhIC8LaYo7QJQjM5T4=",
|
"narHash": "sha256-ZeRjipGQnVtQ/6batI+yVOrL853FZsL0m9A63OaSfgM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "287f84846c1eb3b72c986f5f6bebcff0bd67440d",
|
"rev": "e0ca734ffc85d25297715e98010b93303fa165c4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -438,11 +438,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776036369,
|
"lastModified": 1775603140,
|
||||||
"narHash": "sha256-TxBJY5IwDu3peDIK3b9+A7pwqBaFRCAIllaRSfYMQtI=",
|
"narHash": "sha256-tOAJ2zQ8X/KFQdvFIpQDUr+dL+bs93titDyWRTTrd9U=",
|
||||||
"owner": "NuschtOS",
|
"owner": "NuschtOS",
|
||||||
"repo": "nixos-modules",
|
"repo": "nixos-modules",
|
||||||
"rev": "2bea807180b3931cf8765078205fd9171dbfd2b5",
|
"rev": "6e3c91f482a96ce671b47a2584205ecef024f16d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -594,11 +594,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776050130,
|
"lastModified": 1775963625,
|
||||||
"narHash": "sha256-/f/6/1WOfBJaGMfqV3VxWD9lpFRbPpF+Cx4MO+0mGok=",
|
"narHash": "sha256-OmwF0Rd/HDbEGC0ZcBS2jPMvmCcn3HDqUypjXrR7KfM=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "3c27f4c92a7d977556dd2c10bb564d9c61b375e9",
|
"rev": "573a61faa8ec910a6b8576cc3c145844245574f3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -28,8 +28,6 @@
|
|||||||
"plugdev"
|
"plugdev"
|
||||||
"uaccess"
|
"uaccess"
|
||||||
"ydotool"
|
"ydotool"
|
||||||
"video"
|
|
||||||
"render"
|
|
||||||
]
|
]
|
||||||
++ groups;
|
++ groups;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user