feat: initial NixOS home lab infrastructure setup

- Add modular flake-based NixOS configuration
- Implement GitOps foundation with CI/CD pipeline
- Create comprehensive documentation and branching strategy
- Add modular desktop environments (GNOME, Cosmic, Sway)
- Configure virtualization stack (Incus, Libvirt, Podman)
- Set up development tools and hardware-specific modules
- Establish user configuration with literate programming support

This commit represents the completion of Phase 1: Flakes Migration
with modular configuration, virtualization, and GitOps foundation.
This commit is contained in:
Geir Okkenhaug Jerstad 2025-06-04 16:10:13 +02:00
commit f30013723e
43 changed files with 4220 additions and 0 deletions

View file

@ -0,0 +1,118 @@
## 🏠 Home Lab Configuration Change
### 📋 Description
<!-- Describe what this PR does and why -->
### 🎯 Type of Change
<!-- Mark all that apply -->
- [ ] 🐛 Bug fix (non-breaking change that fixes an issue)
- [ ] ✨ New feature (non-breaking change that adds functionality)
- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] 📚 Documentation update
- [ ] 🔧 Configuration change
- [ ] 🏗️ Infrastructure change
- [ ] 🔒 Security update
### 🖥️ Affected Machines
<!-- Mark all machines affected by this change -->
- [ ] `congenital-optimist` (AMD workstation)
- [ ] `sleeper-service` (Intel file server)
- [ ] Both machines
- [ ] New machine configuration
### 🧪 Testing Performed
<!-- Describe how you tested these changes -->
- [ ] `nix flake check` passes
- [ ] `nixos-rebuild test --flake` successful
- [ ] `nixos-rebuild build --flake` successful
- [ ] Manual testing of affected functionality
- [ ] Rollback tested (if applicable)
### 📝 Testing Checklist
<!-- Check all items that were verified -->
#### System Functionality
- [ ] System boots successfully
- [ ] Network connectivity works
- [ ] Services start correctly
- [ ] No error messages in logs
#### Desktop Environment (if applicable)
- [ ] Desktop environment launches
- [ ] Applications start correctly
- [ ] Hardware acceleration works
- [ ] Audio/video functional
#### Virtualization (if applicable)
- [ ] Incus containers work
- [ ] Libvirt VMs functional
- [ ] Podman containers operational
- [ ] Network isolation correct
#### Development Environment (if applicable)
- [ ] Editors launch correctly
- [ ] Language servers work
- [ ] Build tools functional
- [ ] Git configuration correct
#### File Services (if applicable)
- [ ] NFS mounts accessible
- [ ] Samba shares working
- [ ] Backup services operational
- [ ] Storage pools healthy
### 🔒 Security Considerations
<!-- Any security implications of this change -->
- [ ] No new attack vectors introduced
- [ ] Secrets properly managed
- [ ] Firewall rules reviewed
- [ ] User permissions appropriate
### 📖 Documentation
<!-- Documentation changes -->
- [ ] README.md updated (if needed)
- [ ] Module documentation updated
- [ ] plan.md updated (if needed)
- [ ] Comments added to complex configurations
### 🔄 Rollback Plan
<!-- How to rollback if something goes wrong -->
- [ ] Previous configuration saved
- [ ] ZFS snapshot created
- [ ] Rollback procedure documented
- [ ] Emergency access method available
### 📋 Deployment Notes
<!-- Special considerations for deployment -->
- [ ] No special deployment steps required
- [ ] Requires manual intervention: <!-- describe -->
- [ ] Needs coordination with other changes
- [ ] Breaking change requires communication
### 🔗 Related Issues
<!-- Link any related issues -->
Fixes #<!-- issue number -->
Related to #<!-- issue number -->
### 📸 Screenshots/Logs
<!-- Add any relevant screenshots or log outputs -->
### ✅ Final Checklist
<!-- Verify before submitting -->
- [ ] I have tested this change locally
- [ ] I have updated documentation as needed
- [ ] I have considered the impact on other machines
- [ ] I have verified the rollback plan
- [ ] I have checked for any secrets in the code
- [ ] This change follows the repository's coding standards
### 🧠 Additional Context
<!-- Add any other context about the PR here -->
---
**Reviewer Guidelines:**
1. Verify all testing checkboxes are complete
2. Review configuration changes for security implications
3. Ensure rollback plan is realistic
4. Check that documentation is updated
5. Validate CI pipeline passes

