Building with AI agents
A growing share of the apps on AppHaven are written with, or largely by, AI coding agents. The platform is shaped for that way of working: agents ship through Git, every branch can run as a live preview with its own data, and when a change turns out to be wrong, both the code and the data can be walked back. This guide is the working rhythm that makes agent-built apps safe to run in production.
The workflow: preview first, promote explicitly
The load-bearing property is that a preview is a full, isolated environment: its own machine, its own database, its own volumes. An agent can iterate as fast as it likes on a branch (deploy, break, fix, redeploy) and none of it can read or touch production data. Production only changes when the production branch does, and that merge is the human checkpoint.
Turn on auto-deploy for the production branch and the promotion step becomes the merge itself: the agent's work goes live exactly when a person accepts it, never before.
With Agent integration set up, the agent can also check its own work from the terminal: deployment status, build logs, and container output, plus configuration proposals for human review.
Set the repository up so agents succeed
Agents do best when the contract is explicit and checkable. For AppHaven the contract is small:
- A
Dockerfilethat builds the app. This is the whole build pipeline. Ifdocker buildworks, AppHaven's build works. apphaven.yamlcommitted at the repository root. The manifest is strictly validated, so a manifest the agent breaks fails fast with a named error rather than half-deploying.- Configuration from environment variables, with the database URL taken
from
${service.db.url}. Never a hardcoded connection string, never credentials in the repo. - Listen on the declared port; write only to volume mount paths. Anything written elsewhere is gone on the next deploy. That is the correct default for code an agent regenerates freely.
- A healthcheck, so a deploy can wait for dependencies and a broken service is visibly unhealthy instead of quietly wrong.
It pays to state this in the instructions file your agent reads
(CLAUDE.md, AGENTS.md, or equivalent):
## Deployment (AppHaven)
- This app deploys on AppHaven from this repo. The Dockerfile must always build.
- `apphaven.yaml` declares the services; edit it when adding a service,
volume, or env var. Docs: https://docs.apphaven.eu/manifest
- Read all config from env vars. The database URL is provided as DATABASE_URL.
- Persist files only under the volume mount paths declared in apphaven.yaml.
- Never commit secrets; they are set in the AppHaven console.
- The app is private: every request needs a login. A path that must answer
without one needs a public_path.add proposal with a reason. An administrator
approves in the console; it takes effect on the next deployment.
- To ship: push a branch and deploy it as a preview. main auto-deploys to
production after merge. Keep schema migrations backward compatible.
Suggesting a public path
An agent can propose public_path.add for a webhook or API that needs to bypass the AppHaven login.
It submits a CLI batch with a reason and opens a review page. A project administrator approves or
declines that item in the app's Proposals section. Recommendations that should travel with the
repo go in apphaven.yaml under proposals, with stable IDs. They appear only after reaching the
configured production branch. See Change proposals for examples and retry handling.
Approval saves configuration; the exemption takes effect on each branch's next deployment. The
endpoint must authenticate its own callers, such as by validating webhook signatures. Until approval
and deployment, an AppHaven login redirect is expected. Agents can read the decision with
apphaven proposals show <app> <proposal-id> --json and must respect declined items.
Migration safety
Database migrations are where agent speed meets real risk, because a schema change is the one thing a redeploy doesn't undo. Three habits keep them boring:
Run the migration on a preview first. A preview has its own database, so the migration executes for real (syntax, locks, data transforms) with zero exposure. An agent that ships a migration should always ship it through a preview deploy.
Prefer expand–contract over in-place change. Add the new column, write to
both, backfill, switch reads, and only later remove the old column, with each
step deployable and reversible on its own. The dangerous shapes are the
one-shot ones: DROP COLUMN, destructive UPDATEs, renames that strand the
previous version of the code. If a step can't be undone by deploying the
previous commit, it deserves a human's eyes before it reaches production.
Lean on point-in-time recovery as the backstop. The production database is captured continuously: if a bad migration does land, the database can be restored to the moment before it ran. Every deployment records its commit and time, so "the moment before" is never a guess.
Keeping dependencies patched
Dependency upgrades are exactly the kind of small, verifiable work an agent is good at, and AppHaven hands it the list. Every build is checked against published vulnerabilities, and your production deployment is re-checked nightly, so the queue of "what needs raising" is always current. See Vulnerability management.
With the CLI set up, an agent can run the whole loop itself: apphaven vulns <app> gives it the package, the version you run, and the version that fixes
each finding; it raises the versions and pushes; the preview build reports back
whether the findings cleared and whether the app still works. Review the diff
and the preview as you would any other change, then merge.
Two things keep this safe by construction. The agent cannot deploy, so nothing reaches production without your merge, and an upgrade that breaks the app breaks a preview, on its own machine with its own database.
When an agent ships a bad change
The recovery moves, from mildest to strongest:
- Bad code, data fine: revert the commit on the production branch and deploy. Rollback deploys are fast because the previous commit's image is reused.
- Crashed on arrival: the deployment is marked Failed, the failed containers' output is kept for inspection, and your data is untouched. Fix forward or revert.
- Bad data, from a migration or a runaway write: restore the database to a point in time just before the deploy, revert the code, deploy. See Backups & recovery.
The common thread: because deployments record commits and data has history, an agent's mistake is a state to return from, not an incident to reconstruct.
Reviewing what an agent did
Everything an agent ships is inspectable in the console without touching a terminal: the Builds tab holds every build log, each deployment lists its exact commit, each container exposes its console output, and the activity timeline shows who deployed what, when. Review the preview URL for behaviour and the console for evidence, then merge.
Where to go next
- Agent integration: give the agent CLI access and the proposal workflow to status, builds, and logs.
- Getting started: the first deploy, end to end.
- What happens when you deploy: the lifecycle an agent rides.
- Backups & recovery: the safety net under all of it.