8.5 KiB
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:
{ 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:
custom.languages.rust.enable = true;
Pattern 2: Per-Machine Overrides
In nixos/default.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:
custom.isLaptop = true;
Pattern 3: Conditional Package Sets
{ 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:
virtualisation.podman = {
enable = true;
dockerCompat = true; # Alias docker → podman
};
virtualisation.docker.enable = lib.mkDefault false;
Add Kubernetes Tools
In nixos/modules/development.nix:
languagePackages = {
# ... existing languages
kubernetes = with pkgs; [ kubectl helm kustomize ];
};
Use in host:
custom.development.languages = [ "rust" "kubernetes" ];
Add Desktop Environment
Create nixos/modules/desktop.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:
custom.desktop.enable = true;
custom.desktop.environment = "gnome";
Add SSH Server
Edit nixos/modules/system.nix:
services.openssh = {
enable = lib.mkDefault false;
ports = [ 22 ];
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
};
Enable in specific host:
# hosts/server/default.nix
services.openssh.enable = true;
Add Nginx Web Server
Create nixos/modules/web.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:
{ 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:
custom.database.postgres.enable = true;
Add Docker Containers for Services
Create nixos/modules/containers.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:
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:
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:
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:
{ 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:
imports = [
./modules/ssh.nix
];
Add Tmux Configuration
Edit home/modules/dev-tools.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:
{ pkgs, pkgs-unstable, ... }:
{
programs.neovim = {
enable = true;
package = pkgs-unstable.neovim;
# ...
};
}
Conditional Configuration Based on Hardware
In hosts/laptop/default.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:
{ 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
# 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:
nix flake update nixpkgs
nix flake update home-manager
Parallel Builds
In flake.nix, speed up evaluation:
NIX_BUILD_CORES=4 sudo nixos-rebuild switch --flake .#laptop
Binary Cache
Use nixpkgs binary cache:
# 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.