
- Removed system/ directory, merged applications into users/geir.nix - Simplified fonts.nix to bare minimum (users can add more) - Moved transmission.nix to sleeper-service/services/ (machine-specific) - Organized grey-area services into services/ directory - Updated import paths and tested all configurations - Added research documentation for deploy-rs and GNU Stow
10 KiB
GNU Stow Research Summary
Overview
GNU Stow is a symlink farm manager that helps organize and deploy dotfiles and software packages. It creates symbolic links from a source directory to a target directory, making it ideal for managing dotfiles across multiple systems without copying files.
Repository: https://www.gnu.org/software/stow/ Language: Perl License: GPL-3.0+ Status: Mature, stable, widely adopted
Core Concept
Stow works by creating symbolic links from a "stow directory" (source) to a "target directory" (typically $HOME
). Each subdirectory in the stow directory represents a "package" that can be independently stowed or unstowed.
dotfiles/ # Stow directory
├── zsh/ # Package: zsh configuration
│ └── .zshrc # Will link to ~/.zshrc
├── emacs/ # Package: emacs configuration
│ └── .emacs.d/ # Will link to ~/.emacs.d/
│ └── init.el
└── git/ # Package: git configuration
└── .gitconfig # Will link to ~/.gitconfig
Key Features
🔗 Symlink Management
- Non-destructive: Creates symlinks without overwriting existing files
- Conflict detection: Warns about file conflicts before creating links
- Tree folding: Optimizes symlink structure for efficiency
- Partial deployment: Deploy only specific packages (e.g., just zsh config)
📦 Package-Based Organization
- Modular structure: Each application gets its own package directory
- Selective deployment: Install only needed configurations per machine
- Easy maintenance: Add/remove configurations without affecting others
- Version control friendly: Git can track each package independently
🛡️ Safety Features
- Dry-run mode: Preview what would be done without making changes
- Conflict resolution: Handles existing files and directories gracefully
- Rollback capability: Easy to unstow (remove) configurations
- Target verification: Ensures target directory exists and is writable
Command Examples
# Basic stow operations
cd ~/dotfiles
stow zsh # Deploy zsh configuration
stow emacs git # Deploy multiple packages
stow --target=/opt/local mypackage # Custom target directory
# Management operations
stow --delete zsh # Remove zsh symlinks (unstow)
stow --restow emacs # Restow (unstow then stow again)
stow --simulate zsh # Dry run - show what would happen
# Advanced usage
stow --verbose zsh # Verbose output
stow --no-folding emacs # Disable tree folding optimization
stow --ignore='\.DS_Store' zsh # Ignore certain files
Directory Structure Example
~/dotfiles/ # Stow directory
├── zsh/ # Package: ZSH
│ ├── .zshrc # → ~/.zshrc
│ └── .config/ # → ~/.config/
│ └── zsh/ # → ~/.config/zsh/
│ └── aliases.zsh # → ~/.config/zsh/aliases.zsh
├── emacs/ # Package: Emacs
│ ├── .emacs.d/ # → ~/.emacs.d/
│ │ ├── init.el # → ~/.emacs.d/init.el
│ │ └── config.org # → ~/.emacs.d/config.org
│ └── .config/ # → ~/.config/
│ └── emacs/ # → ~/.config/emacs/
├── git/ # Package: Git
│ ├── .gitconfig # → ~/.gitconfig
│ └── .gitignore_global # → ~/.gitignore_global
└── nixos/ # Package: NixOS-specific
└── .config/ # → ~/.config/
└── nixos/ # → ~/.config/nixos/
└── user.nix # → ~/.config/nixos/user.nix
Comparison with Current Org-Mode Approach
Feature | Current Org-Mode | GNU Stow |
---|---|---|
Configuration format | Literate programming | Traditional dotfiles |
Deployment method | Tangle + copy/symlink | Automatic symlinking |
Documentation | Embedded in code | Separate documentation |
Version control | Single org file | Multiple files in packages |
Learning curve | Steep (Emacs/Org) | Gentle (simple concept) |
Flexibility | Very high | Moderate |
Maintenance | Manual tangling | Automatic linking |
Cross-platform | Excellent | Excellent |
NixOS integration | Native | External tool |
Advantages of GNU Stow
✅ Simplicity & Reliability
- Minimal learning curve: Understand symlinks = understand Stow
- No dependencies: Works on any Unix-like system with Perl
- Predictable behavior: Simple, well-defined symlink creation rules
- Mature and stable: Decades of development and testing
✅ Flexible Organization
- Package-based: Logical separation of application configurations
- Selective deployment: Deploy only needed configs per machine
- Easy experimentation: Test new configs without affecting others
- Conflict handling: Safe deployment with conflict detection
✅ Version Control Benefits
- Git-friendly: Each package can be tracked separately
- Branching: Different branches for different machine types
- History: Track changes to individual application configs
- Collaboration: Easy to share specific application configurations
✅ Multi-Machine Management
# Different configs for different machine types
stow --target=/home/geir desktop # Desktop-specific configs
stow --target=/home/sma server # Server-specific configs
# Machine-specific packages
dotfiles/
├── desktop-geir/ # Only for desktop user geir
├── server-sma/ # Only for server user sma
└── common/ # Shared configurations
Disadvantages & Limitations
❌ Compared to Org-Mode Approach
- No literate programming: Configuration and documentation separate
- Less integration: Not as tightly integrated with Emacs workflow
- File-based: No ability to generate configs from templates
- Static configuration: Less dynamic than org-mode tangling
❌ General Limitations
- Symlink visibility: Some applications don't handle symlinks well
- Permission issues: Target directory permissions must be correct
- Perl dependency: Requires Perl runtime (usually not an issue)
- No config generation: Can't generate configs based on system state
Integration with Current NixOS Setup
🎯 Hybrid Approach Options
Option 1: Stow for Traditional Dotfiles
# Keep org-mode for complex Emacs config
# Use Stow for simple dotfiles
dotfiles/
├── emacs.org # Keep current literate approach
├── zsh/ # Simple dotfiles via Stow
│ └── .zshrc
└── git/
└── .gitconfig
Option 2: User-Specific Deployment
# Different approaches per user
~/dotfiles-geir/ # Org-mode for desktop user
~/dotfiles-sma/ # Stow for server user (simpler configs)
Option 3: NixOS + Stow Integration
# In NixOS configuration
environment.systemPackages = [ pkgs.stow ];
# User activation script
system.userActivationScripts.stow-dotfiles = ''
cd /home/geir/dotfiles
${pkgs.stow}/bin/stow --target=/home/geir common zsh git
'';
🔧 Implementation Strategies
For Server Configurations (sma user):
- Simple, minimal dotfiles via Stow
- Basic shell, git, and utility configurations
- No complex literate programming needed
For Desktop Configurations (geir user):
- Keep org-mode for Emacs (complex, well-integrated)
- Consider Stow for simpler applications (git, zsh aliases)
- Hybrid approach based on complexity
Practical Examples
📝 Basic Setup
# Initialize dotfiles repository
mkdir ~/dotfiles
cd ~/dotfiles
# Create package structure
mkdir -p zsh git emacs
# Add configurations
echo 'alias ll="ls -la"' > zsh/.zshrc
echo '[user]
name = Geir Okkenhaug Jerstad
email = geir@geokkjer.eu' > git/.gitconfig
# Deploy configurations
stow zsh git
🏠 Home Lab Specific Usage
# Machine-specific dotfiles
dotfiles/
├── server-common/ # Shared server configs
│ ├── .zshrc
│ └── .vimrc
├── sleeper-service/ # NFS-specific configs
│ └── .config/
│ └── nfs/
└── grey-area/ # Git server specific
└── .gitconfig
# Deploy on sleeper-service
stow server-common sleeper-service
# Deploy on grey-area
stow server-common grey-area
🔄 Migration Strategy
# Phase 1: Extract simple configs from org-mode
emacs config.org
# Tangle simple configs to separate files
# Create Stow packages for extracted configs
# Phase 2: Test Stow deployment
stow --simulate zsh # Test before applying
stow zsh # Deploy if tests pass
# Phase 3: Maintain hybrid approach
# Keep org-mode for complex configs (Emacs)
# Use Stow for simple configs (shell, git)
Integration with Current Workflow
🎯 Recommended Approach for Home Lab
Keep Current Org-Mode For:
- Emacs configuration (complex, well-integrated)
- Complex, documented configurations
- Configurations that benefit from literate programming
Use GNU Stow For:
- Server user (sma) configurations
- Simple shell configurations
- Git configurations
- Application-specific dotfiles that don't need documentation
Implementation Plan:
- Create stow repository for server configs
- Test on sleeper-service with sma user
- Gradually migrate simple configs from org-mode
- Maintain hybrid approach based on complexity needs
Conclusion & Recommendation
🎯 For Our Home Lab Context
GNU Stow is excellent for:
- Server configurations (sma user)
- Simple, stable dotfiles
- Multi-machine deployments
- Configurations that don't need complex documentation
Current org-mode approach excels for:
- Complex Emacs configurations
- Documented, literate configurations
- Generated configurations
- Desktop user (geir) complex setups
📋 Action Plan
- Immediate: Create stow-based dotfiles repository for server users
- Short-term: Deploy simple sma user configs via Stow on sleeper-service
- Medium-term: Evaluate migration of simple configs from org-mode
- Long-term: Maintain hybrid approach - Stow for simple, org-mode for complex
Verdict: GNU Stow is an excellent complement to our current org-mode approach. Use Stow for simple, server-side configurations while keeping org-mode for complex desktop configurations. This provides the best of both worlds - simplicity where appropriate, power where needed.