Creating Profiles
Learn how to build reusable feature profiles for your Nix configuration.
Table of Contents
Section titled “Table of Contents”- Overview
- What is a Profile?
- Profile Structure
- Creating a Simple Profile
- Advanced Profiles
- Using Profiles
- Best Practices
- Examples
Overview
Section titled “Overview”Profiles are composable feature bundles that group related configuration. They:
- Bundle packages, settings, and services
- Enable/disable entire feature sets at once
- Can be shared across machines
- Promote configuration reuse
What is a Profile?
Section titled “What is a Profile?”Profile vs Module
Section titled “Profile vs Module”Module - Building block with options
# Defines HOW something worksoptions.myapp.enable = ...;config = lib.mkIf config.myapp.enable { ... };
Profile - Pre-configured feature bundle
# Defines WHAT you getenvironment.systemPackages = [ pkgs.tool1 pkgs.tool2 ];programs.tool1.enable = true;
When to Use Profiles
Section titled “When to Use Profiles”Use profiles for:
- ✅ Feature sets (cloud tools, development tools)
- ✅ Role-based configs (developer, ops, security)
- ✅ Platform-specific bundles (macOS apps, Linux tools)
- ✅ Shareable configurations
Use modules for:
- ✅ Configurable services
- ✅ System-wide settings
- ✅ Reusable abstractions
Profile Structure
Section titled “Profile Structure”Basic Profile Template
Section titled “Basic Profile Template”{ config, pkgs, lib, ... }:{ # System packages environment.systemPackages = with pkgs; [ package1 package2 ];
# Program configuration programs.tool.enable = true;
# Services services.myservice.enable = true;
# Environment variables environment.variables = { VAR = "value"; };}
File Organization
Section titled “File Organization”nix/profiles/├── cloud-cli.nix # Cloud provider tools├── developer.nix # Development utilities├── hardware-security.nix # Ledger, GPG, SSH├── python-dev.nix # Python development└── frontend-dev.nix # Frontend tools
Creating a Simple Profile
Section titled “Creating a Simple Profile”Example: Cloud CLI Profile
Section titled “Example: Cloud CLI Profile”Already in your config at nix/profiles/cloud-cli.nix
:
{ config, pkgs, ... }:{ # Cloud CLI tools environment.systemPackages = with pkgs; [ # AWS awscli2
# GCP google-cloud-sdk
# Kubernetes kubectl kubectx k9s helm
# Infrastructure terraform terragrunt
# Container tools skopeo dive ];}
Example: Developer Profile
Section titled “Example: Developer Profile”Already in your config at nix/profiles/developer.nix
:
{ config, pkgs, ... }:{ environment.systemPackages = with pkgs; [ # JSON/YAML tools jq yq-go
# File utilities tree fd ripgrep
# Build tools just gnumake ];}
Advanced Profiles
Section titled “Advanced Profiles”Profile with Options
Section titled “Profile with Options”Profiles can define their own options:
{ config, pkgs, lib, ... }:
let cfg = config.profiles.python-dev;in { options.profiles.python-dev = { enable = lib.mkEnableOption "Python development profile";
includeDataScience = lib.mkOption { type = lib.types.bool; default = false; description = "Include data science tools"; }; };
config = lib.mkIf cfg.enable (lib.mkMerge [ # Base Python tools { environment.systemPackages = with pkgs; [ python3 python3Packages.pip python3Packages.virtualenv poetry black ruff ]; }
# Data science tools (conditional) (lib.mkIf cfg.includeDataScience { environment.systemPackages = with pkgs; [ python3Packages.numpy python3Packages.pandas python3Packages.matplotlib python3Packages.jupyter ]; }) ]);}
Profile with Home Manager
Section titled “Profile with Home Manager”Profiles can configure both system and user:
{ config, pkgs, ... }:{ # System-level packages environment.systemPackages = with pkgs; [ docker kubectl ];
# User-level configuration home-manager.users.${config.system.primaryUser} = { home.packages = with pkgs; [ k9s dive ];
programs.git = { aliases = { k = "!kubectl"; d = "!docker"; }; }; };}
Platform-Specific Profiles
Section titled “Platform-Specific Profiles”{ config, pkgs, lib, ... }:{ # Common tools environment.systemPackages = with pkgs; [ git vim ];
# macOS specific environment.systemPackages = lib.optionals pkgs.stdenv.isDarwin [ pkgs.darwin.trash ];
# Linux specific environment.systemPackages = lib.optionals pkgs.stdenv.isLinux [ pkgs.systemd ];
# macOS Homebrew casks homebrew = lib.mkIf pkgs.stdenv.isDarwin { casks = [ "visual-studio-code" "docker" ]; };}
Using Profiles
Section titled “Using Profiles”Enable in Host Configuration
Section titled “Enable in Host Configuration”Add to hosts/your-mac.nix
:
{ imports = [ ../nix/profiles/cloud-cli.nix ../nix/profiles/developer.nix ../nix/profiles/python-dev.nix ];}
Enable in Flake
Section titled “Enable in Flake”Add to flake.nix
:
darwinConfigurations.your-mac = darwin.lib.darwinSystem { modules = [ ./nix/modules/common.nix ./nix/modules/darwin-base.nix
# Profiles ./nix/profiles/cloud-cli.nix ./nix/profiles/developer.nix ./nix/profiles/hardware-security.nix
./hosts/your-mac.nix ];};
Conditional Profiles
Section titled “Conditional Profiles”{ imports = [ # Always enabled ../nix/profiles/developer.nix ] # Conditional ++ lib.optional config.work.enable ../nix/profiles/cloud-cli.nix ++ lib.optional config.gaming.enable ../nix/profiles/gaming.nix;}
Best Practices
Section titled “Best Practices”Single Responsibility
Section titled “Single Responsibility”# ✅ Good: Focused profile{ environment.systemPackages = [ pkgs.python3 pkgs.poetry pkgs.black ];}
# ❌ Bad: Kitchen sink# nix/profiles/everything.nix{ environment.systemPackages = [ pkgs.python3 # Python pkgs.nodejs # Node pkgs.go # Go pkgs.awscli # Cloud # Too much! ];}
Composition Over Duplication
Section titled “Composition Over Duplication”# ✅ Good: Compose smaller profiles{ imports = [ ./base-dev.nix ./python-dev.nix ./frontend-dev.nix ];}
# ❌ Bad: Duplicate everything# nix/profiles/fullstack.nix{ environment.systemPackages = [ # Duplicates from base-dev pkgs.git pkgs.vim # Python stuff pkgs.python3 # Frontend stuff pkgs.nodejs ];}
Clear Naming
Section titled “Clear Naming”# ✅ Good: Descriptive namesnix/profiles/├── python-dev.nix # Python development├── cloud-aws.nix # AWS tools├── frontend-react.nix # React development
# ❌ Bad: Vague namesnix/profiles/├── dev.nix # What kind?├── tools.nix # Which tools?├── stuff.nix # ???
Documentation
Section titled “Documentation”# Good: Document what profile provides{ config, pkgs, ... }:{ # Frontend Development Profile # # Provides: # - Node.js and package managers (npm, pnpm, yarn) # - Build tools (webpack, vite) # - Linters and formatters (eslint, prettier) # - Browser tools (playwright)
environment.systemPackages = with pkgs; [ # ... packages ];}
Examples
Section titled “Examples”Example 1: Language Profile
Section titled “Example 1: Language Profile”{ config, pkgs, ... }:{ # Go development tools environment.systemPackages = with pkgs; [ # Compiler and tools go gopls # Language server gotools # go fmt, go imports, etc golangci-lint # Linting delve # Debugger
# Database tools (for Go apps) sqlite postgresql ];
# Environment variables environment.variables = { GOPATH = "$HOME/go"; GOBIN = "$HOME/go/bin"; };
# Shell configuration programs.zsh.shellAliases = { got = "go test ./..."; gob = "go build"; gor = "go run ."; };}
Example 2: Role-Based Profile
Section titled “Example 2: Role-Based Profile”{ config, pkgs, ... }:{ # DevOps engineer profile environment.systemPackages = with pkgs; [ # Cloud awscli2 google-cloud-sdk azure-cli
# Containers docker kubectl helm k9s
# Infrastructure terraform ansible packer
# Monitoring prometheus grafana
# Scripting python3 bash ];
# Kubernetes config environment.variables = { KUBECONFIG = "$HOME/.kube/config"; };}
Example 3: Security Profile
Section titled “Example 3: Security Profile”{ config, pkgs, ... }:{ # Security tools profile environment.systemPackages = with pkgs; [ # Scanning nmap masscan rustscan
# Analysis wireshark tcpdump burpsuite
# Cryptography gnupg age sops openssl
# Password management pass gopass ];
# Security-focused settings environment.variables = { GNUPGHOME = "$HOME/.gnupg"; };
programs.gnupg.agent.enable = true;}
Example 4: AI/ML Profile
Section titled “Example 4: AI/ML Profile”{ config, pkgs, ... }:{ # AI/ML development profile environment.systemPackages = with pkgs; [ # Python for ML python3 python3Packages.pip
# ML frameworks (via pip/poetry) poetry
# Jupyter python3Packages.jupyter python3Packages.ipython
# GPU tools (if available) cudaPackages.cudatoolkit ];
# Python packages via overlay nixpkgs.overlays = [ (final: prev: { python3 = prev.python3.override { packageOverrides = pyfinal: pyprev: { # Custom Python packages }; }; }) ];}
Example 5: Minimal Profile
Section titled “Example 5: Minimal Profile”{ config, pkgs, ... }:{ # Minimal base profile environment.systemPackages = with pkgs; [ # Essential tools only git vim curl wget tree ];
programs.zsh = { enable = true; enableCompletion = true; };}
Testing Profiles
Section titled “Testing Profiles”Test Build
Section titled “Test Build”# Build without applyingdarwin-rebuild build --flake .#your-hostname
# Check what packages are addednix-store -q --tree ./result | grep -v "^/"
Enable/Disable
Section titled “Enable/Disable”# Easy to toggle{ imports = [ ../nix/profiles/developer.nix # ../nix/profiles/cloud-cli.nix # Disabled ];}
Profile Variants
Section titled “Profile Variants”# Create variantsimports = if config.work.enable then [ ../nix/profiles/cloud-aws.nix ../nix/profiles/devops.nix ] else [ ../nix/profiles/minimal.nix ];
Next Steps
Section titled “Next Steps”- Creating Modules - Write custom modules
- Adding Packages - Install software
- Working with Overlays - Customize packages
- Custom Profile Example - Complete walkthrough
Related Documentation
Section titled “Related Documentation”- Structure Guide - Profile system explained
- Profiles Reference - All profiles documented
- Examples - Practical examples
External References
Section titled “External References”- NixOS Profiles - Wiki documentation
- Nix Modules - Module system
- Configuration Patterns - Nix Pills
Ready to create profiles? Start with a simple profile!