478 lines
8.5 KiB
Markdown
478 lines
8.5 KiB
Markdown
|
|
# Customization Guide
|
||
|
|
|
||
|
|
Advanced customization patterns for your portable NixOS setup.
|
||
|
|
|
||
|
|
## Creating Custom Modules
|
||
|
|
|
||
|
|
### Pattern 1: Language-Specific Development Environment
|
||
|
|
|
||
|
|
Create `nixos/modules/languages/rust.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
options.custom.languages.rust.enable = lib.mkEnableOption "Rust development";
|
||
|
|
|
||
|
|
config = lib.mkIf config.custom.languages.rust.enable {
|
||
|
|
environment.systemPackages = with pkgs; [
|
||
|
|
rustup
|
||
|
|
cargo-edit
|
||
|
|
cargo-deny
|
||
|
|
rust-analyzer
|
||
|
|
];
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Use in `hosts/laptop/default.nix`:
|
||
|
|
```nix
|
||
|
|
custom.languages.rust.enable = true;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 2: Per-Machine Overrides
|
||
|
|
|
||
|
|
In `nixos/default.nix`:
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
options.custom = {
|
||
|
|
isLaptop = lib.mkOption { type = lib.types.bool; default = false; };
|
||
|
|
isServer = lib.mkOption { type = lib.types.bool; default = false; };
|
||
|
|
};
|
||
|
|
|
||
|
|
config = {
|
||
|
|
# Settings that only apply to laptops
|
||
|
|
power.powertop.enable = lib.mkIf config.custom.isLaptop true;
|
||
|
|
services.thermald.enable = lib.mkIf config.custom.isLaptop true;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
In `hosts/laptop/default.nix`:
|
||
|
|
```nix
|
||
|
|
custom.isLaptop = true;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 3: Conditional Package Sets
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
options.custom.tools.enable = lib.mkEnableOption "Extra tools";
|
||
|
|
|
||
|
|
config = lib.mkIf config.custom.tools.enable {
|
||
|
|
environment.systemPackages = with pkgs; [
|
||
|
|
# Always included
|
||
|
|
git
|
||
|
|
curl
|
||
|
|
|
||
|
|
# Only if GUI is available
|
||
|
|
(lib.optionals (config.custom.hasGui) [
|
||
|
|
firefox
|
||
|
|
vlc
|
||
|
|
])
|
||
|
|
|
||
|
|
# Only on laptops
|
||
|
|
(lib.optionals config.custom.isLaptop [
|
||
|
|
powertop
|
||
|
|
upower
|
||
|
|
])
|
||
|
|
];
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Common Customizations
|
||
|
|
|
||
|
|
### Add Docker/Podman Support
|
||
|
|
|
||
|
|
Edit `nixos/modules/development.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
virtualisation.podman = {
|
||
|
|
enable = true;
|
||
|
|
dockerCompat = true; # Alias docker → podman
|
||
|
|
};
|
||
|
|
|
||
|
|
virtualisation.docker.enable = lib.mkDefault false;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Kubernetes Tools
|
||
|
|
|
||
|
|
In `nixos/modules/development.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
languagePackages = {
|
||
|
|
# ... existing languages
|
||
|
|
kubernetes = with pkgs; [ kubectl helm kustomize ];
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
Use in host:
|
||
|
|
```nix
|
||
|
|
custom.development.languages = [ "rust" "kubernetes" ];
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Desktop Environment
|
||
|
|
|
||
|
|
Create `nixos/modules/desktop.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
options.custom.desktop = {
|
||
|
|
enable = lib.mkEnableOption "Desktop environment";
|
||
|
|
environment = lib.mkOption {
|
||
|
|
type = lib.types.enum [ "gnome" "kde" "xfce" ];
|
||
|
|
default = "gnome";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
config = let
|
||
|
|
cfg = config.custom.desktop;
|
||
|
|
in lib.mkIf cfg.enable {
|
||
|
|
services.xserver.enable = true;
|
||
|
|
services.xserver.displayManager.gdm.enable = cfg.environment == "gnome";
|
||
|
|
services.xserver.desktopManager.gnome.enable = cfg.environment == "gnome";
|
||
|
|
|
||
|
|
# Similar for KDE, XFCE...
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Use in host:
|
||
|
|
```nix
|
||
|
|
custom.desktop.enable = true;
|
||
|
|
custom.desktop.environment = "gnome";
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add SSH Server
|
||
|
|
|
||
|
|
Edit `nixos/modules/system.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
services.openssh = {
|
||
|
|
enable = lib.mkDefault false;
|
||
|
|
ports = [ 22 ];
|
||
|
|
settings = {
|
||
|
|
PermitRootLogin = "no";
|
||
|
|
PasswordAuthentication = false;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
Enable in specific host:
|
||
|
|
```nix
|
||
|
|
# hosts/server/default.nix
|
||
|
|
services.openssh.enable = true;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Nginx Web Server
|
||
|
|
|
||
|
|
Create `nixos/modules/web.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
options.custom.web.enable = lib.mkEnableOption "Web server";
|
||
|
|
|
||
|
|
config = lib.mkIf config.custom.web.enable {
|
||
|
|
services.nginx = {
|
||
|
|
enable = true;
|
||
|
|
virtualHosts."localhost" = {
|
||
|
|
listen = [{ addr = "127.0.0.1"; port = 8080; }];
|
||
|
|
locations."/".root = "/var/www";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add PostgreSQL Database
|
||
|
|
|
||
|
|
Create `nixos/modules/database.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
options.custom.database.postgres.enable = lib.mkEnableOption "PostgreSQL";
|
||
|
|
|
||
|
|
config = lib.mkIf config.custom.database.postgres.enable {
|
||
|
|
services.postgresql = {
|
||
|
|
enable = true;
|
||
|
|
ensureDatabases = [ "dev" ];
|
||
|
|
ensureUsers = [{
|
||
|
|
name = "dev";
|
||
|
|
ensureDBOwnership = true;
|
||
|
|
}];
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Enable in host:
|
||
|
|
```nix
|
||
|
|
custom.database.postgres.enable = true;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Docker Containers for Services
|
||
|
|
|
||
|
|
Create `nixos/modules/containers.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
virtualisation.podman.enable = true;
|
||
|
|
|
||
|
|
# Define containers to auto-start
|
||
|
|
virtualisation.podman.containers = {
|
||
|
|
redis = {
|
||
|
|
image = "redis:latest";
|
||
|
|
ports = [ "6379:6379" ];
|
||
|
|
autoStart = lib.mkDefault false;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Home Manager Customizations
|
||
|
|
|
||
|
|
### Add Starship Configuration
|
||
|
|
|
||
|
|
Edit `home/modules/shell.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
programs.starship = {
|
||
|
|
enable = true;
|
||
|
|
settings = {
|
||
|
|
add_newline = true;
|
||
|
|
character = {
|
||
|
|
success_symbol = "[➜](bold green)";
|
||
|
|
error_symbol = "[➜](bold red)";
|
||
|
|
};
|
||
|
|
rust = {
|
||
|
|
disabled = false;
|
||
|
|
symbol = "🦀 ";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Zsh Plugins
|
||
|
|
|
||
|
|
Edit `home/modules/shell.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
programs.zsh.plugins = [
|
||
|
|
{
|
||
|
|
name = "zsh-autosuggestions";
|
||
|
|
src = pkgs.fetchFromGitHub { /* ... */ };
|
||
|
|
}
|
||
|
|
{
|
||
|
|
name = "powerlevel10k";
|
||
|
|
src = pkgs.fetchFromGitHub { /* ... */ };
|
||
|
|
file = "powerlevel10k.zsh-theme";
|
||
|
|
}
|
||
|
|
];
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add VSCode Configuration
|
||
|
|
|
||
|
|
Edit `home/modules/editor.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
programs.vscode = {
|
||
|
|
enable = true;
|
||
|
|
extensions = with pkgs.vscode-extensions; [
|
||
|
|
ms-python.python
|
||
|
|
rust-lang.rust-analyzer
|
||
|
|
hashicorp.terraform
|
||
|
|
];
|
||
|
|
userSettings = {
|
||
|
|
"editor.fontSize" = 14;
|
||
|
|
"editor.formatOnSave" = true;
|
||
|
|
"python.linting.enabled" = true;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add SSH Configuration
|
||
|
|
|
||
|
|
Create `home/modules/ssh.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
programs.ssh = {
|
||
|
|
enable = true;
|
||
|
|
matchBlocks = {
|
||
|
|
"github.com" = {
|
||
|
|
host = "github.com";
|
||
|
|
user = "git";
|
||
|
|
identityFile = "~/.ssh/github";
|
||
|
|
identitiesOnly = true;
|
||
|
|
};
|
||
|
|
"*.example.com" = {
|
||
|
|
user = "myuser";
|
||
|
|
identityFile = "~/.ssh/work";
|
||
|
|
forwardAgent = true;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Import in `home/default.nix`:
|
||
|
|
```nix
|
||
|
|
imports = [
|
||
|
|
./modules/ssh.nix
|
||
|
|
];
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Tmux Configuration
|
||
|
|
|
||
|
|
Edit `home/modules/dev-tools.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
programs.tmux = {
|
||
|
|
enable = true;
|
||
|
|
mouse = true;
|
||
|
|
baseIndex = 1;
|
||
|
|
keyMode = "vi";
|
||
|
|
|
||
|
|
plugins = with pkgs.tmuxPlugins; [
|
||
|
|
sensible
|
||
|
|
vim-tmux-navigator
|
||
|
|
resurrect
|
||
|
|
];
|
||
|
|
|
||
|
|
extraConfig = ''
|
||
|
|
# Custom keybindings
|
||
|
|
bind -n M-h select-pane -L
|
||
|
|
bind -n M-j select-pane -D
|
||
|
|
bind -n M-k select-pane -U
|
||
|
|
bind -n M-l select-pane -R
|
||
|
|
'';
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## Integration Patterns
|
||
|
|
|
||
|
|
### Using Unstable Packages Everywhere
|
||
|
|
|
||
|
|
In `home/modules/editor.nix`, use unstable neovim:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ pkgs, pkgs-unstable, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
programs.neovim = {
|
||
|
|
enable = true;
|
||
|
|
package = pkgs-unstable.neovim;
|
||
|
|
# ...
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Conditional Configuration Based on Hardware
|
||
|
|
|
||
|
|
In `hosts/laptop/default.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, lib, pkgs, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
# Laptop-specific
|
||
|
|
services.power-profiles-daemon.enable = true;
|
||
|
|
services.logind.lidSwitchExternalPower = "ignore";
|
||
|
|
|
||
|
|
# Wireless
|
||
|
|
networking.wireless.enable = true;
|
||
|
|
|
||
|
|
# Battery
|
||
|
|
systemd.services.battery-monitor = {
|
||
|
|
description = "Monitor battery health";
|
||
|
|
wantedBy = [ "multi-user.target" ];
|
||
|
|
script = "${pkgs.acpi}/bin/acpi";
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Using Secrets in Home Manager
|
||
|
|
|
||
|
|
In `home/modules/example.nix`:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{ config, sops-nix, ... }:
|
||
|
|
|
||
|
|
{
|
||
|
|
imports = [ sops-nix.homeManagerModules.sops ];
|
||
|
|
|
||
|
|
sops.defaultSopsFile = ../../secrets/secrets.yaml;
|
||
|
|
|
||
|
|
sops.secrets."api/myapi" = {
|
||
|
|
path = "%r/myapi"; # In ~/.config/sops-nix
|
||
|
|
};
|
||
|
|
|
||
|
|
# Use in programs
|
||
|
|
home.sessionVariables.MY_API_KEY = config.sops.secrets."api/myapi".path;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Changes Safely
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build without applying
|
||
|
|
home-manager build --flake .#myusername@linux
|
||
|
|
|
||
|
|
# Check what will change
|
||
|
|
sudo nixos-rebuild test --flake .#laptop # Activates but doesn't add to boot
|
||
|
|
|
||
|
|
# Compare with current
|
||
|
|
sudo nixos-rebuild diff --flake .#laptop
|
||
|
|
|
||
|
|
# Rollback if something breaks
|
||
|
|
nixos-rebuild --rollback switch # NixOS
|
||
|
|
home-manager switch --flake .#myusername@linux ~/.local/state/home-manager/current # HM
|
||
|
|
```
|
||
|
|
|
||
|
|
## Performance Optimization
|
||
|
|
|
||
|
|
### Selective Updates
|
||
|
|
|
||
|
|
Update only specific inputs:
|
||
|
|
```bash
|
||
|
|
nix flake update nixpkgs
|
||
|
|
nix flake update home-manager
|
||
|
|
```
|
||
|
|
|
||
|
|
### Parallel Builds
|
||
|
|
|
||
|
|
In `flake.nix`, speed up evaluation:
|
||
|
|
```bash
|
||
|
|
NIX_BUILD_CORES=4 sudo nixos-rebuild switch --flake .#laptop
|
||
|
|
```
|
||
|
|
|
||
|
|
### Binary Cache
|
||
|
|
|
||
|
|
Use nixpkgs binary cache:
|
||
|
|
```nix
|
||
|
|
# nixos/default.nix
|
||
|
|
nix = {
|
||
|
|
settings = {
|
||
|
|
substituters = [ "https://cache.nixos.org" ];
|
||
|
|
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypQMvvZN1FSVucqL2mGvhiqHIl8=" ];
|
||
|
|
};
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
See QUICKREF.md for common operations reference.
|