233
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,233 @@
name: 🏠 Home Lab CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
schedule:
# Weekly dependency updates check
- cron: '0 0 * * 0'
env:
NIXPKGS_ALLOW_UNFREE: 1
jobs:
# Lint and validate flake configuration
validate:
name: 🔍 Validate Configuration
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
extra-conf: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Setup Nix Magic Cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Check flake syntax
run: nix flake check --all-systems
- name: Format check
run: |
nix fmt
git diff --exit-code
# Build configurations for all machines
build:
name: 🔨 Build Configurations
runs-on: ubuntu-latest
needs: validate
strategy:
matrix:
machine: [congenital-optimist, sleeper-service]
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
extra-conf: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Setup Nix Magic Cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build ${{ matrix.machine }} configuration
run: |
nix build .#nixosConfigurations.${{ matrix.machine }}.config.system.build.toplevel
- name: Check configuration size
run: |
nix path-info -S .#nixosConfigurations.${{ matrix.machine }}.config.system.build.toplevel
# Security and dependency auditing
security:
name: 🔒 Security Audit
runs-on: ubuntu-latest
needs: validate
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
extra-conf: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Setup Nix Magic Cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Run security audit
run: |
echo "TODO: Implement security auditing"
# Future: nix-audit or similar security tools
# Check for known vulnerabilities in dependencies
- name: Check for secrets in repository
run: |
echo "Checking for accidentally committed secrets..."
if grep -r "PRIVATE KEY\|password\|secret" . --exclude-dir=.git --exclude="*.md" --exclude=".github"; then
echo "❌ Potential secrets found in repository"
exit 1
else
echo "✅ No obvious secrets found"
fi
# Documentation and module validation
documentation:
name: 📚 Documentation & Modules
runs-on: ubuntu-latest
needs: validate
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
extra-conf: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Setup Nix Magic Cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Validate module structure
run: |
echo "Validating module structure..."
# Check that all modules have proper structure
for module in modules/*/*.nix; do
echo "Checking $module"
nix eval --file "$module" || echo "Warning: $module may have syntax issues"
done
- name: Generate documentation
run: |
echo "TODO: Generate system documentation"
# Future: Automatically generate module documentation
# Update README with current system state
# Update flake.lock and test
update-dependencies:
name: 🔄 Update Dependencies
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
extra-conf: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Setup Nix Magic Cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Update flake.lock
run: |
nix flake update
- name: Test updated dependencies
run: |
nix flake check
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "🔄 Update flake.lock - Automated dependency update"
title: "Automated dependency update"
body: |
## 🔄 Automated Dependency Update
This PR updates the flake.lock file with the latest versions of all inputs.
### Changes
- Updated all flake inputs to latest versions
- Ran `nix flake check` to ensure compatibility
### Validation
- [x] Flake syntax validation passed
- [x] Build tests completed successfully
Please review and test locally before merging.
branch: automated/update-dependencies
delete-branch: true
# Deployment (for self-hosted runners on actual machines)
deploy:
name: 🚀 Deploy Configuration
runs-on: self-hosted
needs: [validate, build, security]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Deploy to machines
run: |
echo "TODO: Implement deployment strategy"
# Future: Implement actual deployment
# This would require self-hosted runners on each machine
# or remote deployment via SSH
echo "Would deploy to:"
echo "- congenital-optimist"
echo "- sleeper-service"
# Notification on completion
notify:
name: 📢 Notify Results
runs-on: ubuntu-latest
needs: [validate, build, security, documentation]
if: always()
steps:
- name: Notify status
run: |
echo "Pipeline completed"
echo "Validate: ${{ needs.validate.result }}"
echo "Build: ${{ needs.build.result }}"
echo "Security: ${{ needs.security.result }}"
echo "Documentation: ${{ needs.documentation.result }}"
# Future: Send notifications to Discord/Slack/Email
# if any jobs failed

108
.gitignore vendored Normal file
View file

@ -0,0 +1,108 @@
# NixOS Home Lab - GitIgnore Configuration
# Infrastructure as Code for Multi-Machine NixOS Environment
## Nix Build Artifacts
result
result-*
.direnv/
.envrc
## NixOS System Generation Links
/result
/result-*
## Nix Store Symlinks
*.drv
*.drv.chk
## Development Shells
shell.nix.backup
default.nix.backup
## Backup Files
*.backup
*.bak
*.orig
*~
.#*
\#*#
## Temporary Files
*.tmp
*.temp
/tmp/
.cache/
## Editor Files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
## System-Specific Files
hardware-configuration.nix.backup
/boot/
/proc/
/sys/
/dev/
## Secrets and Keys (until we set up proper secrets management)
secrets/*.key
secrets/*.pem
secrets/*.cert
secrets/private/
*.age
*.gpg
## Log Files
*.log
logs/
/var/log/
## ZFS Snapshots (metadata only, not the snapshots themselves)
.zfs/
## CI/CD Artifacts
.github/workflows/artifacts/
ci-cache/
build-cache/
## Local Configuration Overrides
local.nix
override.nix
config.local.nix
## Machine-Specific Overrides (for testing)
machines/*/local-override.nix
machines/*/test-config.nix
## User-Specific Development Files
users/*/dotfiles/.tangled/
users/*/dotfiles/auto-generated/
users/*/dotfiles/*.el~
## Flake-specific ignores
.pre-commit-config.yaml.backup
.envrc.backup
## Documentation Build Artifacts
docs/_build/
docs/.doctrees/
*.pdf.tmp
## Nix Profile Links
.nix-profile
.nix-defexpr
## MacOS (if accessing from Mac)
.DS_Store
.AppleDouble
.LSOverride
## Windows (if accessing from Windows)
Thumbs.db
ehthumbs.db
Desktop.ini

259
BRANCHING_STRATEGY.md Normal file
View file

@ -0,0 +1,259 @@
# 🌳 Git Branching Strategy for Home Lab Infrastructure
## Branch Structure
### 🚀 Main Branches
#### `main`
- **Purpose**: Production-ready configurations
- **Protection**: Protected branch with required reviews
- **Deployment**: Automatically deployed to production machines
- **Stability**: Should always be stable and tested
#### `develop`
- **Purpose**: Integration branch for new features
- **Testing**: Continuous integration testing
- **Merging**: Features merge here first
- **Deployment**: Deployed to staging/test environments
### 🔧 Supporting Branches
#### Feature Branches: `feature/<description>`
- **Purpose**: Development of new features or modules
- **Naming**: `feature/add-cosmic-desktop`, `feature/sleeper-service-config`
- **Lifetime**: Temporary, deleted after merge
- **Source**: Branch from `develop`
- **Merge**: Merge back to `develop`
#### Machine Branches: `machine/<machine-name>`
- **Purpose**: Machine-specific configuration changes
- **Naming**: `machine/congenital-optimist`, `machine/sleeper-service`
- **Use Case**: Testing machine-specific changes
- **Merge**: Merge to `develop` after testing
#### Hotfix Branches: `hotfix/<issue>`
- **Purpose**: Critical fixes for production
- **Naming**: `hotfix/security-patch`, `hotfix/boot-failure`
- **Source**: Branch from `main`
- **Merge**: Merge to both `main` and `develop`
#### Module Branches: `module/<module-name>`
- **Purpose**: Development of specific modules
- **Naming**: `module/virtualization`, `module/desktop-gnome`
- **Scope**: Single module focus
- **Testing**: Module-specific testing
### 🏷️ Tagging Strategy
#### Version Tags: `v<major>.<minor>.<patch>`
- **Purpose**: Mark stable releases
- **Format**: `v1.0.0`, `v1.2.1`
- **Trigger**: Major configuration milestones
- **Deployment**: Tag triggers deployment workflows
#### Machine Tags: `<machine>-v<version>`
- **Purpose**: Machine-specific deployments
- **Format**: `congenital-optimist-v1.0.0`
- **Use Case**: Track per-machine configurations
- **Rollback**: Enable machine-specific rollbacks
#### Phase Tags: `phase-<number>-complete`
- **Purpose**: Mark migration phase completion
- **Format**: `phase-1-complete`, `phase-2-complete`
- **Documentation**: Link to plan.md milestones
## 🔄 Workflow Examples
### Standard Feature Development
```bash
# Start new feature
git checkout develop
git pull origin develop
git checkout -b feature/add-incus-clustering
# Develop and test
# ... make changes ...
nix flake check
sudo nixos-rebuild test --flake .#congenital-optimist
# Commit and push
git add .
git commit -m "feat: add Incus clustering support"
git push origin feature/add-incus-clustering
# Create PR to develop
# ... review process ...
# Merge to develop
```
### Machine-Specific Changes
```bash
# Machine-specific branch
git checkout develop
git checkout -b machine/sleeper-service
# Test on specific machine
sudo nixos-rebuild test --flake .#sleeper-service
# Commit and merge
git add .
git commit -m "feat(sleeper-service): add NFS server configuration"
```
### Hotfix Process
```bash
# Critical fix needed
git checkout main
git checkout -b hotfix/zfs-boot-failure
# Fix the issue
# ... emergency fix ...
sudo nixos-rebuild test --flake .#congenital-optimist
# Deploy to main
git add .
git commit -m "fix: resolve ZFS boot failure"
git checkout main
git merge hotfix/zfs-boot-failure
git tag v1.0.1
# Backport to develop
git checkout develop
git merge hotfix/zfs-boot-failure
```
## 📋 Commit Convention
### Format
```
<type>(<scope>): <description>
[optional body]
[optional footer]
```
### Types
- **feat**: New feature or module
- **fix**: Bug fix
- **docs**: Documentation changes
- **style**: Formatting, missing semicolons, etc.
- **refactor**: Code refactoring
- **test**: Adding tests
- **chore**: Maintenance tasks
### Scopes
- **machine**: `(congenital-optimist)`, `(sleeper-service)`
- **module**: `(desktop)`, `(virtualization)`, `(users)`
- **config**: `(flake)`, `(ci)`
- **docs**: `(readme)`, `(plan)`
### Examples
```bash
feat(desktop): add Cosmic desktop environment module
fix(virtualization): resolve Incus networking issues
docs(readme): update installation instructions
refactor(modules): reorganize desktop environment modules
chore(ci): update GitHub Actions workflow
```
## 🛡️ Branch Protection Rules
### Main Branch Protection
- **Required Reviews**: 1 reviewer minimum
- **Status Checks**: All CI checks must pass
- **Up-to-date**: Branch must be up to date before merging
- **Admin Override**: Allow admin override for hotfixes
- **Force Push**: Disabled
- **Deletion**: Disabled
### Develop Branch Protection
- **Required Reviews**: 1 reviewer (can be self-review)
- **Status Checks**: All CI checks must pass
- **Auto-merge**: Allow auto-merge after checks
- **Force Push**: Disabled for others
## 🔄 Merge Strategies
### Feature to Develop
- **Strategy**: Squash and merge
- **Reason**: Clean history, single commit per feature
- **Title**: Use conventional commit format
### Develop to Main
- **Strategy**: Merge commit
- **Reason**: Preserve feature branch history
- **Testing**: Full integration testing required
### Hotfix to Main
- **Strategy**: Fast-forward if possible
- **Reason**: Immediate deployment needed
- **Testing**: Minimal but critical testing
## 🚀 Deployment Strategy
### Automatic Deployment
- **main** → Production machines (congenital-optimist, sleeper-service)
- **develop** → Test environment (if available)
### Manual Deployment
- Feature branches can be manually deployed for testing
- Use `nixos-rebuild test` for non-persistent testing
- Use `nixos-rebuild switch` for persistent changes
### Rollback Strategy
```bash
# Rollback to previous version
git checkout main
git revert <commit-hash>
git tag rollback-v1.0.0-to-v0.9.9
# Or rollback to specific tag
git checkout v1.0.0
sudo nixos-rebuild switch --flake .#congenital-optimist
```
## 📊 Branch Lifecycle
### Weekly Maintenance
- **Monday**: Review open feature branches
- **Wednesday**: Merge develop to main if stable
- **Friday**: Clean up merged feature branches
- **Sunday**: Update dependencies (automated)
### Monthly Tasks
- Review and update branch protection rules
- Clean up old tags and releases
- Update documentation
- Security audit of configurations
## 🎯 Best Practices
### Branch Naming
- Use descriptive names: `feature/improve-zfs-performance`
- Include issue numbers: `feature/123-add-cosmic-desktop`
- Use lowercase with hyphens
- Keep names under 50 characters
### Commit Messages
- Use imperative mood: "add", "fix", "update"
- Keep first line under 50 characters
- Include body for complex changes
- Reference issues: "Fixes #123"
### Testing Requirements
- Always run `nix flake check` before committing
- Test with `nixos-rebuild test` on relevant machines
- Document testing performed in PR description
- Consider impact on other machines
### Code Review
- Focus on configuration correctness
- Check for security implications
- Verify documentation updates
- Ensure rollback plan exists
- Test locally when possible
---
This branching strategy ensures stable, tested configurations while enabling rapid development and emergency fixes when needed.

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Home Lab Infrastructure
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

254
README.md Normal file
View file

@ -0,0 +1,254 @@
# 🏠 NixOS Home Lab Infrastructure
[![NixOS](https://img.shields.io/badge/NixOS-25.05-blue.svg)](https://nixos.org/)
[![Flakes](https://img.shields.io/badge/Nix-Flakes-green.svg)](https://nixos.wiki/wiki/Flakes)
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
Infrastructure as Code for a multi-machine NixOS home lab environment using flakes and modular configuration.
## 🚀 Quick Start
```bash
# Clone the repository
git clone <repository-url> Home-lab
cd Home-lab
# Check flake configuration
nix flake check
# Build configuration (test)
sudo nixos-rebuild test --flake .#congenital-optimist
# Apply configuration (permanent)
sudo nixos-rebuild switch --flake .#congenital-optimist
```
## 🏗️ Architecture Overview
### Machines
- **`congenital-optimist`** - AMD Threadripper workstation (primary development)
- **`sleeper-service`** - Intel Xeon E3-1230 V2 file server (network storage)
### Technology Stack
- **OS**: NixOS 25.05 (Warbler)
- **Configuration**: Nix Flakes with modular structure
- **Virtualization**: Incus, Libvirt/QEMU, Podman
- **Desktop**: GNOME, Cosmic, Sway
- **Storage**: ZFS with snapshots and NFS
- **Network**: Tailscale mesh networking
## 📁 Repository Structure
```
Home-lab/
├── flake.nix # Main flake configuration
├── flake.lock # Locked dependency versions
├── machines/ # Machine-specific configurations
│ ├── congenital-optimist/ # AMD workstation
│ └── sleeper-service/ # Intel file server
├── modules/ # Reusable NixOS modules
│ ├── common/ # Shared system configuration
│ ├── desktop/ # Desktop environment modules
│ ├── development/ # Development tools and editors
│ ├── hardware/ # Hardware-specific configurations
│ ├── services/ # Service configurations
│ ├── system/ # Core system modules
│ ├── users/ # User configurations
│ └── virtualization/ # Container and VM setup
├── users/ # User-specific configurations
│ └── geir/ # Primary user configuration
│ ├── dotfiles/ # Literate configuration with org-mode
│ └── user.nix # System-level user config
├── overlays/ # Nix package overlays
├── packages/ # Custom package definitions
└── secrets/ # Encrypted secrets (future)
```
## 🔧 Configuration Management
### Modular Design
Each aspect of the system is organized into focused modules:
- **Desktop Environments**: Separate modules for GNOME, Cosmic, and Sway
- **Virtualization**: Independent Incus, Libvirt, and Podman configurations
- **Development**: Modular tool configurations for different workflows
- **Hardware**: Hardware-specific optimizations and drivers
### Literate Programming
User configurations use Emacs org-mode for literate programming:
- Self-documenting configuration files
- Automatic tangling from `.org` to configuration files
- Version-controlled documentation alongside code
## 🚀 Deployment Workflow
### Local Development
```bash
# Check configuration syntax
nix flake check
# Test configuration without switching
sudo nixos-rebuild test --flake .#<machine-name>
# Build configuration
sudo nixos-rebuild build --flake .#<machine-name>
# Apply configuration
sudo nixos-rebuild switch --flake .#<machine-name>
```
### GitOps Workflow
1. **Feature Branch**: Create branch for configuration changes
2. **Local Testing**: Test changes with `nixos-rebuild test`
3. **Pull Request**: Submit PR with configuration validation
4. **Automated Testing**: CI pipeline validates configuration
5. **Review & Merge**: Code review and merge to main
6. **Deployment**: Automated or manual deployment to machines
## 🔐 Security & Secrets
### Current Approach
- No secrets in git repository
- Manual secret management during initial setup
- ZFS encryption for sensitive data
### Planned Improvements
- **agenix** or **sops-nix** for encrypted secrets in git
- **age** keys for secret encryption/decryption
- **CI/CD** integration with secret management
## 🎯 Machine Specifications
### CongenitalOptimist (AMD Workstation)
- **CPU**: AMD Threadripper (details in hardware-configuration.nix)
- **GPU**: AMD (with proper drivers and virtualization passthrough)
- **Storage**: ZFS pools (zpool + stuffpool)
- **Use Case**: Primary development, virtualization, desktop environments
- **Services**: Development tools, desktop environments, VM host
### SleeperService (Intel File Server)
- **CPU**: Intel Xeon E3-1230 V2 @ 3.70GHz (4 cores, 8 threads)
- **Memory**: 16GB RAM
- **Storage**: ZFS with redundancy
- **Use Case**: Network storage, file sharing, backup services
- **Services**: NFS, Samba, automated backups, monitoring
## 🧪 Testing Strategy
### Automated Testing (Planned)
- **Configuration Validation**: `nix flake check` in CI
- **Build Testing**: Test builds for all machines
- **Module Testing**: Individual module validation
- **Integration Testing**: Full system build verification
### Manual Testing Checklist
- [ ] System boots successfully
- [ ] Desktop environments functional
- [ ] Virtualization stack operational
- [ ] Network services accessible
- [ ] User environment complete
- [ ] Development tools working
## 📈 Monitoring & Maintenance
### Health Checks
- System generation switching
- Service status monitoring
- ZFS pool health
- Network connectivity
- Resource utilization
### Backup Strategy
- **ZFS Snapshots**: Automatic filesystem snapshots
- **Configuration Backups**: Git repository with full history
- **Data Backups**: Automated backup services on SleeperService
- **Recovery Procedures**: Documented rollback processes
## 🔄 CI/CD Pipeline (Planned)
### Validation Pipeline
```yaml
# Planned GitHub Actions workflow
- Syntax Check: nix flake check
- Build Test: nix build .#nixosConfigurations.<machine>
- Security Scan: Nix security auditing
- Documentation: Update system documentation
```
### Deployment Pipeline
```yaml
# Planned deployment automation
- Staging: Deploy to test environment
- Integration Tests: Automated system testing
- Production: Deploy to production machines
- Rollback: Automatic rollback on failure
```
## 🤝 Contributing
### Development Workflow
1. Fork/clone repository
2. Create feature branch
3. Make configuration changes
4. Test locally with `nixos-rebuild test`
5. Submit pull request
6. Address review feedback
7. Merge after approval
### Module Development Guidelines
- Keep modules focused and single-purpose
- Document module options and usage
- Test modules independently when possible
- Follow consistent naming conventions
- Include example configurations
## 📖 Documentation
- **[Plan](plan.md)**: Detailed migration and development plan
- **[Instructions](instruction.md)**: Step-by-step setup instructions
- **[Machine Documentation](machines/)**: Per-machine documentation
- **[Module Documentation](modules/)**: Module-specific documentation
- **[User Documentation](users/)**: User configuration documentation
## 🎯 Roadmap
### Phase 1: Flakes Migration ✅
- [x] Convert to flake-based configuration
- [x] Modularize desktop environments
- [x] Add comprehensive virtualization
- [x] Set up GitOps foundation
### Phase 2: Configuration Cleanup
- [ ] Optimize modular structure
- [ ] Enhance documentation
- [ ] Standardize module interfaces
### Phase 3: Multi-Machine Expansion
- [ ] Add SleeperService configuration
- [ ] Implement service modules
- [ ] Set up network storage
### Phase 4: Automation & CI/CD
- [ ] Implement automated testing
- [ ] Set up deployment pipelines
- [ ] Add monitoring and alerting
### Phase 5: Advanced Features
- [ ] Secrets management
- [ ] Advanced monitoring
- [ ] Backup automation
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🙏 Acknowledgments
- **NixOS Community** for excellent documentation and support
- **Culture Ship Names** for inspiring machine nomenclature
- **Emacs Community** for literate programming inspiration
- **Home Lab Community** for sharing knowledge and experience
---
*"The ship had decided to call itself the Arbitrary, presumably for much the same reason."*

44
flake.lock generated Normal file
View file

@ -0,0 +1,44 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1748889542,
"narHash": "sha256-Hb4iMhIbjX45GcrgOp3b8xnyli+ysRPqAgZ/LZgyT5k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "10d7f8d34e5eb9c0f9a0485186c1ca691d2c5922",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1748929857,
"narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable"
}
}
},
"root": "root",
"version": 7
}

121
flake.nix Normal file
View file

@ -0,0 +1,121 @@
{
description = "Home Lab NixOS Configuration - congenital-optimist & sleeper-service";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs, nixpkgs-unstable, ... }@inputs:
let
system = "x86_64-linux";
# Create unstable package set
unstable = import nixpkgs-unstable {
inherit system;
config.allowUnfree = true;
};
# Shared special arguments for all machines
specialArgs = {
inherit inputs unstable;
};
in {
# NixOS system configurations
nixosConfigurations = {
# congenital-optimist - AMD Threadripper workstation
congenital-optimist = nixpkgs.lib.nixosSystem {
inherit system specialArgs;
modules = [
./machines/congenital-optimist/configuration.nix
./machines/congenital-optimist/hardware-configuration.nix
./modules/common/nix.nix
./modules/common/base.nix
./modules/common/tty.nix
];
};
# sleeper-service - Intel Xeon file server
sleeper-service = nixpkgs.lib.nixosSystem {
inherit system specialArgs;
modules = [
./machines/sleeper-service/configuration.nix
./machines/sleeper-service/hardware-configuration.nix
./modules/common/nix.nix
./modules/common/base.nix
./modules/common/tty.nix
];
};
};
# Custom packages for the home lab
packages.${system} = import ./packages {
pkgs = nixpkgs.legacyPackages.${system};
};
# Development shells for different projects
devShells.${system} = {
default = nixpkgs.legacyPackages.${system}.mkShell {
buildInputs = with nixpkgs.legacyPackages.${system}; [
nixd
alejandra
git
emacs
];
shellHook = ''
echo "Home-lab development environment"
echo "Available configurations:"
echo " - congenital-optimist (Threadripper workstation)"
echo " - sleeper-service (Xeon file server)"
echo ""
echo "Build with: nixos-rebuild build --flake .#<config>"
echo "Switch with: nixos-rebuild switch --flake .#<config>"
'';
};
# Dotfiles development shell
dotfiles = nixpkgs.legacyPackages.${system}.mkShell {
buildInputs = with nixpkgs.legacyPackages.${system}; [
emacs
pandoc
starship
];
shellHook = ''
echo "Literate dotfiles development environment"
echo "Tangle dotfiles with: emacs --batch -l org --eval \"(org-babel-tangle-file \\\"README.org\\\")\""
'';
};
};
# Overlays for package customizations
overlays.default = import ./overlays;
# Applications that can be run directly
apps.${system} = {
# Tangle all user dotfiles
tangle-dotfiles = {
type = "app";
program = "${nixpkgs.legacyPackages.${system}.writeShellScript "tangle-dotfiles" ''
cd users/geir/dotfiles
${nixpkgs.legacyPackages.${system}.emacs}/bin/emacs --batch -l org --eval "(org-babel-tangle-file \"README.org\")"
echo "Dotfiles tangled successfully!"
''}";
};
# Check flake configuration
check-config = {
type = "app";
program = "${nixpkgs.legacyPackages.${system}.writeShellScript "check-config" ''
echo "Checking flake configuration..."
nix flake check
echo "Configuration check complete!"
''}";
};
};
# Formatter for Nix files
formatter.${system} = nixpkgs.legacyPackages.${system}.alejandra;
};
}

752
instruction.md Normal file
View file

@ -0,0 +1,752 @@
# AI Agent Instructions: NixOS Flakes Migration for CongenitalOptimist
## Overview
This document provides step-by-step instructions for AI agents to help migrate the CongenitalOptimist machine from traditional NixOS configuration to flakes-based configuration and upgrade to NixOS 25.05. The system already has excellent modular structure that we'll preserve and enhance.
## Current System Information
- **Hostname**: work (consider renaming to congenital-optimist)
- **Current Version**: NixOS 23.11
- **Target Version**: NixOS 25.05
- **Architecture**: x86_64-linux
- **Storage**: ZFS (zpool for system, stuffpool for data)
- **Hardware**: AMD CPU/GPU
- **User**: geir
- **Dotfiles Approach**: Literate programming with Emacs org-mode (no Home Manager)
## Current Module Structure
```
Home-lab/
├── machines/
│ ├── congenital-optimist/
│ │ ├── configuration.nix (main system config)
│ │ ├── hardware-configuration.nix
│ │ └── About.org
│ └── modules/
│ ├── common/
│ │ ├── base.nix (modern CLI tools & aliases)
│ │ └── tty.nix (console styling with Joker theme)
│ └── virtualization/
│ ├── podman.nix
│ ├── libvirt.nix
│ └── incus.nix
└── Users/
└── geir/
└── user.nix (has typo: progtams → programs)
```
## Prerequisites Check
Before starting, verify:
1. Current system is bootable and stable
2. ZFS pools are healthy (`zpool status`)
3. All referenced modules exist and are working
4. User has sudo/root access
5. Fix typo in `Users/geir/user.nix` first
## Step 1: Fix Existing Configuration Issues
### Fix typo in user.nix
Edit `Home-lab/Users/geir/user.nix` and change:
```nix
progtams.zsh.enableCompletion = true;
```
to:
```nix
programs.zsh.enableCompletion = true;
```
## Step 2: Create Root Flake Structure
Create `Home-lab/flake.nix`:
```nix
{
description = "CongenitalOptimist Home Lab NixOS Configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs, nixpkgs-unstable, ... }@inputs: {
nixosConfigurations = {
congenital-optimist = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {
inherit inputs;
unstable = import nixpkgs-unstable {
system = "x86_64-linux";
config.allowUnfree = true;
};
};
modules = [
./machines/congenital-optimist
];
};
};
};
}
```
## Step 3: Create Target Directory Structure
Execute these commands in the Home-lab directory:
```bash
mkdir -p machines/congenital-optimist
mkdir -p modules/{common,desktop,development,virtualization,users}
mkdir -p users/geir/dotfiles/{emacs,shell,editors}
mkdir -p overlays
mkdir -p packages
```
## Step 4: Convert Main Configuration
Create `machines/CongenitalOptimist/default.nix` by adapting the current `configuration.nix`:
Key changes needed:
1. Change function signature from `{pkgs, ...}:` to `{ config, pkgs, inputs, unstable, ... }:`
2. **Keep `system.stateVersion` as "23.11"** (maintains compatibility with existing data)
3. Fix nerd-fonts syntax (changed in 25.05)
4. Remove the experimental-features setting (handled by flake)
5. Update module import paths for new structure
6. Consolidate user package management
### Nerd Fonts Fix for 25.05
Replace this section in fonts.packages:
```nix
# Old format (will break in 25.05)
nerd-fonts.meslo-lg
nerd-fonts.jetbrains-mono
nerd-fonts.fira-code
nerd-fonts.droid-sans-mono
nerd-fonts.zed-mono
nerd-fonts.iosevka
nerd-fonts.iosevka-term
nerd-fonts.hack
```
With:
```nix
# New format for 25.05
(nerdfonts.override {
fonts = [
"Meslo"
"JetBrainsMono"
"FiraCode"
"DroidSansMono"
"Hack"
"Iosevka"
"IosevkaTerm"
];
})
```
## Step 5: Migrate Existing Modules
### Copy existing modules to new structure:
```bash
# Copy common modules
cp Home-lab/Machines/Modules/common/base.nix modules/common/
cp Home-lab/Machines/Modules/common/tty.nix modules/common/
# Copy virtualization modules
cp Home-lab/Machines/Modules/virtualization/*.nix modules/virtualization/
```
### Create additional common modules:
#### `modules/common/nix.nix`:
```nix
{ config, pkgs, ... }: {
# Enable flakes system-wide
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Optimize nix settings
nix.settings = {
auto-optimise-store = true;
substituters = [
"https://cache.nixos.org/"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
];
};
}
```
## Step 6: Consolidate User Configuration
Create `modules/users/geir.nix` by merging the existing user config:
```nix
{ config, pkgs, ... }: {
users.users.geir = {
isNormalUser = true;
extraGroups = [ "networkmanager" "wheel" "libvirtd" "podman" "incus-admin" ];
shell = pkgs.zsh;
packages = with pkgs; [
# Browsers
chromium
vivaldi
vivaldi-ffmpeg-codecs
nyxt
firefox
# Shell & development tools
starship
fastfetch
hyfetch
nerdfetch
nix-direnv
gh
github-copilot-cli
# Media & graphics
gimp
obs-studio
vesktop
koodo-reader
# System tools
ncpamixer
virt-manager
pavucontrol
gnome-tweaks
beauty-line-icon-theme
# Terminal multiplexer and fun
zellij
neo-cowsay
fortune
clolcat
# Emacs integration
emacsPackages.vterm
];
};
# System-wide ZSH configuration
programs.zsh = {
enable = true;
syntaxHighlighting.enable = true;
enableCompletion = true;
autosuggestions = {
enable = true;
historySearch = true;
};
history = {
enable = true;
shareHistory = true;
saveOnExit = true;
};
};
environment.systemPackages = with pkgs; [
zsh
zsh-completions
nix-zsh-completions
zsh-autocomplete
zsh-autosuggestions
zsh-syntax-highlighting
];
}
```
## Step 7: Create Desktop Environment Modules
### `modules/desktop/gnome.nix`:
```nix
{ config, pkgs, ... }: {
services.xserver = {
enable = true;
desktopManager.gnome.enable = true;
xkb.layout = "no";
};
# XDG portal configuration
xdg.portal = {
enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
}
```
### `modules/desktop/cosmic.nix`:
```nix
{ config, pkgs, ... }: {
services.desktopManager.cosmic.enable = true;
services.displayManager.cosmic-greeter.enable = true;
services.desktopManager.cosmic.xwayland.enable = true;
}
```
### `modules/desktop/sway.nix`:
```nix
{ config, pkgs, ... }: {
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
};
services.dbus.enable = true;
xdg.portal = {
enable = true;
wlr.enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
environment.systemPackages = with pkgs; [
swaylock
swayidle
swaybg
waybar
fuzzel
gammastep
mako
flameshot
];
}
```
## Step 8: Set Up Per-User Literate Dotfiles
Create `users/geir/dotfiles/README.org`:
```org
#+TITLE: CongenitalOptimist Dotfiles Configuration
#+DESCRIPTION: Literate programming approach to dotfiles using Emacs org-mode
#+PROPERTY: header-args :tangle yes
#+STARTUP: overview
* Introduction
This file contains all dotfiles configuration using literate programming.
Each configuration block can be tangled to its respective file using C-c C-v t.
The approach allows for:
- Self-documenting configuration with rationale
- Easy sharing and explanation of setup decisions
- Version control of configuration with full context
- Modular organization of different tool configurations
* Shell Configuration
** Zsh Configuration
#+BEGIN_SRC sh :tangle ~/.zshrc
# Generated from dotfiles/README.org - CongenitalOptimist configuration
export EDITOR="emacs"
export BROWSER="firefox"
export SHELL="/run/current-system/sw/bin/zsh"
# Enable starship prompt (configured in NixOS)
eval "$(starship init zsh)"
# Enable zoxide for smart cd
eval "$(zoxide init zsh)"
# Custom aliases (complementing those in base.nix)
alias gc='git commit'
alias gp='git push'
alias gs='git status'
alias nrs='sudo nixos-rebuild switch --flake .'
alias nrt='sudo nixos-rebuild test --flake .'
alias reload='source ~/.zshrc'
# CongenitalOptimist specific shortcuts
alias lab='cd ~/Home-lab'
alias tangle='cd ~/Home-lab/users/geir/dotfiles && emacs --batch -l org --eval "(org-babel-tangle-file \"README.org\")"'
alias dotfiles='cd ~/Home-lab/users/geir/dotfiles'
#+END_SRC
** Starship Configuration
#+BEGIN_SRC toml :tangle ~/.config/starship.toml
# Starship prompt configuration for CongenitalOptimist
format = """
$username\
$hostname\
$directory\
$git_branch\
$git_state\
$git_status\
$cmd_duration\
$line_break\
$character"""
[character]
success_symbol = "[](bold green)"
error_symbol = "[](bold red)"
[directory]
truncation_length = 3
fish_style_pwd_dir_length = 1
[git_branch]
symbol = "🌱 "
[hostname]
ssh_only = false
format = "[@$hostname](bold blue) "
[username]
show_always = true
format = "[$user](bold yellow)"
#+END_SRC
* Editor Configuration
** Emacs Configuration
#+BEGIN_SRC emacs-lisp :tangle ~/.emacs.d/init.el
;; Generated from dotfiles/README.org - CongenitalOptimist
(setq inhibit-startup-message t)
(setq ring-bell-function 'ignore)
;; Enable line numbers
(global-display-line-numbers-mode 1)
;; Enable org-babel for literate programming
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(python . t)
(nix . t)))
;; Auto-tangle on save for literate config files
(defun auto-tangle-config-files ()
"Auto tangle config files when saving."
(when (string-match-p "users/.*/dotfiles.*\\.org$" (buffer-file-name))
(org-babel-tangle)))
(add-hook 'after-save-hook 'auto-tangle-config-files)
;; Better defaults
(setq-default indent-tabs-mode nil)
(setq-default tab-width 2)
(show-paren-mode 1)
(electric-pair-mode 1)
;; CongenitalOptimist theme setup
(when (display-graphic-p)
(load-theme 'deeper-blue t))
#+END_SRC
* Development Tools
** Git Configuration
#+BEGIN_SRC conf :tangle ~/.gitconfig
[user]
name = geir
email = geir@congenital-optimist.local
[init]
defaultBranch = main
[core]
editor = emacs
pager = bat
[pull]
rebase = false
[alias]
st = status
co = checkout
br = branch
unstage = reset HEAD --
last = log -1 HEAD
visual = !gitk
#+END_SRC
* Home Lab Specific Configuration
** NixOS Rebuild Aliases
These aliases make working with the flake-based configuration easier:
#+BEGIN_SRC sh :tangle ~/.config/shell/nixos-aliases
# NixOS CongenitalOptimist specific aliases
alias nix-build='cd ~/Home-lab && nix build .#nixosConfigurations.congenital-optimist.config.system.build.toplevel'
alias nix-check='cd ~/Home-lab && nix flake check'
alias nix-update='cd ~/Home-lab && nix flake update'
alias nix-clean='sudo nix-collect-garbage -d'
alias edit-dotfiles='cd ~/Home-lab/users/geir/dotfiles && emacs README.org'
#+END_SRC
```
## Step 9: Update Main Configuration Import Structure
Create the main machine configuration in `machines/CongenitalOptimist/default.nix`:
```nix
{ config, pkgs, inputs, unstable, ... }: {
imports = [
./hardware-configuration.nix
../../modules/common/base.nix
../../modules/common/tty.nix
../../modules/common/nix.nix
../../modules/virtualization/podman.nix
../../modules/virtualization/libvirt.nix
../../modules/virtualization/incus.nix
../../modules/desktop/gnome.nix
../../modules/desktop/cosmic.nix
../../modules/desktop/sway.nix
../../modules/users/geir.nix
];
# Boot configuration
boot.loader.grub = {
enable = true;
zfsSupport = true;
efiSupport = true;
efiInstallAsRemovable = true;
mirroredBoots = [
{
devices = ["nodev"];
path = "/boot";
}
];
};
zramSwap = {
enable = true;
algorithm = "zstd";
};
# Hardware
services.fwupd.enable = true;
hardware.enableRedistributableFirmware = true;
hardware.amdgpu.initrd.enable = true;
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
# System settings
nixpkgs.config.allowUnfree = true;
networking.nftables.enable = true;
networking.hostName = "work"; # TODO: consider changing to "congenital-optimist"
services.tailscale.enable = true;
networking.networkmanager.enable = true;
networking.hostId = "8425e349";
time.timeZone = "Europe/Oslo";
i18n.defaultLocale = "en_US.UTF-8";
# Services
services.flatpak.enable = true;
services.emacs.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
pulse.enable = true;
};
programs.steam.enable = true;
# Fonts (updated for 25.05)
fonts.packages = with pkgs; [
noto-fonts
noto-fonts-cjk-sans
noto-fonts-emoji
liberation_ttf
dina-font
proggyfonts
mona-sans
hubot-sans
inter-nerdfont
(nerdfonts.override {
fonts = [
"Meslo"
"JetBrainsMono"
"FiraCode"
"DroidSansMono"
"Hack"
"Iosevka"
"IosevkaTerm"
];
})
];
# System packages
environment.systemPackages = with pkgs; [
# Terminal applications
kitty
terminator
rio
dbus
greetd.tuigreet
wayland
xdg-utils
# System monitoring
glances
inxi
htop
bottom
wget
curl
git
mc
systemctl-tui
# Development tools
guile
rustup
nixd
zls
alejandra
python3Packages.python-lsp-server
gopls
luajitPackages.lua-lsp
nodePackages.bash-language-server
vimPlugins.cmp-nvim-lsp
ccls
gdb
marksman
# Editors
zed-editor
neovim
emacs
vscode
vscodium-fhs
];
# Network and security
services.openssh.enable = true;
services.zfs.autoScrub.enable = true;
services.zfs.trim.enable = true;
networking.firewall.allowedTCPPorts = [ 22 ];
networking.firewall.allowedUDPPorts = [ 22 ];
networking.firewall.enable = true;
system.copySystemConfiguration = true;
system.stateVersion = "23.11"; # DO NOT CHANGE - maintains data compatibility
}
```
## Step 10: Copy Hardware Configuration
Copy the existing hardware configuration:
```bash
cp Home-lab/Machines/CongenitalOptimist/hardware-configuration.nix machines/CongenitalOptimist/
```
## Step 11: Test Configuration
Before applying changes:
1. Test flake evaluation:
```bash
cd Home-lab
nix flake check
```
2. Build configuration without switching:
```bash
sudo nixos-rebuild build --flake .#congenital-optimist
```
3. If successful, test the configuration:
```bash
sudo nixos-rebuild test --flake .#congenital-optimist
```
4. If everything works, switch permanently:
```bash
sudo nixos-rebuild switch --flake .#congenital-optimist
```
## Step 12: Set Up Per-User Literate Dotfiles Workflow
1. Create your main org-mode configuration file:
```bash
cd users/geir/dotfiles
emacs README.org
```
2. Use org-babel to tangle your configurations:
```bash
# In Emacs, use C-c C-v t to tangle all code blocks
# Or from command line:
cd users/geir/dotfiles
emacs --batch -l org --eval "(org-babel-tangle-file \"README.org\")"
```
3. The provided Emacs config includes auto-tangle on save for any user's dotfiles
4. Test that dotfiles are generated correctly in the user's home directory
5. For additional users, create similar structure under `users/<username>/dotfiles/`
## Step 13: Lock and Commit
1. Generate flake.lock:
```bash
nix flake lock
```
2. Commit changes:
```bash
git add .
git commit -m "Migrate CongenitalOptimist to flakes with literate dotfiles"
```
## Verification Steps
After switching:
1. Verify system boots correctly
2. Check all services are running: `systemctl --failed`
3. Test all desktop environments launch (GNOME, Cosmic, Sway)
4. Verify virtualization: `sudo systemctl status libvirtd podman`
5. Check ZFS status: `zpool status`
6. Test network connectivity and Tailscale
7. Verify user environment and all packages available
8. Test modern CLI tools and aliases from base.nix
9. Check console theming and TTY configuration
10. Verify Emacs and literate programming workflow
## Error Resolution
### Common Issues:
1. **Boot failure**: Boot from previous generation in GRUB
2. **Package not found**: Check if package name changed in 25.05
3. **Service fails**: Check journalctl: `journalctl -u <service-name>`
4. **Desktop environment issues**: Switch to TTY (Ctrl+Alt+F2) and debug
5. **Nerd fonts issues**: Verify the new syntax is applied correctly
### Emergency Recovery:
- Boot from previous NixOS generation in GRUB
- Use ZFS snapshots if available: `zfs rollback zpool/root@snapshot-name`
- Keep live USB available for emergency repairs
## Final Validation Checklist
- [ ] System boots to desktop
- [ ] All user applications launch (browsers, editors, terminals)
- [ ] Network and Tailscale functional
- [ ] Virtualization stack operational (podman, libvirt, incus)
- [ ] ZFS and NFS mounts working
- [ ] Development tools functional (editors, LSPs, languages)
- [ ] Audio system working (pipewire)
- [ ] Modern CLI tools and aliases from base.nix working
- [ ] Console theming with Joker palette preserved
- [ ] Bluetooth functional if needed
- [ ] Literate dotfiles workflow established
- [ ] Auto-tangling in Emacs working
## Post-Migration Tasks
1. Consider updating hostname from "work" to "congenital-optimist"
2. Expand literate dotfiles in org-mode with more tools and configurations
3. Create additional machine configurations in the flake
4. Implement secrets management (agenix/sops-nix)
5. Set up automatic updates
6. Add system monitoring
8. Document your literate programming workflow per user
9. Consider using org-mode for documenting the entire home lab setup
10. Set up org-export to generate beautiful documentation from your configs
11. Create templates for common user configuration patterns
12. Plan for additional users with their own dotfiles directories
13. Consider shared vs user-specific configuration strategies
## Notes for AI Agents
1. Always preserve existing functionality - don't remove working features
2. The system already has excellent modular structure - build on it
3. Modern CLI tools are already configured in base.nix - don't duplicate
4. Console theming is already set up - preserve the Joker palette
5. Fix the typo in user.nix before proceeding
6. Keep system.stateVersion as "23.11" - never change this
7. Test thoroughly before committing to permanent changes
8. Prioritize system stability over new features
9. The literate programming approach should complement, not replace, the modular NixOS structure

View file

@ -0,0 +1,103 @@
#+TITLE: CongenitalOptimist Workstation
#+DESCRIPTION: AMD Threadripper 1920X based development workstation for Home-lab
#+AUTHOR: geir
#+DATE: 2024
* CongenitalOptimist: A GSV, for a machine you hope will always perform well.
** Hardware Specifications
- *CPU*: AMD Ryzen Threadripper 1920X @ 3.50GHz (12 cores, 24 threads)
- *GPU*: AMD Radeon RX Vega [Discrete]
- *RAM*: 64GB DDR4 (currently 28.85 GiB used / 62.68 GiB total)
- *Architecture*: x86_64
- *Platform*: AMD TR4 Socket
- *Form Factor*: High-End Desktop (HEDT)
** Role & Purpose
CongenitalOptimist serves as the primary development workstation and creative powerhouse for the Home-lab infrastructure. True to its Culture name, it approaches every computational challenge with unwavering optimism and substantial processing capability.
*** Primary Functions
- Software development and compilation
- Virtual machine hosting and testing
- Container orchestration and development
- Creative workloads (video editing, 3D rendering)
- Multi-desktop environment testing
*** Secondary Functions
- Network storage client (NFS from SleeperService)
- Build server for NixOS configurations
- Media consumption and streaming
- Gaming and entertainment
- System administration hub
** Software Configuration
- *OS*: NixOS 25.05
- *Hostname*: congenital-optimist
- *Desktop Environments*: GNOME, Cosmic, Sway
- *Shell*: Zsh with modern CLI tools
- *Editor Stack*: Emacs, Neovim, VSCode, Zed
- *Containerization*: Podman, Incus
- *Virtualization*: libvirt/KVM with virt-manager
** Network Configuration
- *Tailscale*: Enabled for secure remote access
- *NFS Client*: Mounts from SleeperService file server
- *SSH*: Enabled for remote development
- *Firewall*: NFTables with restrictive default rules
- *DNS*: Systemd-resolved with custom entries
** Storage Architecture
- *Root Filesystem*: ZFS (zpool/root)
- *Nix Store*: ZFS (zpool/nix)
- *User Data*: ZFS (zpool/home)
- *Variable Data*: ZFS (zpool/var)
- *Games*: ZFS (stuffpool/games)
- *VMs*: ZFS (stuffpool/virtual)
- *Network Storage*: NFS mount from SleeperService
** Development Environment
CongenitalOptimist embodies the Culture's optimistic approach to problem-solving. With 24 threads of Threadripper processing power and abundant memory, it tackles complex development tasks with confidence and capability.
*** Configured Development Tools
- Multiple language runtimes (Rust, Python, Go, Guile)
- Language servers for intelligent code completion
- Container development with Podman
- VM development with libvirt
- Git workflow with GitHub CLI integration
- AI-assisted development with GitHub Copilot
*** Desktop Experience
- GNOME: Full-featured desktop for productivity
- Cosmic: Modern System76 desktop experience
- Sway: Tiling window manager for focused development
- Consistent theming and font configuration
- Modern CLI tools (eza, bat, ripgrep, starship)
** Culture Context
Like its namesake GSV, CongenitalOptimist believes that with sufficient processing power and well-designed software, any problem can be solved. It maintains an optimistic outlook even during intensive compilation tasks or complex virtualization scenarios.
The Threadripper architecture mirrors the Culture's philosophy of abundant resources applied intelligently - why have 4 cores when you can have 24? Why settle for basic graphics when you can have Vega-class rendering?
** Operational Philosophy
- *Performance*: Leverage all 24 threads for parallel workloads
- *Reliability*: ZFS ensures data integrity and snapshot capabilities
- *Flexibility*: Multiple desktop environments for different tasks
- *Integration*: Seamless interaction with SleeperService file server
- *Optimization*: NixOS configuration management for reproducible setups
** Power Profile
- High-performance desktop configuration
- Always-on development environment
- Efficient resource utilization across cores
- Temperature monitoring for sustained workloads
- Balanced performance and power consumption
** Future Expansion
- Additional memory for larger virtual machine workloads
- NVMe storage expansion for local high-speed storage
- GPU compute acceleration for AI/ML workloads
- Network upgrade for faster SleeperService connectivity
- Multi-monitor setup expansion
* "The ship had been constructed to be a tool, to do a job of work; and the fact that it had been invested with intelligence had not changed the essence of what it was."
*- Iain M. Banks, describing the optimistic spirit that drives CongenitalOptimist*

View file

@ -0,0 +1,54 @@
{
config,
pkgs,
inputs,
unstable,
...
}: {
imports = [
./hardware-configuration.nix
# System modules
../../modules/system/fonts.nix
../../modules/system/network.nix
../../modules/system/applications.nix
# Hardware modules
../../modules/hardware/amd-workstation.nix
# Desktop environments
../../modules/desktop/common.nix
../../modules/desktop/gnome.nix
../../modules/desktop/cosmic.nix
../../modules/desktop/sway.nix
# Development tools
../../modules/development/tools.nix
# User configuration
../../modules/users/geir.nix
# Virtualization configuration
../../modules/virtualization/incus.nix
../../modules/virtualization/libvirt.nix
../../modules/virtualization/podman.nix
];
# Boot configuration
boot.loader.grub = {
enable = true;
zfsSupport = true;
efiSupport = true;
efiInstallAsRemovable = true;
mirroredBoots = [
{
devices = ["nodev"];
path = "/boot";
}
];
};
# Basic system configuration
nixpkgs.config.allowUnfree = true;
system.stateVersion = "23.11"; # DO NOT CHANGE - maintains data compatibility
}

View file

@ -0,0 +1,68 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "zpool/root";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "zpool/nix";
fsType = "zfs";
};
fileSystems."/var" =
{ device = "zpool/var";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "zpool/home";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/257B-AB7E";
fsType = "vfat";
};
fileSystems."/home/geir/games" =
{ device = "stuffpool/games";
fsType = "zfs";
};
fileSystems."/home/geir/virtual" =
{ device = "stuffpool/virtual";
fsType = "zfs";
};
fileSystems."/mnt/storage/media" =
{ device = "files:/mnt/storage";
fsType = "nfs";
options = [ "x-systemd.automount" "noauto" "x-systemd.idle-timeout=600" ];
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp5s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,57 @@
#+TITLE: SleeperService File Server
#+DESCRIPTION: Intel Xeon E3-1230 V2 based file server for Home-lab network storage
#+AUTHOR: geir
#+DATE: 2025
* SleeperService: A massive GSV with a reputation for taking on unusual tasks.
** Hardware Specifications
- *CPU*: Intel Xeon E3-1230 V2 @ 3.70GHz (4 cores, 8 threads)
- *RAM*: 16GB DDR3
- *Architecture*: x86_64
- *Form Factor*: Server/Tower
- *Age*: Legacy hardware, proven reliability
** Role & Purpose
SleeperService serves as the primary network storage and file server for the Home-lab infrastructure. True to its Culture name, it quietly handles the essential but unglamorous tasks that keep the network running smoothly.
*** Primary Functions
- Network File System (NFS) server
- Centralized backup repository
- System monitoring and alerting hub
- Data redundancy and integrity management
*** Secondary Functions
- Log aggregation and analysis
- Network service monitoring
- Automated backup orchestration
** Network Configuration
- *Hostname*: sleeper-service
- *Domain*: home-lab.local
- *Tailscale*: Enabled for secure remote access
- *SSH*: Primary access method (headless operation)
- *Firewall*: Restrictive, service-specific ports only
** Storage Philosophy
SleeperService embodies the Culture principle of quiet competence. It doesn't need the latest hardware to excel at its mission - reliable, continuous service. The Xeon architecture provides ECC memory support and enterprise-grade reliability perfect for 24/7 file serving operations.
** Culture Context
Like its namesake GSV, SleeperService takes on the "unusual tasks" that other machines might find mundane. It's the dependable workhorse that ensures data is always available, backups are current, and the network storage needs of CongenitalOptimist and future machines are met without fanfare.
** Operational Notes
- Headless operation - no GUI required
- Designed for continuous uptime
- Energy efficient for 24/7 operation
- Minimal resource requirements for maximum stability
- Perfect for background services and automation
** Future Expansion
- Additional storage capacity as needed
- Container services for lightweight applications
- Monitoring dashboard hosting
- Potential media streaming services
- Network infrastructure services (DNS, DHCP)
* "The ship had been constructed over a hundred years before, and was generally reckoned to be slightly eccentric."
*- Iain M. Banks, describing vessels much like SleeperService*

View file

@ -0,0 +1,73 @@
{ config, pkgs, inputs, unstable, ... }: {
imports = [
./hardware-configuration.nix
];
# Boot configuration
boot.loader.grub = {
enable = true;
efiSupport = true;
efiInstallAsRemovable = true;
devices = [ "nodev" ];
};
# Network configuration
networking.hostName = "sleeper-service";
networking.networkmanager.enable = true;
services.tailscale.enable = true;
networking.firewall.enable = true;
# Time and locale
time.timeZone = "Europe/Oslo";
i18n.defaultLocale = "en_US.UTF-8";
# Console configuration
console = {
font = "Lat2-Terminus16";
keyMap = "no";
};
# Enable unfree packages
nixpkgs.config.allowUnfree = true;
# SSH access (headless server)
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
};
# Basic system packages
environment.systemPackages = with pkgs; [
wget
curl
git
htop
eza
bat
ripgrep
du-dust
fd
ncdu
tree
];
# Users
users.users.geir = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" ];
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [
# Add SSH public keys here
];
};
programs.zsh.enable = true;
# Firewall configuration
networking.firewall.allowedTCPPorts = [ 22 ];
system.stateVersion = "25.05";
}

View file

@ -0,0 +1,37 @@
# Do not modify this file! It was generated by 'nixos-generate-config'
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/12345678-1234-1234-1234-123456789abc";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/ABCD-1234";
fsType = "vfat";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp0s25.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,20 @@
{ config, pkgs, ... }:
{
services.transmission = {
enable = true;
user = "geir";
group = "users";
#home = "/mnt/storage/";
settings.rpc-port = 9091;
settings.rpc-bind-address = "0.0.0.0";
#openRPCPort = true;
downloadDirPermissions = "770";
settings = {
download-dir = "/mnt/storage";
#rpc-whitelist-enabled = true;
rpc-whitelist = "127.0.0.1,10.0.0.*,100.*.*.*";
rpc-host-whitelist = "idea,files,nixos-work,server1";
};
};
}

85
modules/README.md Normal file
View file

@ -0,0 +1,85 @@
# NixOS Modules Directory Structure
This directory contains reusable NixOS modules organized by functional domain for the Home-lab infrastructure.
## Directory Organization
### `common/`
Core modules shared across all machines in the home lab:
- `base.nix` - Modern CLI tools, aliases, and essential packages
- `tty.nix` - Console configuration and theming
- `nix.nix` - Nix/flakes configuration and optimization settings
- `ssh.nix` - SSH server and security configurations
- `networking.nix` - Basic networking and firewall settings
### `desktop/`
Desktop environment configurations for workstation machines:
- `gnome.nix` - GNOME desktop environment setup
- `cosmic.nix` - System76 COSMIC desktop configuration
- `sway.nix` - Sway window manager and Wayland setup
- `fonts.nix` - Font packages and configurations
- `audio.nix` - PipeWire/audio system setup
### `development/`
Development tools and environments:
- `editors.nix` - Text editors (Emacs, Neovim, VSCode)
- `languages.nix` - Programming languages and runtimes
- `tools.nix` - Development utilities and CLI tools
- `containers.nix` - Development container tools
- `git.nix` - Git configuration and tools
### `virtualization/`
Virtualization and containerization:
- `podman.nix` - Podman container runtime
- `libvirt.nix` - KVM/QEMU virtualization
- `incus.nix` - System container management
- `docker.nix` - Docker runtime (if needed)
### `services/`
Network services primarily for SleeperService file server:
- `nfs.nix` - Network File System server
- `samba.nix` - SMB/CIFS file sharing
- `backup.nix` - Automated backup services
- `monitoring.nix` - System monitoring and alerting
- `storage.nix` - ZFS and storage management
- `media.nix` - Media server services (Jellyfin/Plex)
### `users/`
User management and shared user configurations:
- `common.nix` - Shared user settings across machines
- `groups.nix` - System groups and permissions
- `security.nix` - User security policies
## Usage
Modules are imported in machine configurations like:
```nix
imports = [
../../modules/common/base.nix
../../modules/desktop/gnome.nix
../../modules/virtualization/podman.nix
];
```
## Design Philosophy
- **Modular**: Each module has a single, clear responsibility
- **Reusable**: Modules work across different machine types
- **Composable**: Mix and match modules for different machine roles
- **Documented**: Each module includes usage examples and options
- **Testable**: Modules can be tested independently
## Machine Profiles
### CongenitalOptimist (Workstation)
- All desktop modules
- Development tools
- Virtualization stack
- User-focused configurations
### sleeper-service (File Server)
- Common base only
- Service modules (NFS, Samba, backup)
- No desktop environment
- Server-focused configurations

27
modules/common/base.nix Normal file
View file

@ -0,0 +1,27 @@
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
tldr
eza
bat
ripgrep
du-dust
bottom
fd
fzf
zoxide
uutils-coreutils-noprefix
];
environment.shellAliases = {
vi = "nvim";
vim = "nvim";
h = "tldr";
# oxidized
ls = "eza -l";
cat = "bat";
grep = "rg";
top = "btm";
du = "dust";
find = "fd";
};
}

36
modules/common/nix.nix Normal file
View file

@ -0,0 +1,36 @@
{ config, lib, pkgs, ... }:
{
# Enable flakes and other experimental features
nix = {
settings = {
experimental-features = [ "nix-command" "flakes" ];
auto-optimise-store = true;
trusted-users = [ "root" "@wheel" ];
substituters = [
"https://cache.nixos.org/"
"https://nix-community.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
# Enable garbage collection
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
# Optimize store weekly
optimise = {
automatic = true;
dates = [ "03:45" ];
};
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
}

29
modules/common/tty.nix Normal file
View file

@ -0,0 +1,29 @@
{ pkgs, ... }:
{
services.getty.greetingLine = ''\l'';
console = {
earlySetup = true;
# Joker palette
colors = [
"1b161f"
"ff5555"
"54c6b5"
"d5aa2a"
"bd93f9"
"ff79c6"
"8be9fd"
"bfbfbf"
"1b161f"
"ff6e67"
"5af78e"
"ffce50"
"caa9fa"
"ff92d0"
"9aedfe"
"e6e6e6"
];
};
}

View file

@ -0,0 +1,29 @@
{ config, pkgs, ... }: {
# Common desktop configuration shared across all environments
# XDG Portal configuration for Wayland/X11 compatibility
xdg.portal = {
enable = true;
wlr.enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
# Display manager and session management
services.dbus.enable = true;
# Common desktop packages
environment.systemPackages = with pkgs; [
# Basic desktop tools
firefox
alacritty
nautilus
# Media and graphics
vlc
gimp
# Utilities
gnome-tweaks
dconf-editor
];
}

View file

@ -0,0 +1,11 @@
{ config, pkgs, ... }: {
# Cosmic Desktop Environment (System76's new Rust-based DE)
services.desktopManager.cosmic.enable = true;
services.displayManager.cosmic-greeter.enable = true;
services.desktopManager.cosmic.xwayland.enable = true;
# Cosmic-specific packages
environment.systemPackages = with pkgs; [
# Cosmic is still in development, most packages come with the DE
];
}

22
modules/desktop/gnome.nix Normal file
View file

@ -0,0 +1,22 @@
{ config, pkgs, ... }: {
# GNOME Desktop Environment
services.xserver = {
enable = true;
desktopManager.gnome.enable = true;
xkb.layout = "no";
};
# GNOME-specific packages
environment.systemPackages = with pkgs; [
gnome-extension-manager
gnome-shell-extensions
dconf-editor
gnome-tweaks
];
# GNOME services
services.gnome = {
gnome-keyring.enable = true;
glib-networking.enable = true;
};
}

28
modules/desktop/sway.nix Normal file
View file

@ -0,0 +1,28 @@
{ config, pkgs, ... }: {
# Sway Window Manager (Wayland-based i3 replacement)
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
};
# Sway-specific packages
environment.systemPackages = with pkgs; [
# Core Sway tools
swaylock
swayidle
swaybg
# Wayland utilities
waybar # Status bar
fuzzel # Application launcher
gammastep # Blue light filter
mako # Notification daemon
flameshot # Screenshot tool
wl-clipboard # Clipboard utilities
# Additional Wayland tools
grim # Screenshot utility
slurp # Screen area selection
wf-recorder # Screen recorder
];
}

View file

@ -0,0 +1,40 @@
{ config, pkgs, ... }: {
# Development editors and tools
environment.systemPackages = with pkgs; [
# Editors
zed-editor
neovim
emacs
vscode
vscodium-fhs
# Language servers
nixd
zls
alejandra
python3Packages.python-lsp-server
gopls
luajitPackages.lua-lsp
nodePackages.bash-language-server
vimPlugins.cmp-nvim-lsp
ccls
marksman
# Programming languages and tools
guile
rustup
gdb
# Development utilities
git
nix-direnv
gh
github-copilot-cli
];
# System-wide Emacs daemon
services.emacs.enable = true;
# Enable ZSH system-wide for development
programs.zsh.enable = true;
}

View file

@ -0,0 +1,30 @@
{ config, pkgs, ... }: {
# AMD GPU configuration
hardware.amdgpu.initrd.enable = true;
# Firmware updates and proprietary firmware
services.fwupd.enable = true;
hardware.enableRedistributableFirmware = true;
# Bluetooth configuration
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
# ZRAM swap configuration
zramSwap = {
enable = true;
algorithm = "zstd";
};
# Audio system (PipeWire)
services.pipewire = {
enable = true;
alsa.enable = true;
pulse.enable = true;
};
# Gaming support
programs.steam.enable = true;
}

View file

@ -0,0 +1,30 @@
{ config, pkgs, ... }: {
# System applications and utilities
environment.systemPackages = with pkgs; [
# Terminal applications
kitty
terminator
rio
greetd.tuigreet
# System monitoring
glances
inxi
htop
bottom
systemctl-tui
# File and data tools
wget
curl
mc
# Desktop integration
dbus
wayland
xdg-utils
];
# Flatpak support
services.flatpak.enable = true;
}

36
modules/system/fonts.nix Normal file
View file

@ -0,0 +1,36 @@
{ config, pkgs, ... }: {
# Font configuration
fonts.packages = with pkgs; [
# Base fonts
noto-fonts
noto-fonts-cjk-sans
noto-fonts-emoji
liberation_ttf
dina-font
proggyfonts
# GitHub fonts
mona-sans
hubot-sans
inter-nerdfont
# Nerd Fonts (updated syntax for NixOS 25.05)
nerd-fonts.meslo-lg
nerd-fonts.jetbrains-mono
nerd-fonts.fira-code
nerd-fonts.droid-sans-mono
nerd-fonts.hack
nerd-fonts.iosevka
nerd-fonts.iosevka-term
];
# Console configuration
console = {
font = "Lat2-Terminus16";
keyMap = "no";
};
# Internationalization
i18n.defaultLocale = "en_US.UTF-8";
time.timeZone = "Europe/Oslo";
}

View file

@ -0,0 +1,26 @@
{ config, pkgs, ... }: {
# Network configuration
networking = {
hostName = "congenital-optimist";
hostId = "8425e349";
networkmanager.enable = true;
nftables.enable = true;
# Firewall configuration
firewall = {
enable = true;
allowedTCPPorts = [ 22 ];
allowedUDPPorts = [ 22 ];
};
};
# VPN and remote access
services.tailscale.enable = true;
services.openssh.enable = true;
# ZFS services
services.zfs = {
autoScrub.enable = true;
trim.enable = true;
};
}

44
modules/users/geir.nix Normal file
View file

@ -0,0 +1,44 @@
{ config, pkgs, ... }: {
# User configuration for geir
users.users.geir = {
isNormalUser = true;
extraGroups = [ "networkmanager" "wheel" "libvirt" "incus-admin" "podman" ];
shell = pkgs.zsh;
packages = with pkgs; [
# Browsers
chromium
vivaldi
vivaldi-ffmpeg-codecs
nyxt
firefox
# Terminal and shell tools
starship
fastfetch
hyfetch
nerdfetch
zellij
neo-cowsay
fortune
clolcat
# Audio and system control
ncpamixer
pavucontrol
# Desktop applications
gimp
obs-studio
vesktop
koodo-reader
# System management
virt-manager
gnome-tweaks
beauty-line-icon-theme
# Emacs integration
emacsPackages.vterm
];
};
}

View file

@ -0,0 +1,19 @@
{ config, pkgs, ... }:
{
virtualisation.incus = {
enable = true;
ui.enable = true;
package = pkgs.incus;
};
environment.systemPackages = with pkgs; [
incus
lxc
];
users.users.geir = {
extraGroups = [
"incus-admin"
];
};
networking.firewall.allowedTCPPorts = [ 8443 ];
}

View file

@ -0,0 +1,21 @@
{ config, pkgs, ... }: {
virtualisation.libvirtd = {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
runAsRoot = true;
swtpm.enable = true;
ovmf = {
enable = true;
packages = [ pkgs.OVMFFull.fd ];
};
};
};
environment.systemPackages = with pkgs; [
qemu_kvm
libvirt
virt-manager
virt-viewer
];
}

View file

@ -0,0 +1,18 @@
{ pkgs, ... }: {
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
defaultNetwork.settings.dns_enabled = true;
};
environment.systemPackages = with pkgs; [
podman-tui
podman-compose
buildah
skopeo
];
# Enable container runtime for desktop integration
virtualisation.containers.enable = true;
}

101
names.md Normal file
View file

@ -0,0 +1,101 @@
Inspired by Ship Names (Minds):
Many Culture ship names are statements or phrases, often with a humorous, ironic, or philosophical bent.
**Witty / Humorous / Ironic:**
* `SleeperService`: A massive GSV (General Systems Vehicle) with a reputation for taking on unusual tasks.
* `OfCourseIStillLoveYou`: A popular choice, often abbreviated to `OCISLY`. (This one was famously used by SpaceX for one of their drone ships).
* `NoMoreMrNiceGuy`: A GSV with a clear statement of intent.
* `JustReadTheInstructions`: For a machine that, hopefully, does what it's told!
* `AttitudeAdjuster`: A GSV, good for a machine that helps correct or manage things.
* `GreyArea`: A versatile name, originally the ship *Meatfucker* before a name change.
* `ZeroGravitas`: For a machine that perhaps doesn't take itself too seriously, or handles lightweight tasks.
* `SoMuchForSubtlety`: When directness is key.
* `ProblemChild`: A GCU (General Contact Unit) name that could be amusing for a temperamental machine.
* `LivewareProblem`: An ROU (Rapid Offensive Unit) name, humorously referring to user error.
* `GravitasShortfall`: Short for the ROU *Experiencing A Significant Gravitas Shortfall*.
* `JustTesting`: A simple, unassuming name for perhaps an experimental setup.
* `NervousEnergy`: A GCU name, could fit a busy or high-performance machine.
**More Serious / Philosophical:**
* `ProstheticConscience`: A GSV, for a machine that perhaps enforces rules or ethics.
* `LimitingFactor`: A GCU, could be good for a machine that defines boundaries or bottlenecks.
* `Arbitrary`: A GCU name, for a machine with a general purpose.
* `Xenophile`: A GCU, for a machine that interacts with many different systems or data types.
* `CongenitalOptimist`: A GSV, for a machine you hope will always perform well.
**Assertive / Offensive (often ROUs - Rapid Offensive Units):**
* `KillingTime`: An ROU, direct and to the point.
* `FrankExchangeOfViews`: An SC (Special Circumstances) favorite, often an ROU.
* `HeavyMessing`: An ROU, implies significant impact.
* `LastingDamage`: An ROU, for a machine that makes a permanent mark.
* `EightRoundsRapid`: An ROU, suggesting quick, decisive action.
* `MoralConstraints`: Short for the ROU *Falling Outside The Normal Moral Constraints*.
### Inspired by Character Names:
**Humans / Humanoids:**
* `Zakalwe`: Cheradenine Zakalwe, a complex and highly capable agent of Special Circumstances.
* `Gurgeh`: Jernau Morat Gurgeh, the master game player from "The Player of Games."
* `Sma`: Diziet Sma, another prominent Special Circumstances agent.
* `Quilan`: An interesting character from "Look to Windward."
* `Lededje`: Lededje Y'breq, from "Surface Detail."
**Drones / AI (Non-Ship Minds):**
* `Skaffen`: Short for Skaffen-Amtiskaw, Diziet Sma's intelligent drone companion.
* `MawhrinSkel`: A memorable and somewhat rebellious drone from "The Player of Games."
* `FlereImsaho`: A drone with a significant role in "Consider Phlebas."
* `TurminderXuss`: The Mind of the GSV *Mistake Not...* is sometimes referred to as Xuss.
Ship Names (Often Witty, Philosophical, or Ominous)
Culture ship names are famous for their character. They are categorized by class, like GSV (General Systems Vehicle), GCU (General Contact Unit), ROU (Rapid Offensive Unit), etc. ROUs tend to have more aggressive names, while GSVs and GCUs can be more whimsical or philosophical.
**Shorter / Punchier Options:**
* `Gravitas` (inspired by *Absence Of Gravitas* or *Zero Gravitas*)
* `AttitudeAdjuster` (ROU)
* `Empiricist` (GSV)
* `GreyArea` (GCU, also infamously known as *Meatfucker*)
* `LimitingFactor` (GSV)
* `LittleRascal` (GSV)
* `MistakeNot` (short for the very long and threatening *Mistake Not My Current State Of Joshing Gentle Peevishness...*)
* `NuisanceValue` (ROU)
* `SleeperService` (GSV - a very versatile and well-known name)
* `SteelyGlint`
* `TacticalGrace` (ROU)
* `Xenophobe` (GSV - perhaps good for a firewall or a machine dealing with external connections?)
**Iconic / Slightly Longer (can be abbreviated):**
* `ClearAirTurbulence` (the Free Company ship from *Consider Phlebas*)
* `FrankExchangeOfViews` (ROU - could be `FrankExchange` or `FEoV`)
* `GunboatDiplomat` (ROU)
* `JustReadTheInstructions` (ROU - often abbreviated J.R.T.I.)
* `NoMoreMrNiceGuy` (ROU)
* `OfCourseIStillLoveYou` (GSV - famously adopted by SpaceX for a drone ship)
* `ProstheticConscience` (GSV)
* `QuietlyConfident`
* `SenseAmidstMadness` (from *Sense Amidst Madness, Wit Amidst Folly*)
* `SoMuchForSubtlety`
* `TheEndsOfInvention`
* `UnacceptableBehaviour` (ROU)
### Character & Drone Names
These are often more conventional as names but still carry the weight of their personalities from the books.
* `Sma` (Diziet Smas, a pragmatic and experienced Special Circumstances agent)
* `Gurgeh` (Jernau Morat Gurgeh, the master game player from *The Player of Games*)
* `Zakalwe` (Cheradenine Zakalwe, the complex and formidable SC agent from *Use of Weapons*)
* `Balveda` (Perosteck Balveda, an SC agent from *Consider Phlebas*)
* `Horza` (Bora Horza Gobuchul, the protagonist/antagonist from *Consider Phlebas*)
* `Skaffen` (from Skaffen-Amtiskaw, Diziet Sma's highly capable drone companion)
* `Mawhrin` (from Mawhrin-Skel, an ambitious drone from *The Player of Games*)
* `Kabe` (Ambassador Kabe, an ancient and wise alien from *Look to Windward*)
* `Ziller` (the exiled Chelgran composer from *Look to Windward*)
* `Lededje` (Lededje Y'breq, a determined character from *Surface Detail*)
* `QiRia` (a significant Mind from *The Hydrogen Sonata*)
* `Ferbin` (a character from *The Hydrogen Sonata*)

28
overlays/default.nix Normal file
View file

@ -0,0 +1,28 @@
final: prev: {
# Custom packages and overrides for Home-lab infrastructure
# Home-lab specific tools and scripts
home-lab-tools = final.callPackage ../packages/home-lab-tools.nix { };
# Override packages with custom configurations
starship = prev.starship.override {
# Add any custom starship configuration
};
# Add unstable packages to stable
inherit (final.unstable or {})
# Example: latest version of development tools
# zed-editor
# github-copilot-cli
;
# Custom vim/neovim configurations
vim-home-lab = prev.vim.override {
features = "huge";
};
# Emacs with custom packages
emacs-home-lab = prev.emacs.override {
# Custom emacs configuration
};
}

145
packages/README.md Normal file
View file

@ -0,0 +1,145 @@
# Packages Directory
This directory contains custom package definitions and overlays for the Home-lab NixOS infrastructure.
## Directory Purpose
The `packages/` directory is used for:
- Custom package derivations not available in nixpkgs
- Modified versions of existing packages
- Home-lab specific applications and utilities
- Package overlays and customizations
## Structure
### Custom Packages
- `my-package/` - Individual package directories
- `default.nix` - Package collection and exports
- `flake-module.nix` - Flake integration for packages
### Package Categories
- `applications/` - Custom applications and GUIs
- `scripts/` - Shell scripts and automation tools
- `configs/` - Configuration packages and templates
- `overlays/` - Package overlays and modifications
## Usage
### In Flake Configuration
```nix
# flake.nix
{
outputs = { self, nixpkgs, ... }: {
packages.x86_64-linux = import ./packages {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
};
overlays.default = import ./packages/overlays;
};
}
```
### In Machine Configuration
```nix
# machine configuration
{
nixpkgs.overlays = [ inputs.self.overlays.default ];
environment.systemPackages = with pkgs; [
# Custom packages from this directory
my-custom-tool
home-lab-scripts
];
}
```
## Package Development
### Creating New Package
1. Create package directory: `packages/my-package/`
2. Write `default.nix` with package derivation
3. Add to `packages/default.nix` exports
4. Test with `nix build .#my-package`
### Package Template
```nix
{ lib, stdenv, fetchFromGitHub, ... }:
stdenv.mkDerivation rec {
pname = "my-package";
version = "1.0.0";
src = fetchFromGitHub {
owner = "user";
repo = "repo";
rev = "v${version}";
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
meta = with lib; {
description = "Description of my package";
homepage = "https://github.com/user/repo";
license = licenses.mit;
maintainers = [ "geir" ];
platforms = platforms.linux;
};
}
```
## Overlay Examples
### Package Modification
```nix
# overlays/default.nix
final: prev: {
# Modify existing package
vim = prev.vim.override {
features = "huge";
};
# Add custom package
home-lab-tools = final.callPackage ../tools { };
}
```
## Home-lab Specific Packages
### CongenitalOptimist Packages
- Development environment customizations
- Workstation-specific tools
- Desktop application modifications
### sleeper-service Packages
- File server utilities
- Monitoring tools
- Backup scripts
- Network service tools
## Best Practices
- **Versioning**: Pin package versions for reproducibility
- **Documentation**: Include clear descriptions and usage
- **Testing**: Test packages across target machines
- **Licensing**: Respect upstream licenses and attributions
- **Maintenance**: Keep packages updated and functional
## Integration with Modules
Packages can be integrated with NixOS modules:
```nix
# modules/development/tools.nix
{ config, pkgs, ... }: {
environment.systemPackages = with pkgs; [
# Reference custom packages
home-lab-dev-tools
custom-editor-config
];
}
```
## Flake Outputs
Custom packages are exported as flake outputs:
- `packages.x86_64-linux.package-name`
- `overlays.default`
- `apps.x86_64-linux.script-name`

16
packages/default.nix Normal file
View file

@ -0,0 +1,16 @@
{ pkgs ? import <nixpkgs> { } }:
{
# Custom packages for Home-lab infrastructure
# Home-lab specific tools and utilities
home-lab-tools = pkgs.callPackage ./home-lab-tools.nix { };
# Re-export commonly used packages with custom configurations
inherit (pkgs)
# Core utilities that might be customized
git
curl
wget
;
}

View file

@ -0,0 +1,38 @@
{ lib, stdenv, writeShellScriptBin, ... }:
writeShellScriptBin "home-lab-tools" ''
#!/usr/bin/env bash
# Home-lab administration tools
# Placeholder for custom utilities and scripts
case "$1" in
"status")
echo "Home-lab infrastructure status:"
echo " congenital-optimist: $(systemctl is-active tailscale || echo 'unknown')"
echo " sleeper-service: Checking connectivity..."
;;
"backup")
echo "Initiating backup procedures..."
echo "This would trigger backup scripts across the infrastructure"
;;
"monitor")
echo "System monitoring overview:"
echo "Use this space for custom monitoring commands"
;;
"deploy")
echo "Deploying configurations..."
echo "This would handle nixos-rebuild across machines"
;;
*)
echo "Home-lab Tools"
echo "Usage: $0 {status|backup|monitor|deploy}"
echo ""
echo "Available commands:"
echo " status - Check infrastructure status"
echo " backup - Run backup procedures"
echo " monitor - Show monitoring overview"
echo " deploy - Deploy configurations"
;;
esac
''

