# An AI Coworker in an LXC Container

> A dedicated container on my Proxmox host runs a coding agent that writes, reviews, and ships changes to this site — through the same git-push pipeline I use. The interesting engineering isn't the model; it's the guardrails around it.

URL: https://harshith.in/blog/an-ai-coworker-in-an-lxc/
Author: Harshith Sunku (Staff Engineer) — https://harshith.in/about/
Tags: ai, linux, systems
Series: [The Homelab](https://harshith.in/series/homelab/) (part 3 of 5)

There's a container on my Proxmox host — Ubuntu 25.04, 4 vCPUs, 8 GB —
whose only job is to run a coding agent with access to this site's
repository. It has written posts, redesigned pages, fixed SEO bugs, and
shipped the search feature you can use right now. Not as a copilot in my
editor: as a coworker with its own machine.

The problem this post answers is the one I actually lost sleep over:
**how do you give an autonomous agent commit access and still sleep at
night?** I didn't know when I started — that uncertainty is exactly why
the lab got to host the experiment. The answer turned out to be the same
answer as for any junior engineer: constrain the blast radius and make
review cheap.

## Why the agent gets its own container

The first decision was isolation. The agent runs [in an LXC
container](https://harshith.in/blog/homelab-proxmox-zfs-lxc/) rather than on my workstation,
which buys exactly what containers buy: a filesystem boundary, a resource
cgroup, and a snapshot story. If an agent-driven `npm install` goes
sideways, the damage is confined to a ZFS dataset I can roll back in one
command. It also makes the agent's environment *reproducible* — the same
reason we put CI in containers, [as I covered in the container
internals post](https://harshith.in/blog/what-is-a-container/).

Sizing turned out to be trivial: the model runs in a datacenter, not
here, so the container is doing text processing and site builds. 4 vCPUs
and 8 GB never break a sweat; the full Astro build with 90 posts and OG
image generation takes about a minute. (If you want to know why local
inference wasn't an option, [the memory-bandwidth math](https://harshith.in/blog/how-llm-inference-works/)
answers it — a GPU-less container with an 8 GB ceiling isn't in that
conversation, and frontier-model quality wasn't negotiable for prose.)

API traffic doesn't go straight to providers either. It routes through an
LLM proxy on an Oracle free-tier VM, so keys live off my LAN and I get
one choke point for logging and rate limits.

## The pipeline is the guardrail

The agent inherits the same publishing pipeline
[the whole site runs on](https://harshith.in/blog/how-this-blog-runs-for-0/), and that
pipeline is doing quiet security work:

- **Everything is a git commit.** There is no path to production that
  skips version control. Every change the agent makes is diffable,
  attributable (commits are co-signed with the agent's name), and
  revertible.
- **CI is the reviewer that never trusts.** Type-check plus full build on
  every push. The content schema is strict — an invalid frontmatter field
  or a broken internal link pattern fails the build before deploy.
- **`draft: true` is a staging area.** Posts can land in the repo without
  going live, so "write it" and "publish it" are separate decisions.
- **`AGENTS.md` is the onboarding doc.** The repo carries its own
  instructions — voice, conventions, schema, do-nots. The agent reads it
  the way a new hire reads a runbook, and it works for the same reason
  runbooks work: the knowledge lives next to the system, not in someone's
  head.

Notice what's *not* in the list: trust in the model. The loop is designed
so that a bad change is cheap to catch and cheap to undo — the same
philosophy as [the agent-loop architecture](https://harshith.in/blog/building-an-agent-loop/)
itself, where the model proposes and the harness disposes.

## What it's actually like

The honest report: the agent is excellent at the work that has a
verifier. "Make the sitemap emit lastmod and prove it in the build
output" comes back done, with the grep to show it. It's weaker where
taste is the spec — I still edit for voice, and the
[MCP integrations](https://harshith.in/blog/model-context-protocol-explained/) that let it
check its own output (build logs, link checkers, search indexes) matter
more than raw model quality.

The surprise was workflow, not capability: an agent with its own machine
and a queue beats an agent in your editor, because it turns "help me
type" into "here's a task, ping me with the diff." That's a delegation
model, and delegation needs exactly the guardrails above — which is why
the pipeline came first.

## Takeaways

- Give an autonomous agent the same thing you'd give a new hire: an
  isolated machine, a documented repo, and a review process — not raw
  trust.
- LXC + ZFS snapshots make the blast radius a rollback, not an incident.
- Route agent API traffic through a proxy you control: keys off the LAN,
  one place to log and limit.
- Make CI strict enough that "the build passed" means something; then let
  the agent iterate against it.
- The productivity unlock is delegation with verification — the model
  proposes, git and CI dispose.
