NixOS Configuration Patterns

NixOS allows you to describe your entire system configuration declaratively. This guide explores practical patterns and techniques for managing NixOS systems in production environments.

The NixOS Module System

NixOS uses a modular configuration system that allows you to organize settings into reusable modules:

# Basic structure of a NixOS module
{ config, pkgs, lib, ... }:

with lib;

{
  # Module options (schema)
  options.services.myservice = {
    enable = mkEnableOption "myservice";
    
    port = mkOption {
      type = types.port;
      default = 8080;
      description = "Port to listen on";
    };
    
    logLevel = mkOption {
      type = types.enum [ "debug" "info" "warn" "error" ];
      default = "info";
      description = "Logging verbosity level";
    };
  };

  # Module implementation
  config = mkIf config.services.myservice.enable {
    systemd.services.myservice = {
      description = "My Custom Service";
      wantedBy = [ "multi-user.target" ];
      
      serviceConfig = {
        ExecStart = "${pkgs.myservice}/bin/myservice --port ${toString config.services.myservice.port} --log-level ${config.services.myservice.logLevel}";
        Restart = "always";
        User = "myservice";
      };
    };
    
    # Create the system user
    users.users.myservice = {
      isSystemUser = true;
      createHome = true;
      home = "/var/lib/myservice";
      group = "myservice";
    };
    
    users.groups.myservice = {};
    
    # Ensure data directory exists
    systemd.tmpfiles.rules = [
      "d /var/lib/myservice 0750 myservice myservice -"
    ];
  };
}

System Architecture Patterns

Layered System Configuration

Structure your configuration in layers, from most general to most specific:

Multi-Environment Configuration

Manage development, staging, and production environments using conditionals:

Service Configuration Patterns

Service Factory Pattern

Create a factory function to generate consistent service configurations:

Usage example:

Consistent Database Services

Create a standard pattern for database services:

Usage example:

Security Patterns

Defense in Depth Configuration

Apply multiple layers of security:

Networking Patterns

Multi-Environment Network Configuration

Manage network configurations across different environments:

Storage and Filesystem Patterns

Resilient Storage Configuration

Configure storage with reliability in mind:

Deployment and Upgrade Patterns

Atomic Upgrades and Rollbacks

Leverage NixOS's atomic upgrade capabilities:

Infrastructure as Code Integration

Terraform Integration

Use NixOS to provision and configure cloud resources:

Monitoring and Observability Patterns

Comprehensive System Monitoring

Set up robust monitoring for system health:

Conclusion

These NixOS configuration patterns help build maintainable and reliable systems for DevOps environments. They leverage NixOS's declarative approach to create consistent, reproducible infrastructure that can easily scale from development to production environments.

By using these patterns, you can develop a standard approach to system configuration that reduces maintenance overhead, improves security, and makes your infrastructure more predictable across all environments.

Further Resources

Last updated