---
title: NixOS homelab
type: project
description: Two NixOS machines in one flake, with AI agents that change the config only after I approve.
tags: [nixos, agents, self-hosting]
related: [index.md, campus.md, aware.md, agntos.md, ../skills.md]
id: homelab
dates: "May 2026 to present"
role: solo
status: active
rank: featured
updated: 2026-10-16
---
Dates: May 2026 to present
Role: solo
Rank: featured project
Stack: NixOS · Nix flakes · Docker · Tailscale · Hermes Agent · llama.cpp
machines, one NixOS flake: 2
hardened containers: 27
agent sessions since June 2026: 472
agent skills in git: 191
tool calls: 58,000
Links: GitHub (public NixOS config) https://github.com/HasNate618/nixos-config-public
Summary: My laptop and a home server built from used parts run from one NixOS flake. Hermes Agent, from Nous Research, proposes the config changes, but nothing applies until I approve it, and a failed build rolls back to the last good one. One bug I won't forget: I set a WireGuard VPN as the server's default route, the peer died, and the whole machine went dark until I reset it by hand. Now the VPN lives inside the one container that needs it.

# NixOS homelab

## tl;dr

- One version-controlled Nix flake defines two machines: my laptop (flow) and a home server (home).
- 27 hardened Docker containers and native services, reachable only over Tailscale.
- One Hermes Agent profile per machine. Agents change the config, I approve, and a safe-rebuild guard applies it.
- A git-versioned library of 191 agent skills.
- 472 agent sessions and 58,000 tool calls since June 2026.

## Why I built it

I used to run a Debian Docker Compose homelab and a separate local AI setup. Both drifted from their config over time. Once AI agents were making changes, I needed every change to be a diff I could read first and undo later. I started building my own agent for NixOS configuration first (AgntOS), got impatient, and switched to NixOS with Hermes Agent instead. It works really well.

## What I built

I designed and built everything below. The agents edit config inside it, and I review every change before it applies.

- Moved both old setups to NixOS one service at a time, into one flake.
- Split services into modules by role: infrastructure, access, media, AI and monitoring.
- Put every service behind Caddy, reachable only over my private Tailscale network.
- Hardened containers: dropped capabilities, no-new-privileges, resource limits.
- Secrets encrypted in git with sops-nix, decrypted at boot to tmpfs.
- A self-hosted AI stack: Open WebUI, a Bifrost gateway between local and cloud models, crawl4ai, DeGoog search and Whisper.
- Two MCP servers. trawl does web search and page reading in one tool. Brightspace MCP exposes my courses, assignments, grades and announcements.
- A Hermes Agent profile per host, behind a nixos-safe-rebuild guard.
- llama.cpp on the laptop as a local model provider.

## How it works

Hermes Agent is an AI agent from Nous Research that works through tools and saved skills.

```diagram
alt: I ask an agent for a change. The agent edits the NixOS config and never touches the running system by hand. I approve, a safe-rebuild guard applies it, and if the build fails it rolls back to the last good build.
me: "change X" ─► agent edits NixOS config ─► I approve
                                                │
       live ◄── nixos-safe-rebuild ◄────────────┘
                     │
                     └── fails? roll back to last good build
```

1. I ask an agent for a change. The flow profile works on the laptop. The homelab profile reaches the server over SSH.
2. The agent edits the config. It never changes the running system by hand.
3. I approve. nixos-safe-rebuild applies it and rolls back if the build fails.
4. If a bad change gets through anyway, I boot the previous NixOS generation.
5. Subagents take the bigger investigations. A weekly curator prunes the skill library and backs up what it removes.
6. Uptime Kuma checks every service each minute, Netdata tracks metrics, and ntfy sends alerts.

## Models and cost

- The agents mostly run on low-cost hosted models, picked per task.
- llama.cpp on the laptop serves local GGUF models, and both agent profiles can use it.
- Bifrost routes between local and cloud models from one endpoint.

## Results

- 472 agent sessions and 58,000 tool calls since June 2026.
- 191 agent skills, versioned in git.
- 27 hardened containers, all private to Tailscale.

Two things that broke, and what I did:

> **VPN lockout.** A WireGuard default route took the whole server offline when the VPN peer died. Fixing it needed a physical reset. Now the VPN lives in one container, shared only by the service that needs it.

> **NIC driver bug.** The onboard network driver dropped to 10 Mbps after link hiccups. A systemd timer now checks link speed and reloads the driver.