380
plan.md Normal file
View file

@ -0,0 +1,380 @@
# Home Lab Migration Plan
## Current State Assessment
### CongenitalOptimist Machine
- **Current NixOS Version**: 25.05
- **Hardware**: AMD CPU/GPU, ZFS storage (zpool + stuffpool), NFS mounts
- **Desktop Environments**: GNOME, Cosmic, Sway
- **Virtualization**: libvirt, Incus, Podman
- **Configuration Style**: Traditional NixOS (non-flakes)
- **Dotfiles Approach**: Prefer Emacs org-mode with literate programming (no Home Manager)
### Current Structure
```
Home-lab/
├── Machines/
│ ├── CongenitalOptimist/ (existing - AMD workstation)
│ │ ├── configuration.nix
│ │ ├── hardware-configuration.nix
│ │ └── About.org
│ └── Modules/ (existing modular structure)
│ ├── common/
│ │ ├── base.nix (modern CLI tools & aliases)
│ │ └── tty.nix (console styling)
│ └── virtualization/
│ ├── podman.nix
│ ├── libvirt.nix
│ └── incus.nix
└── Users/
└── geir/
└── user.nix (has typo: progtams → programs)
```
### Target Structure (Post-Migration)
```
Home-lab/
├── flake.nix
├── flake.lock
├── machines/
│ ├── congenital-optimist/ (AMD workstation)
│ │ ├── default.nix
│ │ ├── hardware-configuration.nix
│ │ └── About.org
│ └── sleeper-service/ (Intel Xeon E3-1230 V2 file server)
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── About.org
├── modules/
│ ├── common/
│ ├── desktop/
│ ├── development/
│ ├── virtualization/
│ ├── services/
│ │ ├── nfs.nix
│ │ ├── samba.nix
│ │ ├── backup.nix
│ │ └── monitoring.nix
│ └── users/
│ └── common.nix (shared user configurations)
├── users/
│ └── geir/
│ ├── dotfiles/
│ │ ├── README.org (geir's literate config)
│ │ ├── emacs/
│ │ ├── shell/
│ │ └── editors/
│ └── user.nix (geir's system config)
├── overlays/
├── packages/
└── secrets/ (for future secrets management)
```
## Phase 1: Flakes Migration (Priority: High)
### 1.1 Create Flake Foundation
- [x] Create `flake.nix` at repository root
- [x] Define nixpkgs input pinned to NixOS 25.05
- [x] Add nixpkgs-unstable for bleeding edge packages
- [x] Structure outputs for multiple machines (no Home Manager)
- [x] Fix inconsistent naming convention (machine directories to lowercase)
- [x] Update flake outputs to use correct lowercase paths
### 1.2 Restructure Configuration
- [x] Convert `configuration.nix` to flake-compatible format
- [x] **Keep `system.stateVersion` as "23.11"** (maintains data compatibility)
- [x] Update existing module imports for flake structure
- [x] Integrate existing user configuration properly
- [x] Fix nerd-fonts syntax for 25.05 compatibility
- [x] Fix hostname typo (congenial-optimist → congenital-optimist)
### 1.3 Consolidate User Configuration
- [x] Fix typo in `users/geir/user.nix` (progtams → programs) - Already correct
- [x] Merge duplicate user packages between main config and user module
- [x] Decide on package location strategy (system vs user level)
- [x] Ensure all existing functionality is preserved
### 1.4 Configuration Testing & Validation
- [x] Validate flake syntax with `nix flake check`
- [x] Test build without switching: `nixos-rebuild build --flake`
- [x] Test configuration: `nixos-rebuild test --flake`
- [x] **Successfully tested modularized configuration with virtualization**
### 1.5 Desktop Environment Modularization ✅ NEW
- [x] Split monolithic `environments.nix` into modular components:
- [x] `common.nix` - Shared desktop configuration (XDG portal, dbus)
- [x] `gnome.nix` - GNOME desktop environment with extensions
- [x] `cosmic.nix` - System76 Cosmic desktop environment
- [x] `sway.nix` - Sway window manager with Wayland tools
- [x] Update main configuration to use modular desktop imports
- [x] Test modular desktop configuration successfully
### 1.6 Virtualization Stack ✅ NEW
- [x] Add comprehensive virtualization support:
- [x] **Incus** - Modern container and VM management (replaces LXD)
- [x] **Libvirt/QEMU** - Full KVM virtualization with virt-manager
- [x] **Podman** - Rootless containers with Docker compatibility
- [x] Configure proper user groups (incus-admin, libvirt, podman)
- [x] Enable UEFI/OVMF support for modern VM guests
- [x] Test all virtualization services running successfully
- [ ] Create rollback plan and ZFS snapshots
- [ ] Switch to flake configuration permanently
### 1.7 GitOps Foundation & CI/CD Setup ✅ NEW
- [ ] Initialize git repository for infrastructure as code
- [ ] Create comprehensive `.gitignore` for NixOS/Nix projects
- [ ] Set up initial commit with current modular configuration
- [ ] Plan CI/CD pipeline for configuration validation
- [ ] Design branch strategy for infrastructure changes
- [ ] Create templates for pull request workflows
- [ ] Plan automated testing for configuration changes
- [ ] Set up secrets management strategy for CI/CD
- [ ] Document GitOps workflow for multi-machine deployments
### 1.8 Additional Migration Tasks
- [x] Update all documentation files to use consistent naming
- [x] Update flake descriptions and comments for clarity
- [x] Verify all module imports work correctly in new structure
- [x] Modularize congenital-optimist configuration into logical modules
- [ ] Clean up any remaining references to old PascalCase paths
- [ ] Test that existing aliases and CLI tools still work
- [ ] Verify desktop environments (GNOME, Cosmic, Sway) all function
- [ ] Test virtualization stack (podman, libvirt, incus) functionality
- [ ] Validate ZFS and storage configuration compatibility
- [x] Generate and commit flake.lock file
- [ ] Create backup of current working configuration before final switch
## Phase 2: Configuration Cleanup & Organization
### 2.1 Optimize Current Modular Structure
- [ ] Review and optimize existing `common/base.nix` tools
- [ ] Enhance `common/tty.nix` console configuration
- [ ] Validate virtualization modules are complete
- [ ] Create desktop environment modules (separate GNOME, Cosmic, Sway)
- [ ] Separate development tools into dedicated module
### 2.2 Target Directory Structure
```
Home-lab/
├── flake.nix
├── flake.lock
├── machines/
│ ├── CongenitalOptimist/ (AMD workstation)
│ │ ├── default.nix (main machine config)
│ │ ├── hardware-configuration.nix
│ │ └── About.org
│ └── SleeperService/ (Intel Xeon file server)
│ ├── default.nix (file server config)
│ ├── hardware-configuration.nix
│ └── About.org
├── modules/
│ ├── common/
│ │ ├── base.nix (existing modern CLI tools)
│ │ ├── tty.nix (existing console config)
│ │ └── nix.nix (flakes + experimental features)
│ ├── desktop/
│ │ ├── gnome.nix
│ │ ├── cosmic.nix
│ │ └── sway.nix
│ ├── development/
│ │ ├── editors.nix (emacs, neovim, vscode, etc.)
│ │ ├── languages.nix (rust, python, LSPs)
│ │ └── tools.nix
│ ├── virtualization/ (existing)
│ │ ├── podman.nix
│ │ ├── libvirt.nix
│ │ └── incus.nix
│ ├── services/ (for SleeperService)
│ │ ├── nfs.nix (network file sharing)
│ │ ├── samba.nix (windows compatibility)
│ │ ├── backup.nix (automated backups)
│ │ ├── monitoring.nix (system monitoring)
│ │ └── storage.nix (ZFS/RAID management)
│ └── users/
│ └── common.nix (shared user configurations)
├── users/
│ └── geir/
│ ├── dotfiles/
│ │ ├── README.org (main literate config)
│ │ ├── emacs/
│ │ ├── shell/
│ │ └── editors/
│ └── user.nix (consolidated user config)
├── overlays/
├── packages/
└── secrets/ (for future secrets management)
```
## Phase 3: System Upgrade & Validation
### 3.1 Pre-upgrade Preparation
- [ ] Backup current system configuration
- [ ] Document current package versions
- [ ] Create ZFS snapshots of all datasets
- [ ] Test flake build without switching
- [ ] Verify all existing modules work in flake context
### 3.2 Upgrade Execution
- [ ] Switch to flake-based configuration
- [ ] Upgrade to NixOS 25.05
- [ ] Validate all services start correctly
- [ ] Test desktop environments functionality
- [ ] Verify virtualization stack
- [ ] Check user environment and packages
### 3.3 Post-upgrade Validation
- [ ] Verify all applications launch
- [ ] Test development tools (editors, LSPs, compilers)
- [ ] Validate container and VM functionality
- [ ] Check ZFS and NFS mount operations
- [ ] Verify shell environment and modern CLI tools work
- [ ] Test console theming and TTY setup
## Phase 4: Literate Dotfiles Setup
### 4.1 Per-User Org-mode Infrastructure
- [ ] Create per-user dotfiles directories (`users/geir/dotfiles/`)
- [ ] Create comprehensive `users/geir/dotfiles/README.org` with auto-tangling
- [ ] Set up Emacs configuration for literate programming workflow
- [ ] Configure automatic tangling on save
- [ ] Create modular sections for different tool configurations
- [ ] Plan for additional users (admin, service accounts, etc.)
### 4.2 Configuration Domains
- [ ] Shell configuration (zsh, starship, aliases)
- [ ] Editor configurations (emacs, neovim, vscode)
- [ ] Development tools and environments
- [ ] System-specific tweaks and preferences
- [ ] Git configuration and development workflow
### 4.3 Integration with NixOS
- [ ] Link org-mode generated configs with NixOS modules where appropriate
- [ ] Document the relationship between system-level and user-level configs
- [ ] Create per-user configuration templates for common patterns
- [ ] Plan user-specific configurations vs shared configurations
- [ ] Consider user isolation and security implications
## Phase 5: Home Lab Expansion Planning
### 5.1 Infrastructure Additions
#### Naming Convention
- **Machine Names**: UpperCase (e.g., `CongenitalOptimist`, `SleeperService`)
- **Folder Names**: UpperCase matching machine names (e.g., `CongenitalOptimist/`, `SleeperService/`)
- **Flake Outputs**: lowercase-with-hyphens (e.g., `nixosConfigurations.congenital-optimist`)
- **Hostnames**: lowercase-with-hyphens (e.g., `congenital-optimist`, `sleeper-service`)
- [ ] **SleeperService** file server (Intel Xeon E3-1230 V2, 16GB RAM):
- NFS server for network storage
- Samba server for Windows compatibility
- Automated backup services
- System monitoring and alerting
- ZFS or software RAID for data redundancy
- [ ] Plan for additional machines:
- Media server (Jellyfin/Plex) - could run on SleeperService
- Home automation hub
- CI/CD runner
- [ ] Plan for additional users across machines:
- Service accounts for automation
- Admin accounts for management
- Guest accounts for temporary access
- [ ] Network infrastructure planning
- [ ] Consider hardware requirements for future expansion
### 5.2 Services Architecture
- [ ] Centralized configuration management
- [ ] Per-user secrets management (agenix/sops-nix)
- [ ] User-specific service configurations
- [ ] Monitoring and logging (Prometheus, Grafana)
- [ ] Backup strategy across machines and users
- [ ] Container orchestration planning
### 5.3 Security & Networking
- [ ] VPN configuration (Tailscale expansion)
- [ ] Firewall rules standardization
- [ ] SSH key management
- [ ] Certificate management (Let's Encrypt)
## Phase 6: Advanced Features
### 6.1 Development Workflow
- [ ] Devshells for different projects
- [ ] Cachix setup for faster builds
- [ ] CI/CD integration
- [ ] Literate dotfiles with org-mode tangling automation
### 6.2 Automation & Maintenance
- [ ] Automated system updates
- [ ] Configuration validation tests
- [ ] Deployment automation
- [ ] Monitoring and alerting
## Timeline Estimates
- **Phase 1**: 1-2 weeks (flakes migration)
- **Phase 2**: 1 week (cleanup and organization)
- **Phase 3**: 2-3 days (upgrade and validation)
- **Phase 4**: 1 week (literate dotfiles setup)
- **Phase 5**: 2-4 weeks (expansion planning and implementation)
- **Phase 6**: Ongoing (advanced features as needed)
## Risk Mitigation
### Critical Risks
1. **Boot failure after upgrade**: ZFS snapshots for quick rollback
2. **Desktop environment issues**: Keep multiple DEs as fallback
3. **Virtualization breakage**: Document current VM configurations
4. **Data loss**: Multiple backup layers (ZFS, external)
5. **User environment regression**: Backup existing dotfiles
### Rollback Strategy
- ZFS snapshot rollback capability
- Keep old configuration.nix as reference
- Maintain emergency boot media
- Document manual recovery procedures
- Preserve current user configuration during migration
## Success Criteria
- [ ] System boots reliably with flake configuration
- [ ] All current functionality preserved
- [ ] NixOS 25.05 running stable
- [ ] Configuration is modular and maintainable
- [ ] User environment fully functional with all packages
- [ ] Modern CLI tools and aliases working
- [ ] Console theming preserved
- [ ] Virtualization stack operational
- [ ] Literate dotfiles workflow established
- [ ] Ready for multi-machine expansion
- [ ] Development workflow improved
- [ ] Documentation complete for future reference
## Infrastructure Notes
### CongenitalOptimist (AMD Workstation)
- Already has excellent modular structure
- Modern CLI tools (eza, bat, ripgrep, etc.) already configured in base.nix
- Console theming with Joker palette already implemented
- User configuration needs cleanup (fix typo, consolidate packages)
- ZFS configuration is solid and shouldn't need changes
- Keep Tailscale configuration as network foundation
- The AMD GPU setup should carry over cleanly to 25.05
- Consider renaming hostname from "work" to "congenital-optimist" for consistency
### SleeperService (Intel Xeon File Server)
- Intel Xeon E3-1230 V2 @ 3.70GHz (4 cores, 8 threads)
- 16GB RAM - adequate for file server operations
- Perfect for reliable, background file serving tasks
- Culture name fits: "massive GSV with reputation for taking unusual tasks"
- Will handle NFS mounts currently served by external "files" server
- Plan for ZFS or software RAID for data redundancy
- Headless operation - no desktop environments needed
- SSH-only access with robust monitoring
### Home Lab Philosophy
- Emacs org-mode literate programming approach provides better control than Home Manager
- Culture ship names create memorable, characterful infrastructure
- Modular NixOS configuration allows easy machine additions
- Per-user dotfiles structure scales across multiple machines
- Tailscale provides secure network foundation for multi-machine setup

101
users/README.md Normal file
View file

@ -0,0 +1,101 @@
# Users Directory Structure
This directory contains per-user configurations and dotfiles for the Home-lab infrastructure, organized to support multiple users across multiple machines.
## Directory Organization
### `geir/`
Primary user configuration for geir:
- `user.nix` - NixOS user configuration (packages, groups, shell)
- `dotfiles/` - Literate programming dotfiles using org-mode
- `README.org` - Main literate configuration file
- `emacs/` - Emacs-specific configurations
- `shell/` - Shell configurations (zsh, bash, etc.)
- `editors/` - Editor configurations (neovim, vscode)
### Future Users
Additional user directories will follow the same pattern:
- `admin/` - Administrative user for system management
- `service/` - Service accounts for automation
- `guest/` - Temporary/guest user configurations
## User Configuration Philosophy
### NixOS Integration
Each user has a `user.nix` file that defines:
- User account settings (shell, groups, home directory)
- User-specific packages
- System-level user configurations
- Integration with home lab services
### Literate Dotfiles
Each user's `dotfiles/README.org` serves as:
- Single source of truth for all user configurations
- Self-documenting setup with rationale
- Auto-tangling to generate actual dotfiles
- Version-controlled configuration history
### Multi-Machine Consistency
User configurations are designed to work across machines:
- congenital-optimist: Full development environment
- sleeper-service: Minimal server access
- Future machines: Consistent user experience
## Dotfiles Structure
### `dotfiles/README.org`
Main literate configuration file containing:
- Shell configuration (zsh, starship, aliases)
- Editor configurations (emacs, neovim)
- Development tool settings
- Git configuration
- Machine-specific customizations
### Subdirectories
- `emacs/` - Generated Emacs configuration files
- `shell/` - Generated shell configuration files
- `editors/` - Generated editor configuration files
## Usage Examples
### Importing User Configuration
```nix
# In machine configuration
imports = [
../../users/geir/user.nix
];
```
### Adding New User
1. Create user directory: `users/newuser/`
2. Copy and adapt `user.nix` template
3. Create `dotfiles/README.org` with user-specific configs
4. Import in machine configurations as needed
### Tangling Dotfiles
```bash
# From user's dotfiles directory
cd users/geir/dotfiles
emacs --batch -l org --eval "(org-babel-tangle-file \"README.org\")"
```
## Design Principles
- **User Isolation**: Each user's configs are self-contained
- **Machine Agnostic**: Configs work across different machines
- **Literate Programming**: All configs are documented and explained
- **Version Control**: Full history of configuration changes
- **Automation**: Auto-tangling and deployment workflows
## Security Considerations
- User-specific secrets managed separately
- Limited cross-user access
- Machine-appropriate privilege levels
- Service account isolation
## Naming Convention
- **User Directories**: lowercase (e.g., `geir/`, `admin/`)
- **Configuration Files**: descriptive names (e.g., `user.nix`, `README.org`)
- **Generated Files**: follow target application conventions

View file

@ -0,0 +1,267 @@
#+TITLE: Userland configurations for Geir Okkenhaug Jerstad
#+AUTHOR: Geir Okkenhaug Jerstad
#+DATE: [2025-05-28]
#+STARTUP: overview
#+PROPERTY: header-args :tangle yes
#+PROPERTY: header-args:nix :mkdirp yes
* Introduction
Socalled dotfiles, or userland configurations, are personal configurations for various tools
and applications.
* Sway
Configuration for sway waybar fuzzel and other sway related tools
#+BEGIN_SRC shell :tangle /home/geir/.config/sway/config
default_border none
### Variables
#
# Logo key. Use Mod1 for Alt.
set $mod Mod4
# Home row direction keys, like vim
set $left h
set $down j
set $up k
set $right l
# Your preferred terminal emulator
set $term kitty
set $menu fuzzel
# Set gnome stuff
set $gnome-schema org.gnome.desktop.interface
### Output configuration
#
# Default wallpaper (more resolutions are available in /run/current-system/sw/share/backgrounds/sway/)
output * bg /home/geir/Pictures/wall.jpg fill
#
# Example configuration:
#
# output HDMI-A-1 resolution 1920x1080 position 1920,0
#
# You can get the names of your outputs by running: swaymsg -t get_outputs
### Idle configuration
#
# Example configuration:
#
exec swayidle -w \
timeout 1200 'swaylock -f -c 000000' \
timeout 36000 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \
before-sleep 'swaylock -f -c 000000'
# This will lock your screen after 600 seconds of inactivity, then turn off
# your displays after another 600 seconds, and turn your screens back on when
# resumed. It will also lock your screen before your computer goes to sleep.
### Input configuration
#
# Example configuration:
#
input "type:touchpad" {
dwt enabled
tap enabled
natural_scroll enabled
middle_emulation enabled
}
#
# You can get the names of your inputs by running: swaymsg -t get_inputs
# Read `man 5 sway-input` for more information about
# or input <identifier>
input "type:keyboard" {
xkb_layout "us, no"
xkb_variant ,nodeadkeys
xkb_options "caps:ctrl_modifier, grp:win_space_toggle"
}
# screenshots
bindsym $mod+c exec flameshot gui -p /home/geir/Pictures/Screenshots
### Key bindings
#
# Basics:
#
# Start a terminal
bindsym $mod+Return exec $term
# Kill focused window
bindsym $mod+Shift+q kill
# Start your launcher
bindsym $mod+d exec $menu
# Drag floating windows by holding down $mod and left mouse button.
floating_modifier $mod normal
# Reload the configuration file
bindsym $mod+Shift+c reload
# Exit sway (logs you out of your Wayland session)
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
#
# Moving around:
#
# Move your focus around
bindsym $mod+$left focus left
bindsym $mod+$down focus down
bindsym $mod+$up focus up
bindsym $mod+$right focus right
# Or use $mod+[up|down|left|right]
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
# Move the focused window with the same, but add Shift
bindsym $mod+Shift+$left move left
bindsym $mod+Shift+$down move down
bindsym $mod+Shift+$up move up
bindsym $mod+Shift+$right move right
# Ditto, with arrow keys
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
#
# Workspaces:
#
# Switch to workspace
bindsym $mod+1 workspace number 1
bindsym $mod+2 workspace number 2
bindsym $mod+3 workspace number 3
bindsym $mod+4 workspace number 4
bindsym $mod+5 workspace number 5
bindsym $mod+6 workspace number 6
bindsym $mod+7 workspace number 7
bindsym $mod+8 workspace number 8
bindsym $mod+9 workspace number 9
bindsym $mod+0 workspace number 10
# Move focused container to workspace
bindsym $mod+Shift+1 move container to workspace number 1
bindsym $mod+Shift+2 move container to workspace number 2
bindsym $mod+Shift+3 move container to workspace number 3
bindsym $mod+Shift+4 move container to workspace number 4
bindsym $mod+Shift+5 move container to workspace number 5
bindsym $mod+Shift+6 move container to workspace number 6
bindsym $mod+Shift+7 move container to workspace number 7
bindsym $mod+Shift+8 move container to workspace number 8
bindsym $mod+Shift+9 move container to workspace number 9
bindsym $mod+Shift+0 move container to workspace number 10
#
# Layout stuff:
#
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
bindsym $mod+b splith
bindsym $mod+v splitv
# Switch the current container between different layout styles
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# Make the current focus fullscreen
bindsym $mod+f fullscreen
# Toggle the current focus between tiling and floating mode
bindsym $mod+Shift+space floating toggle
# Swap focus between the tiling area and the floating area
bindsym $mod+ctrl+space focus mode_toggle
# Move focus to the parent container
bindsym $mod+a focus parent
#
# Scratchpad:
#
# Sway has a "scratchpad", which is a bag of holding for windows.
# You can send windows there and get them back later.
# Move the currently focused window to the scratchpad
bindsym $mod+Shift+minus move scratchpad
# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym $mod+minus scratchpad show
#
# Resizing containers:
#
mode "resize" {
# left will shrink the containers width
# right will grow the containers width
# up will shrink the containers height
# down will grow the containers height
bindsym $left resize shrink width 10px
bindsym $down resize grow height 10px
bindsym $up resize shrink height 10px
bindsym $right resize grow width 10px
# Ditto, with arrow keys
bindsym Left resize shrink width 10px
bindsym Down resize grow height 10px
bindsym Up resize shrink height 10px
bindsym Right resize grow width 10px
# Return to default mode
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+r mode "resize"
#
# Status Bar:
#
bar {
swaybar_command waybar
}
include /etc/sway/config.d/*
exec dbus-sway-environment
exec configure-gtk
exec gammastep
*+END_SRC
* Zsh
Configuration for zsh.
#+BEGIN_SRC shell :tangle /home/geir/.config/zsh/.zshrc
# Zsh configuration for Geir Okkenhaug Jerstad
zstyle ':completion:*' completer _expand _complete _ignored
zstyle ':completion:*' matcher-list ''
zstyle :compinstall filename '/home/geir/.zshrc'
autoload -Uz compinit
compinit
HISTFILE=~/.histfile
HISTSIZE=10000
SAVEHIST=10000
setopt autocd extendedglob
unsetopt beep nomatch
bindkey -e
eval "$(starship init zsh)"
eval "$(direnv hook zsh)"
eval "$(zoxide init zsh)"
fortune -s | cowsay -f dragon | clolcat
#+END_SRC
* Git
Configuration for git.
#+BEGIN_SRC shell :tangle /home/geir/.gitconfig
user.email=geokkjer@gmail.com
user.name=Geir Okkenhaug Jerstad
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
filter.lfs.clean=git-lfs clean -- %f
init.defaultbranch=main
#+END_SRC

View file

@ -0,0 +1,222 @@
#+title: Emacs Configuration
#+author: Geir Okkenhaug Jerstad
#+email: geir@geokkjer.eu
#+options: toc:nil num:nil
#+PROPERTY: header-args:emacs-lisp :tangle ~/.emacs.d/init.el
* About
My attempt at a litterate configuration for Emacs.
to tangle this file.
keyboard shortcut `C-c C-v t` (org-babel-tangle) in Emacs.
This will generate the `~/.emacs.d/init.el` file with the configuration.
* Prep
* Configuration
** Setup lexical binding
Here we set up lexical binding, which is a feature in Emacs Lisp that allows for more efficient variable scoping and function closures. This is recommended for performance reasons.
#+BEGIN_SRC emacs-lisp
;; enable lexical binding
(setq lexical-binding t)
#+END_SRC
** Set automatic update of packages
We set up Emacs to automatically update packages on startup. This ensures that we always have the latest versions of the packages we use.
#+BEGIN_SRC emacs-lisp
(defun geokkjer/display-startup-time ()
(message "Emacs loaded in %s with %d grabage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done))
(add-hook 'emacs-startup-hook #'geokkjer/display-startup-time)
(setq gc-cons-threshold (* 50 1000 1000))
#+END_SRC
** Customize UI
Here we set up the UI to our liking. We disable the menu bar, tool bar, and scroll bar, and set the font size to 14pt.
#+BEGIN_SRC emacs-lisp
;; disable startup screen
(setq inhibit-startup-screen t)
;; disable menu bar
(menu-bar-mode -1)
;; disable tool bar
(tool-bar-mode -1)
;; disable scroll bar
(scroll-bar-mode -1)
;; set font size
(set-face-attribute 'default nil :height 140)
#+END_SRC
Set up package management
#+BEGIN_SRC
;; Initialize package sources
(require 'package)
;; Set the repos
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")
("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
#+END_SRC
Set up doom modeline, which is a nice status line for Emacs. We set it up to show the current buffer name and the current line number.
#+BEGIN_SRC emacs-lisp
;; Doom modline, all-the-icons and doom-theme
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1)
:custom ((doom-modeline-height 15)))
(setq doom-modeline-icon t)
(use-package all-the-icons)
(use-package doom-themes
:init (load-theme 'doom-monokai-pro t))
#+END_SRC
Set up all-the-icons, which provides icons for various file types and modes in Emacs. This enhances the visual appearance of the UI.
install all-the-icons if not already installed with '<M-x> all-the-icons-install-fonts'
#+BEGIN_SRC emacs-lisp
(use-package all-the-icons
:if (display-graphic-p) ;; only load in GUI Emacs
:ensure t
:init
(unless (package-installed-p 'all-the-icons)
(package-refresh-contents)
(package-install 'all-the-icons))
:config
(all-the-icons-setup))
#+END_SRC
** Org Mode
Configure Org-mode for literate programming and note-taking.
#+BEGIN_SRC emacs-lisp
;; ensure org-mode is installed and up to date
(use-package org
:ensure t
:mode ("\\.org\\'" . org-mode)
:config
;; enable syntax highlighting in code blocks
(setq org-src-fontify-natively t)
;; preserve indentation in code blocks
(setq org-src-preserve-indentation t)
;; enable babel for code execution
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(python . t)
(nix . t)))
;; don't ask for confirmation when evaluating code blocks
(setq org-confirm-babel-evaluate nil))
#+END_SRC
* Code Completion and ide features
** LSP Mode
Here we install lsp-mode and lsp-ui, which are the core components of the LSP (Language Server Protocol) support in Emacs. We also set up keybindings for common LSP commands.
#+BEGIN_SRC emacs-lisp
;; install lsp-mode and lsp-ui if not already installed
(unless (package-installed-p 'lsp-mode)
(package-refresh-contents)
(package-install 'lsp-mode))
(unless (package-installed-p 'lsp-ui)
(package-refresh-contents)
(package-install 'lsp-ui))
(require 'lsp-mode)
(require 'lsp-ui)
;; enable lsp-mode in programming buffers
(add-hook 'prog-mode-hook #'lsp)
;; Enable line numbers
(column-number-mode)
(global-display-line-numbers-mode t)
#+END_SRC
** GitHub Copilot
Here we install from MELPA, enable it in all prog-modes and bind keys for completion:
run <M-x> copilot-install-server and <M-x> copilot-login
#+BEGIN_SRC emacs-lisp
;; ensure Copilot is installed
(unless (package-installed-p 'copilot)
(package-refresh-contents)
(package-install 'copilot))
(require 'copilot)
;; turn on in programming buffers
(add-hook 'prog-mode-hook #'copilot-mode)
;; keybindings: M-TAB to trigger, TAB to accept
(define-key copilot-mode-map (kbd "M-TAB") #'copilot-complete)
(define-key copilot-completion-map (kbd "<tab>") #'copilot-accept-completion)
#+END_SRC
Copilot Chat
#+BEGIN_SRC emacs-lisp
(unless (package-installed-p 'copilot-chat)
(package-install 'copilot-chat))
(use-package copilot-chat
:bind (:map global-map
("C-c C-y" . copilot-chat-yank)
("C-c M-y" . copilot-chat-yank-pop)
("C-c C-M-y" . (lambda () (interactive) (copilot-chat-yank-pop -1))))
)
#+END_SRC
** Language support
Here we install and configure support for various programming languages. We use the `use-package` macro to ensure that the packages are installed and configured correctly.
** NixOS from Emacs
Editing Nix files and doing NixOS admin stuff like nixos-rebuild boot --upgrade
Run the commands with M-x shell-command
#+BEGIN_SRC emacs-lisp
;; NixOS commands
(defun nixos-upgrade ()
"Run 'nixos-rebuild boot --upgrade' in a shell."
(interactive)
(shell-command "nixos-rebuild boot --upgrade"))
(defun nixos-switch ()
"Run 'nixos-rebuild switch' in a shell."
(interactive)
(shell-command "nixos-rebuild switch"))
#+END_SRC
#+BEGIN_SRC emacs-lisp
;; install nix-mode
(use-package nix-mode
:ensure t
:mode "\\.nix\\'")
;; install nix-repl
(use-package nix-repl
:ensure t
:mode "\\.nix\\'")
;; install nixpkgs
(use-package nixpkgs
:ensure t
:mode "\\.nix\\'")
#+END_SRC

69
users/geir/user.nix Normal file
View file

@ -0,0 +1,69 @@
{ pkgs, ... }:
{
users.users.geir = {
isNormalUser = true;
extraGroups = [ "networkmanager" "wheel" ];
shell = pkgs.zsh;
packages = with pkgs; [
# Browsers
chromium
vivaldi
vivaldi-ffmpeg-codecs
nyxt
firefox
# Shell & tools
zsh
zsh-completions
nix-zsh-completions
starship
nix-direnv
# Audio & system
ncpamixer
fastfetch
hyfetch
nerdfetch
emacsPackages.vterm
virt-manager
pavucontrol
gnome-tweaks
beauty-line-icon-theme
# Fun & misc
neo-cowsay
fortune
clolcat
zellij
gimp
vesktop
koodo-reader
# Github CLI
gh
];
};
environment.systemPackages = with pkgs;
[
zsh
zsh-completions
nix-zsh-completions
zsh-autocomplete
zsh-autosuggestions
zsh-syntax-highlighting
];
programs.zsh.enable = true;
programs.zsh.syntaxHighlighting.enable = true;
programs.zsh.enableCompletion = true;
programs.zsh.autosuggestions = {
enable = true;
historySearch = true;
};
programs.zsh.history = {
enable = true;
shareHistory = true;
saveOnExit = true;
};
}