Building an (almost) fully self-hosted, sandboxed, agentic software factory
JakeWritesCode
About me
Dark Mode
Table of contents
Building an (almost) fully self-hosted, sandboxed, agentic software factory<br>I built an (almost) fully self-hosted, sandboxed, agentic software factory.
tl;dr: It worked! From one prompt it created a repo, wrote the application and tests, got CI green, provisioned<br>Postgres and deployed the finished app behind HTTPS without another message from me.If you just wanna see the outcome<br>you can find a demo video at the bottom
LLMs got fun again! Maybe they always were and I was just stuck in the trough of disillusionment. Lately, whenever I<br>need a little tool, I just build it.<br>I was in the gym the other day and wanted a weights tracker. The app I had in mind was about as CRUD-y as it gets, but<br>all the app store versions wanted £12 per month, so I just one-shotted one with Claude. Great fun, but giving an LLM<br>root access to my machine in auto mode still doesn’t sit right with me.<br>So, the challenge: how can I create a fully remote agentic development environment where we structurally contain the LLM<br>rather than just trusting it? I want to give it an instruction and have it autonomously move through the<br>whole SDLC:<br>Researching the right stack and packages to use.<br>Planning and writing the code and tests.<br>Committing to Git, building and running a CI pipeline.<br>Deploying the work to a ‘production’ server with databases, o11y, and a domain with SSL.<br>All on my home server, without another cloud infrastructure bill. The only ongoing cost specific to this experiment is<br>a £20 Codex sub.<br>The Server(s)
Here they are in all their glory.<br>The one at the bottom is a 2014 dual-core i3 I’ve been running as a homelab for five years. It’s valiantly hosting this<br>blog and about 45 other Docker containers, from Pi-hole to a full Prometheus / Loki / Grafana stack. It also has port<br>443 forwarded from my router. I’d be miffed if an LLM broke it, so that’s not what we’re using today.<br>The top one is a 2021 10th-gen i7 with 32GB RAM, bought fresh from eBay with nothing on it. Perfect.<br>The Stack<br>The core development stack is self-hosted through Coolify. Inference and integrations like Tailscale, Telegram, DNS and<br>ACME still leave the box. You could host inference too, but I don’t have the hardware and I’d rather OpenAI subsidise<br>my experiments.<br>ComponentNotesPi-holeLocal DNS rules, with the side benefit of seeing less shitty advertising.TailscaleMakes my home network follow me around.CoolifyA self-hosted, Heroku-style PaaS built on Docker.Forgejo (with runners)Self-hosted Git and CI.Hermes (with WebUI)An OpenClaw-style virtual assistant, using Codex for inference.TelegramTalk to the agent from the toilet or wherever.Firecrawl (self-hosted)A scraping / translation layer between the agent and the web.Porkbun (Registrar) & Let’s EncryptA domain and on-the-fly SSL certificates.Whatever elsePostgres, Redis, whatever your apps need. It’s just Docker under the hood, innit?<br>Sources<br>This isn’t a full how-to guide. I could probably write an Ansible one-shot script to set it all up; leave an issue on<br>the GitHub repo below if you’d like one. If you’ve read this far, though, you can probably figure it out.<br>SourceNotesCoolify Setup BlogMy Coolify-on-Hetzner setup guide.Coolify DockerfilesProduction Dockerfiles that actually work on Coolify. Just add env vars.Forgejo Hermes SkillA Hermes skill for the Forgejo CLI; just provide a key.<br>Networking<br>The first guardrail is obvious: it’s on its own metal. Hermes could rm -rf / and at worst it would cost me a couple<br>of hours rebuilding it.<br>The next layer of bombproofing is the network. My older server has port 443 forwarded from the router; this one doesn’t.<br>There’s no external ingress, cutting out a huge attack surface and all the internet background radiation from people<br>speculatively probing /wp-admin on every DNS A record I set up.<br>But, if there’s no ingress, how do I:<br>Get access to all our cool new apps on my phone?<br>Generate an SSL cert at a vanity URL so I can access https://cool-new-app.internal.jakeshomelab.me?<br>I have Tailscale set up with my older server as an exit node. When I’m away from home, selecting it routes my traffic<br>through that server and Pi-hole, which I’m using for custom DNS. Pi-hole lets you add dnsmasq rules like this:<br>address=/internal.jakeshomelab.me/192.168.1.201<br>Anything requesting *.internal.jakeshomelab.me now resolves to my new server, where Coolify’s reverse proxy picks it<br>up and serves my shiny new services.<br>SSL Certs<br>With Caddy or Traefik and Docker labels, you can serve port 3000 on container X from<br>https://my-service.internal.jakeshomelab.me. Point an A record at the server and it’ll contact Let’s Encrypt,<br>complete an ACME challenge and get an SSL cert. I learned this three years ago and it...