How I Built and Secured a Self-Hosted Stack A developer built and secured a 13-service self-hosted platform on a single Linux VPS, including a personal AI chat interface, budgeting, RSS, notes, bookmarks, uptime monitoring, a dashboard, dev utilities, and an autonomous AI agent. The key security challenge was containing the AI agent, which has tool use and persistent memory. The developer isolated the agent on a dedicated Docker network, ensuring it has no network path to the database or other services, and implemented key-only SSH with a tested recovery console and a default-deny firewall. I built and operate a 13-service self-hosted platform on a single Linux VPS: a personal AI chat interface, budgeting, RSS, notes, bookmarks, uptime monitoring, a dashboard, dev utilities — and a self-hosted autonomous AI agent. Everything sits behind one reverse proxy with automatic HTTPS, most of it behind single sign-on, and the whole thing is captured as Docker Compose config that survives reboots and rebuilds. Up front, honestly: this is a personal, self-directed project, and I'd put my level at junior / early-career. I designed and run it, but it isn't an audited, production-grade environment. The value I'd point a reviewer to isn't enterprise completeness — it's the reasoning . So I'm going to lead with the part I cared most about: containing the AI agent. The interesting security question in this stack is: how do you contain a thing that's actively trying to get around your controls? The agent — Hermes, by Nous Research — has persistent memory and tool use: it can execute code, browse, and run web searches. It legitimately needs exactly two things from the rest of the stack: the chat front-end to talk to and the private metasearch service to search . It does not need the database, the notes app, the budget data, or the host. The mistake I caught. In the first iteration, the agent was sitting on the shared application network alongside everything else — which meant it had a network path to the database port . I didn't intend that; it was just the default outcome of dropping it on the same network as the apps. What I did instead of panicking. I stopped and reasoned about the actual blast radius. The database password was never readable by the agent — it lives in the database/Compose environment, not on the agent's filesystem or in anything its tools could read. What was exposed was an open port: a reachable network path to a data store from a code-executing agent. So the real exposure was narrower than "the agent can read my database." But that distinction doesn't earn the path a pass. Least privilege says an autonomous agent shouldn't have a route to a data store it has no reason to touch — full stop — regardless of whether I currently believe the credentials are safe. The re-architecture. I moved the agent onto a dedicated, isolated Docker network hermes-net : docker network connect hermes-net