Skip to content
AppHaven.

Guide

How to deploy an AI-built app

Your app works on your laptop. Now give it a home where colleagues can use it, records survive updates, and you can see what went wrong when a release fails.

Short answer

Package the app for its production runtime, configure secrets and persistent storage, then deploy a test environment. Check login, saved records and a redeploy before releasing to users. Confirm who owns backups and recovery before the app holds live business data.

Choose what the platform should operate

A virtual server gives you control but leaves server patching, database operation and recovery setup with you. A managed application platform such as Render handles service infrastructure; Railway lets you compose services with explicit database responsibilities. Vercel is worth evaluating for a frontend-centric workload.

AppHaven is designed to run AI-built business applications with a managed database, private access and production backups around them. The walkthrough below uses AppHaven and a Node.js invoice tracker. The persistence, permissions and release checks apply on other hosts too.

Start with a working app

The example is an invoice tracker built with Node.js. It already has a screen for creating invoices, a database connection read from DATABASE_URL, and an npm start command. The same steps apply to other business apps; substitute their build and start commands.

You need Git, Docker for the local build check, and an AppHaven account. Your app must listen on 0.0.0.0:3000 and use PostgreSQL for this database example. If it currently uses SQLite, changing the connection string is not a conversion: ask your agent to adapt the database layer and migrations first.

Package the app

Dockerfile

FROM node:22-bookworm-slim
WORKDIR /app
ENV NODE_ENV=production
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
USER node
EXPOSE 3000
CMD ["npm", "start"]

For a JavaScript app that runs directly with npm start. TypeScript and frameworks with a build step need a build stage and their production start command. Commit package-lock.json before building.

.dockerignore

node_modules
.git
.env
.env.*
*.log
backups
exports
*.dump

Store database exports under backups/ or exports/ so they stay out of the image. Keep SQL migration files in the build. Add any other private files your repository uses to this list.

Local build check

docker build -t invoice-tracker .

A successful build checks packaging. The app still needs its database and runtime settings before it can serve requests.

Declare the app and its database

apphaven.yaml

services:
  web:
    type: container
    build:
      dockerfile: Dockerfile
    ports:
      - 3000
    env:
      DATABASE_URL: ${service.db.url}
    depends_on:
      - service: db
        condition: healthy

  db:
    type: postgres
    version: "17"

The database service supplies DATABASE_URL at runtime. Do not paste a real database password into this file.

Make the first database setup explicit

Your application needs tables as well as a connection. Use its migration tool to create the schema, and document the command in the repository. For example, an existing npm run migrate script can run before the web process starts. Confirm the script is safe to run again and that a failure stops startup; do not add a script name that your project does not implement.

For this first deployment, use an empty database and synthetic invoices. Existing production data needs a separate import and verification step. The database guide covers data changes and recovery.

Connect and deploy a preview

  1. Commit a setup branch

    Commit the Dockerfile, .dockerignore, manifest and migration changes on a branch such as deploy-setup. Keep it separate from main.

  2. Create the app

    In your AppHaven project, create an application and choose its region. In Source, connect the repository and select main as the production branch.

  3. Add runtime settings

    In Settings, add the application’s base URL and other plain settings as Variables. Add API keys as Secrets. Use sandbox keys for external services while testing; a separate database does not stop a preview from sending a real email or charging a card.

  4. Deploy deploy-setup

    Choose the setup branch in Deploy. Follow the build log, then open the preview URL when the deployment is Running. Keep access private. The console walkthrough shows these controls.

Check the result before releasing

Check Expected result
Open the URL in a signed-out browser The AppHaven login appears before the private app.
Create an invoice labelled TEST-001 It appears in the app with the amount you entered.
Deploy the same preview branch again TEST-001 is still present after startup.
Try an invalid amount or missing customer The app rejects the input without saving a broken invoice.
Read the application log No database credentials, API keys or invoice contents are printed.

Release it to your team

Merge the reviewed setup into your production branch and deploy that branch. Production has its own database: run the schema migrations there and check the app again. Preview records are test data, not an import into production.

Invite a colleague through the project’s Members page. In Backups, check the production restore window and choose the retention you need. AppHaven handles backup capture; restoration currently goes through support. Keep the app and deployment names in your release notes so you can request help quickly.

If the deployment fails

What you see What to check first
The image fails to build Read the first meaningful build error. Check the lockfile, build command and files excluded by .dockerignore.
The process starts and exits Read crash output. Check required settings and migration errors.
Running, but the page will not open Check that the process listens on 0.0.0.0 and that its port matches the manifest.
Tables are missing Check that the migration ran against this deployment’s database, not the one on your laptop.
Data disappears after an update Check that the app uses the managed database, rather than a local file or an in-memory development store.

Common questions

Can I deploy a Python or Go app?

Yes. Use a Dockerfile that builds and starts that application. The database declaration and preview workflow follow the same pattern.

Will every push go live?

Production deploys from the branch you selected. With auto-deploy enabled, a push to that branch can release immediately. Require reviewed pull requests in your Git host if you want approval before release.

Put your first app on AppHaven

Try the walkthrough in a private AppHaven preview, using test records before your first production release.