home-lab/research/gnu-stow.md
Geir Okkenhaug Jerstad 9837d82199 Refactor: Simplify module structure and reorganize services
- 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
2025-06-07 12:11:20 +02:00

300 lines
No EOL
10 KiB
Markdown

# 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
```bash
# 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**
```bash
# 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**
```bash
# 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**
```bash
# Different approaches per user
~/dotfiles-geir/ # Org-mode for desktop user
~/dotfiles-sma/ # Stow for server user (simpler configs)
```
**Option 3: NixOS + Stow Integration**
```nix
# 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**
```bash
# 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**
```bash
# 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**
```bash
# 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:**
1. **Create stow repository** for server configs
2. **Test on sleeper-service** with sma user
3. **Gradually migrate** simple configs from org-mode
4. **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**
1. **Immediate**: Create stow-based dotfiles repository for server users
2. **Short-term**: Deploy simple sma user configs via Stow on sleeper-service
3. **Medium-term**: Evaluate migration of simple configs from org-mode
4. **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.