My coding agent writes the app, writes the tests, and fixes the bug I missed. Then it stops and hands me a list of deploy commands. The most capable collaborator I've ever had turns into an intern who isn't allowed near production. Why is the last mile still mine?
In this post, I'll walk through agentic-hosting, an open-source tool that turns a server you own into a place your AI agent can safely ship apps to on its own. By the end, you'll be able to set it up, let an agent deploy an app and add a database, and drive the whole loop from your agent with simple commands.
⭐ agentic-hosting is open source — star it on GitHub: https://github.com/dennisonbertram/agentic-hosting
🤖 Give this to your agent: point it at https://raw.githubusercontent.com/dennisonbertram/agentic-hosting/main/llms.txt and it can set everything up for you.
I don't think the problem is that agents can't be trusted. It's that hosting was built for humans clicking through dashboards. So when an agent shows up, we give it nothing or everything: no access, or root.
agentic-hosting is a third option. It's a self-hosted PaaS (platform-as-a-service, like a Heroku you run yourself) whose main user is an agent talking to a REST API. There's a dashboard, but it's for you to look over the agent's shoulder.
The idea: a small, safe set of verbs
The README's design principles read like a philosophy of delegation:
- Agentic-first. Agents call the API directly.
- One happy path per primitive. One build system (Nixpacks, which turns source code into a container image with no config), one router (Traefik, a reverse proxy), one engine per database type (Postgres, Redis).
- Multi-tenant. Each agent or team is a tenant, with its own API key, its own resources, and its own rate limits.
- Secure by default. Every container runs under gVisor, a sandbox that intercepts system calls before they reach the host kernel. Root filesystems are read-only, Linux capabilities are dropped, privilege escalation is blocked, and secrets are encrypted with AES-256-GCM.
The second principle is my favorite. For humans, choice is a feature. For agents, choice is surface area for mistakes. With one way to build, route, and provision, an agent can't get creative in ways you'll regret at 2 a.m. You're not building a platform for agents so much as a grammar.
Under the hood it's refreshingly boring: one Go binary, ah, runs as a systemd service on 127.0.0.1:8080. Traefik sits in front on ports 80/443, and two SQLite databases hold state and metering.
Setting it up
You need a Linux server (Ubuntu 22.04+ recommended). The README has the full script; here's the shape.
1. Install the pieces: Docker, gVisor's runsc, Go 1.25, and Nixpacks. Register gVisor as a Docker runtime:
cat > /etc/docker/daemon.json <<'JSON'
{
"runtimes": { "runsc": { "path": "/usr/bin/runsc" } },
"default-address-pools": [{"base":"172.20.0.0/14","size":24}]
}
JSON
systemctl restart docker
2. Start the infrastructure: a traefik-public network, Traefik (copy its docker run command from the README), and a local image registry bound to loopback:
docker network create --driver bridge traefik-public
docker run -d --name paas-registry --restart unless-stopped \
-p 127.0.0.1:5000:5000 \
-v /var/lib/ah/registry:/var/lib/registry \
registry:2
3. Build ah and create its secrets:
git clone https://github.com/dennisonbertram/agentic-hosting /agentic-hosting
cd /agentic-hosting
CGO_ENABLED=1 go build -o bin/ah ./cmd/ah
cp bin/ah /usr/local/bin/ah
mkdir -p /var/lib/ah/builds /var/lib/ah/backups
head -c 32 /dev/urandom | xxd -p -c 64 > /var/lib/ah/master.key
chmod 600 /var/lib/ah/master.key
openssl rand -hex 32 # your bootstrap token
4. Run it: put the token in /etc/default/ah as AH_BOOTSTRAP_TOKEN=..., install deploy/ah.service, and start it:
systemctl daemon-reload && systemctl enable --now ah
curl -H 'X-Forwarded-Proto: https' http://127.0.0.1:8080/v1/system/health
# → {"status":"ok"}
Just kicking the tires? Run locally in dev mode: ./bin/ah --dev --open-registration --port 8080.
Handing the keys to an agent
Now the fun part. Register a tenant — think of it as giving one agent its own apartment in the building:
curl -X POST http://localhost:8080/v1/tenants/register \
-H 'Content-Type: application/json' \
-H 'X-Bootstrap-Token: <bootstrap-token>' \
-d '{"name": "my-agent", "email": "me@example.com"}'
# → {"tenant_id": "ten_...", "api_key": "keyid.secret"}
That key is all the agent needs: Authorization: Bearer <api_key>. Two operator endpoints are worth knowing. POST /v1/system/bootstrap-token/validate with {"token":"…"} returns {"valid":true|false}. POST /v1/tenants/{tenantID}/reactivate restores a suspended tenant and issues a fresh key.
Deploy from git. Create a service (image is required, so the git flow passes the placeholder "pending"), then start a build:
POST /v1/services
{ "name": "my-app", "image": "pending", "port": 3000 }
POST /v1/services/{serviceID}/builds
{ "source_type": "git", "source_url": "https://github.com/org/repo", "source_ref": "main" }
Builds pull from GitHub, GitLab, Bitbucket, sr.ht, and Codeberg over HTTPS. The agent can stream build logs (/builds/{buildID}/logs?follow=true) and runtime logs (/v1/services/{serviceID}/logs?follow=true&tail=100). That matters: an agent that can read its own failure can fix it.
Add a database.
POST /v1/databases
{ "name": "my-db", "type": "postgres" } # or "redis"
GET /v1/databases/{dbID}/connection-string
Wire it in with POST /v1/services/{serviceID}/env. Env vars are encrypted at rest and masked unless you ask for ?reveal=true.
Services live at http://{serviceID}.localhost, or at https://{dns_label}.example.com if you start ah with --base-domain example.com. ah writes Traefik's routing config itself and sets traefik.enable=false on containers, so an image's own labels can't hijack routing.
Even easier: let Claude Code drive
The repo ships a Claude Code skill and slash commands, so nobody writes curl:
mkdir -p ~/.claude/skills/agentic-hosting
cp .claude/skills/agentic-hosting/SKILL.md ~/.claude/skills/agentic-hosting/SKILL.md
cp .claude/commands/ah-*.md ~/.claude/commands/
That gives you six commands:
| Command | What it does |
|---|---|
/ah-register <tenant-name> <email> |
Register a tenant and get an API key |
/ah-deploy <git-url-or-image> <service-name> [port] |
Deploy from a git URL or Docker image |
| `/ah-db <postgres\ | redis> [db-name]` |
/ah-logs <service-name> [build-id] |
Stream runtime logs, or build logs for a build |
/ah-status |
Health, services, databases, circuit breakers |
/ah-snapshot <service-name> [snapshot-name] |
Snapshot a running service |
In practice:
/ah-deploy https://github.com/org/my-app web 3000
/ah-db web postgres
/ah-logs web
/ah-status
The first time I watched the loop — agent writes code, deploys, reads logs, fixes the crash, redeploys — it felt less like using a tool and more like managing someone. (No Claude? The same flows exist as bash scripts in scripts/.)
The guardrails are the product
What makes me comfortable isn't the agent. It's the boring stuff around it:
- A reconciler checks every 30 seconds that what the database thinks is running matches what Docker is actually running.
- A circuit breaker stops restarting a service after 5 crashes in 10 minutes. Resetting it is an explicit API call.
- Disk watermarks warn at 80% and block new deploys, builds, and databases at 90%.
- Rate limits per tenant (100 req/s, burst 200) and globally.
- Idempotency keys (scoped to tenant, method, path, and body, with a 10-minute TTL) mean a retried request doesn't deploy twice.
-
ah backuptakes safe SQLite snapshots and keeps the last 10.
Each one is built for a user who is fast, tireless, and occasionally wrong. That describes an agent. It also describes a junior engineer — and we learned long ago that the answer there isn't withholding access. It's making mistakes cheap.
What this changes
We're moving from operating software to supervising it. The valuable skill is less "do you know the right docker run flags" and more "did you set boundaries so the thing doing the work can't hurt you." Infrastructure becomes management: define the verbs, the limits, and the escape hatches, then get out of the way.
agentic-hosting is an early, opinionated version of that idea. It isn't trying to be Kubernetes. Known gaps include HKDF key separation, billing (metering is query-only today), Prometheus export, and multi-node SQLite.
If you try it:
- Start in
--devmode locally, then move to a real box. - Give each agent its own tenant and key — isolation is the point.
- Install the Claude Code skill; it's the fastest way to feel the loop.
- Read the README's security model before handing over a key.
Wrapping up
We covered why agents need infrastructure built for them, how to set up agentic-hosting on your own server, and how an agent can register, build from git, add a database, and read its own logs — all inside guardrails like sandboxing, circuit breakers, and idempotency keys. The bigger idea: infrastructure is becoming a management problem. You design the boundaries; the agent does the work.
If that resonates:
- ⭐ Star agentic-hosting on GitHub — it genuinely helps other people find it.
- 🤖 Give this to your agent: point it at llms.txt to set everything up, or install the Claude Code skill so it knows how to run things day to day.
- 🚀 Try the quickstart in the README —
--devmode is the fastest way to feel the loop. - 💬 Open an issue with feedback or what you'd want your agent to do next.
I'd love to hear what you build with it.
Top comments (1)
The framing that "the guardrails are the product" really lands. The circuit breaker that stops restarts after 5 crashes in 10 minutes is exactly the kind of boundary agents need — they're fast, tireless, and will happily thrash a box forever if you let them.