Self-hosting a Linux server can involve many repetitive and time-consuming tasks. When I first set up my Ubuntu server, I would spend much of the day searching Stack Overflow for various bash commands. Then LLMs came onto the scene. They made this task much more ergonomic. Still, there was friction. Part of this was due to early LLMs being less reliable, but most of the friction came from the LLM not having the context it needed. So each chat would start with a litany of system info, apps that were installed, troubleshooting steps that had already been tried, etc. My approach has now evolved to using a structured folder documentation repo. This started by coming up with a schema which basically became something like:

HomeServer/
├── README.md                 # hostname, IP, ports, service index
├── server/
│   └── README.md             # host: hardware, network, firewall, cron
├── services/
│   ├── apache/
│   ├── ssh/
│   ├── mattermost/
│   └── …                     # one folder + README per service + optional service related scripts
├── tools/
│   ├── ssh/                  # PowerShell helpers for remote access
│   └── …                     # scripts / small utilities
├── secrets/                  # credentials (local-only, gitignored)
└── docs/
    └── ai-agent-runbook.md   # how agents should work against the box

This confers multiple advantages:

  • Each agent that works within this directory has rich context of the server’s design.
  • Avoids a simplistic file system mirror which would quickly drift.
  • Most tasks are related to a single service at a time; the agent has a clear reading path.
  • The tools folder provides sanctioned actions the agents can take.
  • Explicitly learns from previous interaction quirks like arguments getting mangled when passing between PowerShell and Bash, saving future agents from making the same mistakes.
  • Allows for creating repeatable workflows for annoying tasks — example below.

Upgrading Mattermost

Mattermost is a Slack alternative and upgrading is a relatively straightforward process, but it often would take several hours running backups, reading release docs, checking for breaking changes, etc. To address this I created a detailed runbook for an agent with links to documentation, explicit commands to run on the server, and expectations for what those commands would return. Crucially, also encoded in the runbook are explicit checkpoints where the agent should pause, present a summary of their current status and findings, and ask the user whether they should continue or abort. This has turned a multiple-hour process into a pain-free simple command with a few confirmation steps built in.

Limitations

It is worth noting that this approach is not for everyone. I have active backups of important data on my home server and am open to taking risks with the current generation of LLMs. This approach would benefit from inserting a harness into the workflow to sanitize LLM inputs to avoid catastrophic data loss. As this is a personal project of my own, I am willing to take the risk.