Skip to main content

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

agent writes code on a branch
push
preview deploymentits own URL, database, and storage
you click around, read logs, check the result
merge to the production branch
auto-deploy, or one click
production

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.

tip

With Agent integration set up, the agent can also check its own work from the terminal: deployment status, build logs, and container output, all read-only.

Set the repository up so agents succeed

Agents do best when the contract is explicit and checkable. For AppHaven the contract is small:

  • A Dockerfile that builds the app. This is the whole build pipeline. If docker build works, AppHaven's build works.
  • apphaven.yaml committed 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.
- To ship: push a branch and deploy it as a preview. main auto-deploys to
production after merge. Keep schema migrations backward compatible.

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.

When an agent ships a bad change

The recovery moves, from mildest to strongest:

  1. 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.
  2. 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.
  3. 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