Nix Config
A set of configs for my machines:
- powerhouse (desktop) - NixOS
- capacitor (server) - NixOS
- turbine (laptop) - macOS with nix-darwin
Features
- Modular Architecture: 17+ organized modules across 9 categories for maximum reusability
- Cross-platform: Supports both NixOS and macOS with shared configurations
- Home Manager integration: User-specific configs with modular component imports
- Unified GPG/SSH: Integrated authentication and encryption strategy
- Homebrew support (macOS): GUI applications and Mac-specific software
- Minimal approach: Prefer nixpkgs over Homebrew when possible
- Cross-compilation: Build and validate nix-darwin configs from Linux
Quick Start
Prerequisites
- Install Nix with flakes enabled
- Clone this repository
- Enter the development environment
Development Environment
# Enter development shell
nix develop
# View available commands
just help
Building Configurations
# Build NixOS VM
just build-linux
# Cross-compile nix-darwin config from Linux
just build-darwin
# Validate nix-darwin config (faster)
just check-darwin
Repository Structure
├── docs/ # Documentation
├── hosts/ # Host-specific configurations
│ ├── powerhouse/ # NixOS desktop
│ └── turbine/ # macOS laptop
├── modules/ # Modular components (17+ modules)
│ ├── desktop/ # Desktop environments (hyprland)
│ ├── fonts/ # Font configurations
│ ├── hardware/ # Hardware-specific modules (nvidia)
│ ├── network/ # Network configurations (wireguard)
│ ├── os/ # Operating system modules (common, darwin, nixos)
│ ├── programs/ # Application configurations (git)
│ ├── security/ # Security modules (gpg, ssh, gpg-agent)
│ ├── terminal/ # Terminal tools (nvim, starship, tmux, zsh)
│ └── virtualization/ # Virtualization tools (podman, qemu)
├── users/ # User-specific configurations
├── flake.nix # Main flake configuration
└── justfile # Development commands
Module Architecture
The configuration is built using a modular approach where each component serves a specific purpose:
OS Modules (modules/os/
)
common.nix
- Universal settings for all systemsnixos.nix
- NixOS-specific configurationsdarwin.nix
- macOS-specific configurations
User-specific Modules
modules/terminal/
- Shell, terminal emulators, and CLI toolsmodules/security/
- GPG, SSH, and authenticationmodules/programs/
- Application-specific configurations
System Modules
modules/hardware/
- Hardware-specific configurationsmodules/network/
- Network and VPN configurationsmodules/desktop/
- Desktop environment configurationsmodules/virtualization/
- Container and VM configurations
Configuration Import Strategy
Host Configurations (hosts/*/config.nix
):
imports = [
../../modules/os/common.nix # Universal settings
../../modules/os/nixos.nix # or darwin.nix for macOS
./hardware.nix # Host-specific hardware
];
User Configurations (users/*/home.nix
):
imports = [
../../modules/terminal/zsh.nix
../../modules/security/gpg.nix
../../modules/programs/git.nix
# Add modules as needed
];
Getting Help
- Check the documentation in the navigation menu
- Run
just help
for available commands - Review existing configurations in the hosts/ directory
- Explore modules in the modules/ directory for reusable components
- See module import examples in users/brancengregory/home.nix
- See GitHub Copilot Agent for development environment details
Adding New Modules
To add a new module:
- Create the module file in the appropriate
modules/
subdirectory - Follow the existing module structure and naming conventions
- Import the module in the relevant host or user configuration
- Test the configuration with
just check-darwin
orjust build-linux
Module Architecture
This configuration uses a modular architecture with 17+ modules organized across 9 categories. Each module encapsulates specific functionality and can be imported as needed by host and user configurations.
Module Categories
Desktop Modules (modules/desktop/
)
- hyprland.nix - Hyprland window manager configuration
Font Modules (modules/fonts/
)
- default.nix - System font configurations and font packages
Hardware Modules (modules/hardware/
)
- nvidia.nix - NVIDIA GPU drivers and configuration
Network Modules (modules/network/
)
- wireguard.nix - WireGuard VPN configuration
OS Modules (modules/os/
)
- common.nix - Universal settings for all systems (Nix features, experimental flags)
- nixos.nix - NixOS-specific system configurations
- darwin.nix - macOS-specific system configurations
Program Modules (modules/programs/
)
- git.nix - Git configuration and aliases
Security Modules (modules/security/
)
- gpg.nix - GPG configuration and key management
- gpg-agent.nix - GPG agent configuration
- ssh.nix - SSH client and server configuration
Terminal Modules (modules/terminal/
)
- nvim.nix - Neovim editor configuration
- starship.nix - Starship prompt configuration
- tmux.nix - Terminal multiplexer configuration
- zsh.nix - Z shell configuration and plugins
Virtualization Modules (modules/virtualization/
)
- podman.nix - Podman container runtime
- qemu.nix - QEMU virtualization platform
Module Usage Patterns
Host Configuration Pattern
Host configurations (hosts/*/config.nix
) typically import:
- OS-specific modules (
modules/os/common.nix
+modules/os/nixos.nix
ormodules/os/darwin.nix
) - Hardware-specific modules as needed
- Host-specific hardware configuration
Example:
{pkgs, ...}: {
imports = [
../../modules/os/common.nix # Universal settings
../../modules/os/nixos.nix # NixOS-specific settings
./hardware.nix # Host hardware config
];
networking.hostName = "powerhouse";
system.stateVersion = "25.05";
}
User Configuration Pattern
User configurations (users/*/home.nix
) import user-specific modules:
{pkgs, ...}: {
imports = [
../../modules/fonts/default.nix
../../modules/terminal/zsh.nix
../../modules/terminal/starship.nix
../../modules/terminal/tmux.nix
../../modules/terminal/nvim.nix
../../modules/security/gpg.nix
../../modules/security/ssh.nix
../../modules/security/gpg-agent.nix
../../modules/network/wireguard.nix
../../modules/programs/git.nix
];
# User-specific configuration
home.username = "username";
# ... rest of configuration
}
Cross-Platform Compatibility
Modules are designed to work across NixOS and macOS:
- OS modules provide platform-specific configurations
- User modules use conditional logic for platform differences
- Hardware modules are imported only when relevant
Example of cross-platform user configuration:
home.homeDirectory =
if pkgs.stdenv.isLinux
then "/home/username"
else if pkgs.stdenv.isDarwin
then "/Users/username"
else throw "Unsupported OS";
Adding New Modules
1. Choose the Right Category
Place your module in the appropriate directory:
- System-level configs →
modules/os/
- User programs →
modules/programs/
- Terminal tools →
modules/terminal/
- Security configs →
modules/security/
- etc.
2. Follow Module Structure
{pkgs, ...}: {
# Module configuration here
# Use conditional logic for cross-platform support if needed
}
3. Import in Configurations
Add the module import to relevant host or user configurations:
imports = [
../../modules/category/your-module.nix
# ... other imports
];
4. Test the Configuration
# Validate syntax
nix flake check
# Test darwin config
just check-darwin
# Test NixOS config
just build-linux
Module Dependencies
Modules can depend on other modules by importing them:
{pkgs, ...}: {
imports = [
./base-module.nix
];
# Additional configuration
}
Keep dependencies minimal and well-documented to maintain modularity.
Unified GPG/SSH Strategy
This document outlines the streamlined GPG/SSH configuration implemented across the nix-config ecosystem, providing secure, unified authentication and encryption for both Linux (powerhouse) and macOS (turbine) systems.
Overview
The strategy implements a performance-optimized, secure approach where:
- GPG agent serves as the central authentication hub for both GPG operations and SSH authentication
- Cross-platform compatibility ensures consistent behavior on Linux and macOS
- Streamlined configuration with essential security settings and optimized performance
- Unified configuration managed through home-manager for consistency
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ GPG Client │ │ SSH Client │ │ Git (signed) │
└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
┌─────────────▼──────────────┐
│ GPG Agent │
│ ┌─────────────────────┐ │
│ │ GPG Authentication │ │
│ │ SSH Authentication │ │
│ │ Key Management │ │
│ │ Smart Card Support │ │
│ └─────────────────────┘ │
└────────────────────────────┘
Key Features
Streamlined Security Configuration
- Essential Algorithms: AES256, SHA512, Ed25519 (focused on widely-used, secure algorithms)
- Balanced SSH Settings: Secure but not overly restrictive configurations
- Optimized Cache Settings: 8-24 hour cache TTL for good balance of security and usability
Performance Optimizations
- Lazy GPG Agent Initialization: Only starts/connects when needed
- Efficient Tmux Integration: Uses session/client events instead of frequent pane switches
- Streamlined Environment Setup: Reduced conditional logic and redundant checks
- Minimal Configuration: Essential settings only, removing rarely-used options
Cross-Platform Support
- Unified Pinentry: Terminal-based pinentry-curses for consistent operation
- Platform-Specific Optimizations: Tailored socket handling for Linux/macOS
- Consistent Shell Experience: Same behavior across all platforms
Integration Features
- Git Signing: Automatic commit signing with GPG
- SSH Authentication: GPG keys used for SSH instead of separate SSH keys
- Smart Card Support: Hardware token integration ready
- Agent Management: Lazy startup and optimized TTY handling
Optimized Tmux Configuration
The strategy includes performance-optimized tmux configuration with:
programs.tmux = {
enable = true;
extraConfig = ''
# Streamlined environment variable passing
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION SSH_AUTH_SOCK WINDOWID XAUTHORITY GPG_TTY"
# Efficient GPG_TTY updates - only when creating sessions or attaching clients
set-hook -g session-created 'run-shell "export GPG_TTY=$(tty) && gpg-connect-agent updatestartuptty /bye >/dev/null 2>&1 || true"'
set-hook -g client-attached 'run-shell "export GPG_TTY=$(tty) && gpg-connect-agent updatestartuptty /bye >/dev/null 2>&1 || true"'
'';
};
This ensures:
- Environment variables are properly inherited in new tmux panes
- GPG_TTY is updated only when necessary (session creation/client attachment)
- SSH authentication works consistently across all tmux sessions
- Performance improvement: Eliminates expensive pane-focus-in hooks
Configuration Files
The strategy is implemented across several configuration files:
users/brancengregory/home.nix
: Main GPG/SSH configuration- Environment variables: Cross-platform GPG agent integration
- Platform-specific: Pinentry and socket configuration
Initial Setup
1. Generate GPG Master Key
# Generate a new GPG key with strong settings
gpg --full-gen-key
# Choose:
# (1) RSA and RSA (default) or (9) ECC and ECC
# Key size: 4096 bits (RSA) or Curve 25519 (ECC)
# Valid for: 1-2 years (recommended)
# Real name: Brancen Gregory
# Email: brancengregory@gmail.com
2. Generate SSH Authentication Subkey
# Add SSH authentication capability to your GPG key
gpg --edit-key brancengregory@gmail.com
# In GPG prompt:
gpg> addkey
# Choose (8) RSA (set your own capabilities)
# Toggle off Sign and Encrypt, toggle on Authenticate
# Or choose (10) ECC (set your own capabilities) for Ed25519
gpg> save
3. Export SSH Public Key
# Export SSH public key from GPG
gpg --export-ssh-key brancengregory@gmail.com
# Add this to GitHub, GitLab, servers, etc.
4. Configure Git Signing
# Set your GPG signing key (if not using default)
git config --global user.signingkey YOUR_GPG_KEY_ID
# Verify signing works
git commit --allow-empty -m "Test GPG signing"
git log --show-signature -1
Tmux Integration
The configuration includes performance-optimized tmux support to ensure GPG and SSH work seamlessly within tmux sessions.
Optimized Tmux Features
- Lazy GPG_TTY Updates: Updates GPG_TTY only when creating sessions or attaching clients, not on every pane switch
- SSH agent socket management: Ensures consistent SSH authentication in tmux
- Terminal pinentry optimization: Configured for efficient operation in tmux sessions
- Performance improvement: Eliminates frequent hook executions that could slow down tmux
Usage in Tmux
# Start tmux session
tmux new-session -s work
# SSH from within tmux (works seamlessly)
ssh git@github.com
# Git operations work with automatic signing
git commit -m "Update from tmux session"
git push
# If you encounter issues, manually refresh GPG state
refresh_gpg
Troubleshooting Tmux Issues
If you encounter pinentry or authentication issues in tmux:
# Check GPG agent status
gpg-status
# Restart GPG agent if needed
gpg-restart
# Manually refresh GPG state in current pane
refresh_gpg
# Check SSH keys are loaded
ssh-keys
# Verify SSH socket is correct
echo $SSH_AUTH_SOCK
Daily Usage
SSH Authentication
With the unified strategy, SSH authentication works seamlessly:
# SSH uses your GPG key automatically
ssh git@github.com
# SSH to personal servers
ssh user@server.com
GPG Operations
Standard GPG operations work as expected:
# Encrypt files
gpg --encrypt --recipient brancengregory@gmail.com file.txt
# Sign files
gpg --sign file.txt
# Decrypt/verify
gpg --decrypt file.txt.gpg
Git Integration
Git automatically signs commits with your GPG key:
# Commits are automatically signed
git commit -m "Update configuration"
# Verify signatures
git log --show-signature
Key Management
Backup Strategy
# Export your master key (keep this VERY secure)
gpg --export-secret-keys --armor brancengregory@gmail.com > private-key-backup.asc
# Export public key (safe to share)
gpg --export --armor brancengregory@gmail.com > public-key.asc
# Export revocation certificate
gpg --gen-revoke brancengregory@gmail.com > revocation-cert.asc
Key Rotation
Plan to rotate keys periodically:
- Annual Review: Check key expiration and usage
- Subkey Rotation: Rotate subkeys more frequently than master key
- Revocation: Have revocation certificates ready for emergency use
Troubleshooting
GPG Agent Issues
# Restart GPG agent
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
# Check agent status
gpg-connect-agent 'keyinfo --list' /bye
# Use helpful aliases
gpg-restart # Restart agent
gpg-status # Check status
gpg-refresh # Refresh in tmux pane
SSH Authentication Problems
# Check SSH agent socket
echo $SSH_AUTH_SOCK
# List loaded SSH keys (should show GPG key)
ssh-add -l
# Force GPG agent refresh
gpg-connect-agent updatestartuptty /bye
# Use aliases for quick checks
ssh-keys # List SSH keys
Tmux-Specific Issues
Problem: Pinentry appears in wrong pane or doesn't appear at all
# Solution 1: Refresh GPG state in current pane
refresh_gpg
# Solution 2: Restart GPG agent completely
gpg-restart
# Solution 3: Check GPG_TTY is set correctly
echo $GPG_TTY
Problem: SSH authentication fails in tmux but works outside
# Check SSH socket in tmux session
echo $SSH_AUTH_SOCK
# Verify the socket file exists
ls -la $SSH_AUTH_SOCK
# If socket is missing, restart the session or refresh
refresh_gpg
Problem: Git signing fails in tmux
# Check GPG agent can sign
echo "test" | gpg --clearsign
# Refresh GPG state if needed
refresh_gpg
# Test Git signing explicitly
git commit --allow-empty -m "Test commit" --gpg-sign
Platform-Specific Issues
Linux:
# Check XDG runtime directory
echo $XDG_RUNTIME_DIR
# Verify socket exists
ls -la $XDG_RUNTIME_DIR/gnupg/
macOS:
# Check GPG agent socket
gpgconf --list-dirs agent-ssh-socket
# Verify agent is running
gpgconf --check-programs
Security Considerations
Best Practices
- Strong Passphrases: Use long, unique passphrases for GPG keys
- Limited Scope: Use separate subkeys for different purposes
- Regular Rotation: Plan key rotation schedule
- Secure Storage: Keep master key backup in secure location
- Revocation Ready: Maintain current revocation certificates
Trust Model
- Web of Trust: Participate in key signing when appropriate
- Key Verification: Always verify key fingerprints out-of-band
- Certificate Authorities: Consider using keyserver certificates for verification
Hardware Tokens
The configuration supports hardware tokens (YubiKey, etc.):
- Smart Card Support:
enableScDaemon = true
in GPG agent - Key Generation: Generate keys directly on hardware token
- Backup Strategy: Ensure backup authentication methods
Integration with Services
GitHub/GitLab
- Add your SSH public key to your profile
- Commits will be automatically signed
- SSH authentication works seamlessly
Personal Servers
- Add SSH public key to
~/.ssh/authorized_keys
- Configure host-specific settings in SSH config
- Optionally use GPG for server encryption/signing
Maintenance
Regular Tasks
- Weekly: Check agent status and key usage
- Monthly: Review SSH connections and Git signatures
- Quarterly: Review key expiration dates
- Annually: Consider key rotation and security review
Monitoring
The configuration includes logging and monitoring capabilities:
- GPG agent logs authentication attempts
- SSH client logs connection details
- Git maintains signature verification history
Migration Guide
From Existing SSH Keys
- Backup current SSH keys
- Generate GPG authentication subkey
- Update authorized_keys on servers
- Test SSH authentication with GPG
- Remove old SSH keys once verified
From Existing GPG Setup
- Export current keys
- Apply new home-manager configuration
- Import keys to new agent
- Verify functionality
- Update any custom configurations
Further Reading
Security Guidelines
This document outlines security best practices and considerations for this nix-config repository.
Security Review Summary
✅ Repository Status: Ready for public transition
Security Audit Results
✅ Clean: No hardcoded secrets, API tokens, or private keys found
✅ Clean: No sensitive credentials committed to repository
✅ Clean: Strong security configurations implemented
✅ Fixed: Removed hardcoded password from user configuration
Security Configurations
SSH Security
- Password authentication disabled:
PasswordAuthentication no
- Strong ciphers: Modern encryption algorithms only
- Host key verification:
StrictHostKeyChecking ask
- No agent forwarding:
ForwardAgent no
andForwardX11 no
- Key algorithms: Ed25519 and strong RSA/ECDSA only
GPG Security
- Modern algorithms: SHA512, AES256, strong key preferences
- Secure defaults: No weak ciphers, strong S2K settings
- Key management: Proper keyserver configuration
- Hardware token support: Ready for YubiKey integration
User Account Security
- No hardcoded passwords: Users must set passwords during setup
- Wheel group: Administrative access properly configured
- Shell security: Zsh with proper configuration
Best Practices for Users
Initial Setup
- Set secure password: Run
sudo passwd brancengregory
after first boot - Generate GPG keys: Follow GPG-SSH-STRATEGY.md
- Configure SSH keys: Add your public keys to services (GitHub, etc.)
- Review configurations: Customize settings for your environment
Ongoing Security
- Regular updates: Keep system packages updated
- Key rotation: Follow GPG key rotation schedule
- Monitor access: Review SSH and GPG logs periodically
- Backup strategy: Secure backup of GPG keys and important data
Before Contributing
- No secrets: Never commit passwords, private keys, or API tokens
- Personal info: Remove personal email/username if contributing upstream
- Configuration review: Ensure changes don't introduce security vulnerabilities
Security Contact
For security-related questions or to report vulnerabilities:
- Open an issue with the "security" label
- Follow responsible disclosure practices
References
- GPG/SSH Strategy - Detailed security configuration
- NixOS Security - Official security documentation
- Home Manager Security - User-level security considerations
Homebrew Integration
This nix-darwin configuration includes Homebrew support for managing Mac applications. Here's how to use it:
Philosophy
- Prefer nixpkgs: Use packages from nixpkgs whenever possible (managed in
users/brancengregory/home.nix
) - Use Homebrew for GUI apps: GUI applications and Mac-specific software that aren't available or don't work well in nixpkgs
- Minimal Homebrew usage: Only use Homebrew when nixpkgs isn't sufficient
Configuration Files
modules/os/darwin.nix
: Contains Homebrew configuration (casks, brews, taps, masApps)users/brancengregory/home.nix
: Contains nixpkgs packages (CLI tools, fonts, etc.)
Adding Applications
GUI Applications (Recommended for Homebrew)
Edit modules/os/darwin.nix
and add applications to the casks
list:
casks = [
"visual-studio-code"
"docker"
"slack"
"1password"
];
CLI Tools (Recommended for nixpkgs)
Edit users/brancengregory/home.nix
and add packages to the home.packages
list:
home.packages = with pkgs; [
git
neovim
bat
# ... other packages
];
When to Use Homebrew for CLI Tools
Only use Homebrew brews
for CLI tools that:
- Aren't available in nixpkgs
- Don't work properly when installed via nixpkgs
- Require system integration that nixpkgs can't provide
Mac App Store Apps
For apps from the Mac App Store, add them to masApps
with their app ID:
masApps = {
"Xcode" = 497799835;
"Pages" = 409201541;
};
Migration from Existing Homebrew
If you already have Homebrew installations:
- Inventory existing apps: Run
brew list
andbrew list --cask
- Add to nix-darwin: Add the applications you want to keep to the appropriate lists
- Apply configuration: Run
darwin-rebuild switch --flake .#turbine
- Cleanup: The
cleanup = "zap"
setting will remove unmanaged packages
Applying Changes
After modifying the configuration:
darwin-rebuild switch --flake .#turbine
This will:
- Install new packages/casks
- Remove packages not in the configuration (due to
cleanup = "zap"
) - Update existing packages (due to
upgrade = true
)
Cross-Platform Development
This flake supports building and validating nix-darwin configurations from Linux systems.
Features
Cross-Compilation
Build nix-darwin configurations on Linux without requiring a macOS system:
# Build the full darwin configuration from Linux
nix build .#turbine-darwin
# Or use the convenience command
just build-darwin
# The result will be in ./result/
Configuration Validation
Validate nix-darwin configurations without performing a full build:
# Check if the darwin configuration is valid
nix build .#turbine-check
# Or use the convenience command
just check-darwin
# This is faster than a full build and useful for CI/testing
Note: Some darwin packages with system-specific dependencies may fail during cross-compilation. The validation target helps catch syntax and basic configuration errors without requiring full package builds.
Development Environment
Use the provided development shell for cross-platform work:
# Enter the development environment
nix develop
# Or
just dev
# This provides tools like nixos-rebuild, nix-output-monitor, alejandra, and just
Linux Builder Setup
For optimal performance when building nix-darwin configurations from Linux, you should set up nix-darwin's linux-builder feature. This enables remote building and improves cross-compilation performance.
What is nix-darwin's linux-builder?
The linux-builder is a virtual machine that runs on macOS and allows you to build Linux packages remotely. However, in our case, we're doing the reverse - building macOS packages from Linux. The linux-builder configuration in nix-darwin can be adapted for this purpose.
Setting up Remote Building
- Configure a macOS builder (if you have access to a macOS machine):
Add to your /etc/nix/nix.conf
on the Linux system:
builders = ssh://username@macos-host x86_64-darwin /path/to/remote/nix 2 1 kvm,nixos-test,big-parallel,benchmark
builders-use-substitutes = true
- Alternative: Use GitHub Actions macOS runners for CI/CD:
name: Build Darwin Config
on: [push, pull_request]
jobs:
build-darwin:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
- name: Validate darwin config
run: just check-darwin
build-darwin-native:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
- name: Build darwin config natively
run: just build-darwin
- Local cross-compilation (current setup):
For development and testing, you can use the cross-compilation support directly:
# Quick validation (recommended for most cases)
just check-darwin
# Full cross-compilation (may be slower without remote builder)
just build-darwin
Performance Tips
- Use
just check-darwin
for quick validation during development - Set up remote builders for production deployments
- Use binary caches to avoid rebuilding common packages:
# Add to your nix configuration
nix.settings.substituters = [
"https://cache.nixos.org/"
"https://nix-community.cachix.org"
];
Troubleshooting
If you encounter issues with cross-compilation:
-
Check available builders:
nix show-config | grep builders
-
Verify cross-compilation support:
nix-instantiate --eval -E 'builtins.currentSystem'
-
Use verbose output for debugging:
nix build .#turbine-darwin --verbose
Use Cases
CI/CD Validation
In continuous integration, you can validate both NixOS and nix-darwin configurations on Linux runners:
# Example GitHub Actions workflow
- name: Validate NixOS configuration
run: just build-linux
- name: Validate nix-darwin configuration
run: just check-darwin
- name: Cross-compile darwin configuration
run: just build-darwin
Development Workflow
When developing on Linux but targeting macOS:
- Edit configurations in your preferred Linux environment
- Validate syntax with
just check-darwin
- Cross-compile with
just build-darwin
to catch platform-specific issues - Deploy the configuration on actual macOS hardware when ready
Requirements
- Nix with flakes enabled
- Linux system with sufficient disk space for cross-compilation
- Network access to download dependencies
Troubleshooting
Build Errors
If cross-compilation fails:
- Check that all dependencies support the target platform
- Some macOS-specific packages may not cross-compile successfully
- Consider using remote builders for problematic packages
Performance
Cross-compilation can be resource-intensive:
- Use
nix build --max-jobs auto
to utilize all CPU cores - Consider using a remote darwin builder for better performance
- The validation target (
turbine-check
) is much faster than full builds
Remote Builders
For better performance, you can set up a remote macOS builder:
# In your nix configuration
nix.buildMachines = [{
hostName = "mac-builder.example.com";
system = "x86_64-darwin";
maxJobs = 4;
speedFactor = 2;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" ];
mandatoryFeatures = [ ];
}];
This allows Nix to automatically use the remote macOS system for darwin-specific builds.
GitHub Copilot Coding Agent Environment
This repository is configured with a GitHub Copilot coding agent environment that provides seamless access to all essential Nix development tools and commands.
Features
The Copilot agent environment automatically provides:
- Nix with flakes support - Reliable installation using DeterminateSystems/nix-installer-action
- Development shell - Access to all tools via
nix develop
- Command runner -
just
for convenient development commands - Code formatting -
alejandra
Nix formatter - Cross-compilation - Build and validate configs across platforms
- Testing framework - Automated validation and testing
- Binary caching - Fast builds with magic-nix-cache-action
Available Commands
Core Nix Commands
nix flake check # Check flake syntax and evaluate all outputs
nix develop # Enter development shell with all tools
nix build .#<package> # Build specific packages or configurations
Just Command Shortcuts
just help # Show all available development commands
just check # Check flake syntax (alias for nix flake check)
just check-darwin # Validate nix-darwin config (fast validation)
just build-darwin # Cross-compile full nix-darwin config from Linux
just build-linux # Build NixOS VM for testing
just format # Format Nix files using alejandra
just test # Run cross-compilation tests
just clean # Clean build results and artifacts
Environment Setup
The environment uses GitHub Copilot's official setup workflow approach:
-
Copilot Setup Steps -
.github/workflows/copilot-setup-steps.yml
follows GitHub's official documentation and uses:DeterminateSystems/nix-installer-action@main
for reliable, fast Nix installationDeterminateSystems/magic-nix-cache-action@main
for automatic binary caching- Proper flakes configuration and validation
-
Development Shell - The agent enters the Nix development shell defined in
flake.nix
-
Tool Access - All development tools become available (just, alejandra, etc.)
Benefits of GitHub Copilot Setup Approach
- Official - Follows GitHub's official documentation for Copilot setup steps
- Simple - Single workflow file instead of multiple configuration files
- Reliable - Uses proven, well-tested installation methods
- Speed - Fast installation (~4s on Linux, ~20s on macOS)
- Caching - Binary cache integration for faster builds
- Maintenance - Minimal configuration to maintain
- Compatibility - Works around firewall restrictions
Configuration Files
Primary Configuration
.github/workflows/copilot-setup-steps.yml
- GitHub Copilot setup workflow following official documentation
Supporting Files
flake.nix
- Nix flake with development shell definitionjustfile
- Development command shortcuts
The setup provides:
- Automatic Nix installation - Uses DeterminateSystems actions for reliable setup
- Development shell access - All tools available via
nix develop
- Flake validation - Ensures configuration syntax is correct
Validation
The copilot-setup-steps.yml workflow automatically validates the environment by:
- ✅ Installing Nix with flakes support
- ✅ Checking flake syntax with
nix flake check
- ✅ Entering development shell to verify tools are available
You can manually run the workflow to test the setup:
gh workflow run copilot-setup-steps.yml
Troubleshooting
Common Issues
"nix: command not found"
- The copilot-setup-steps.yml workflow automatically installs Nix
- Or manually install:
curl -L https://nixos.org/nix/install | sh
- Source environment:
source ~/.nix-profile/etc/profile.d/nix.sh
"experimental features not enabled"
- The copilot-setup-steps.yml workflow handles this automatically
- Manual fix:
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
"just: command not found"
- Enter dev shell first:
nix develop
- Or run commands via:
nix develop -c just <command>
Flake evaluation errors
- Check syntax:
nix flake check --no-build
- Update inputs:
nix flake update
GitHub Actions setup issues
- Check workflow logs for detailed error messages
- Ensure
DeterminateSystems/nix-installer-action@main
is used - Verify GitHub token permissions for private repositories
- Magic Nix Cache provides automatic caching for faster builds
Build failures
- Clean previous builds:
just clean
- Check available packages:
nix flake show
Development Workflow
The typical development workflow with the Copilot agent:
- Validate configuration:
nix flake check
- Make changes to Nix files
- Format code:
just format
- Test changes:
just test
or specific validation commands - Build configurations:
just build-darwin
orjust build-linux
Cross-Platform Support
The environment supports cross-platform development:
- Linux: Full support for NixOS configurations and cross-compilation to macOS
- macOS: Native nix-darwin support with Linux VM building capabilities
- Validation: Quick config validation without full builds using
just check-darwin
Integration with Repository
The Copilot agent environment is fully integrated with this repository's structure:
- Flake-based: Uses the
devShells
defined inflake.nix
- Just integration: All
justfile
commands are available - Cross-compilation: Supports the existing cross-platform workflow
- Testing: Integrates with existing test scripts
This provides the Copilot agent with full access to all development capabilities of this Nix configuration repository.
Contributing
This page outlines how to contribute to the Nix configuration and documentation.
Development Environment
- Install Nix with flakes enabled
- Clone the repository
- Enter the development environment:
nix develop
Making Changes
Configuration Changes
- Make your changes to the appropriate files in
hosts/
,modules/
, orusers/
- Test your changes:
just check-darwin # for nix-darwin configs just build-linux # for NixOS configs
- Format your code:
just format
Documentation Changes
- Edit the markdown files in the
docs/
directory - Build and preview the documentation:
just docs-build just docs-serve
- The documentation site will be automatically deployed when changes are merged to main
Available Commands
Run just help
to see all available development commands.