Skip to content

How to put an AI-built app into production

An AI-built app that works on your machine is not deployed. The checklist that carries it from repository to a production deployment that survives its first real user, in order, with the parts people skip.

A paper plane folded from a printed worksheet lifting off a desk toward an open window, one vermilion fold along its spine.

By Sam Moreton

First-hand + researched

AI coding tools have solved an astonishing slice of the work of building software: describe the thing, get the thing, iterate until it runs. What they have not solved, because it is not a coding problem, is everything that happens between "it works on my machine" and "real people are using it and I am not watching a dashboard at dinner".

That gap is where AI-built apps go to die. Not from bugs; the code is usually fine. From the deployment layer nobody prompted anyone about.

This is the checklist. It is ordered, the order matters, and the commentary names the parts people skip.

Step one: run the production start command, locally

The single highest-value ten minutes in this entire process. The application has only ever been started in dev mode. Dev mode forgives: it hot-reloads, it serves unoptimised assets, it papers over build errors. Production mode compiles everything, enforces environment discipline, and fails loudly.

Run the production build and the production start command on your own machine before anything else. Whatever breaks there breaks on the platform too, where you will pay in money and confusion instead of ten local minutes. Fix it now, while the feedback loop is you.

Step two: version control everything, if you have not

If the app lives in a folder with "final" and "final-2" in the name, fix that first. A repository, pushed somewhere safe, is the difference between a deployment pipeline and a ritual of copying folders. It also becomes the trigger for deploys later: push, platform builds, platform runs. The machine that built the app should be optional to its operation.

Step three: treat every secret as already burned

An AI-built app has almost certainly walked your API keys through a chat transcript and a .env file that came perilously close to being committed. The keys that touched any of that are burned. Rotate them: new keys from each provider, old ones revoked, before the first deploy and ideally today.

Then set the replacements as environment variables on the platform, per environment, never in the repository. A canary value in the variable slot proves the plumbing before the real keys arrive. Secrets in build logs count as leaks; check the platform keeps them out.

Step four: the real database

The local SQLite file or the localhost Postgres was scaffolding. Real deployment means a provisioned database, migrations run in order against a fresh copy, and the connection string living in the environment, not in a config file that once lived on your laptop.

Two things people learn the hard way: run migrations as a deployment step, not a formality you hope happened; and establish where state lives. Uploads in a public folder and files written to disk are state, and a rebuild or a second server will orphan all of it. Managed database plus object storage for files makes the compute box disposable, which is the property that makes everything else here survivable.

Step five: domain, DNS and TLS

Point the domain at the platform, let the certificate issue automatically, and accept that DNS propagation takes as long as it takes. Verify the site on the real domain before announcing anything; subtle things, cookies, redirects, OAuth callbacks, only reveal their opinions at this stage. This step is mechanical. Do it calmly, in order, and it stays boring.

Step six: logs that survive the crash

If the only place to see what happened is the terminal you closed, your first production incident will begin with "where do the logs go". Fix that in advance: platform logs that persist restarts, searchable, without SSH. While you are there, confirm what happens when the process crashes. Something should restart it automatically and tell you it happened. If the answer is "nothing restarts it", you have found your next task.

Step seven: backups and the restore you have actually run

Automated backups on the database, a manual backup button for before risky changes, and one restore performed by your own hands before you need one for real. A backup nobody has restored is a hope, and the first real incident is a bad time to learn the restore interface.

Step eight: the security pass AI apps specifically need

Three misses, in order of frequency: debug endpoints left enabled because they were convenient during development; default credentials on admin paths; and keys baked into the client bundle that were meant for the server. All three are findable in ten minutes with a scan of the repository and a look at the built output. Ten minutes now.

What breaks first under real load

With all of the above done, the app will still meet its first real users and discover physics. The usual first bottlenecks, in order: the database connection pool, which was sized for one developer; background work that assumed nobody would click twice; and caching that was never added because locally everything was instant. None of these are emergencies; all of them are normal. Watch the logs, fix the top one, repeat. An architecture that can be scaled or split later is worth more at this stage than one that is theoretically perfect now.

Choosing where it runs

This checklist is deliberately platform-neutral, because the hosting decision deserves its own diagnosis rather than a default. That diagnosis, what your app's shape says about the kind of hosting it needs, is the companion piece: where should an AI-built app be hosted. Run it after step three and you will pick with evidence instead of momentum.