# Host ai chat application with Express: Postgres-backed state

## Summary
Deploy an AI chat application built with Express on Ample using the durable job state pattern. Compute runs the app in an isolated microVM behind a public HTTPS URL, with a managed PostgreSQL 16 database auto-provisioned as `DATABASE_URL`. Verified on Express: a jobs table with a state and attempts counter, processing inside a row-locked transaction, and a second run that is a no-op (job=done, attempts=1, idempotent=true).

## Infrastructure requirements
- **Compute**: Verified (Apps run in isolated x86_64 Firecracker microVMs that auto-pause when idle and wake on request; sizes are the priced VM sizes.)
- **Postgres**: Verified (Managed PostgreSQL 16 runs in its own microVM and is auto-provisioned when an app needs a database and no `DATABASE_URL` is supplied.)

## Prerequisites
- A Express project that builds and starts with the documented commands (`npm install`, `npm run build --if-present`, `npm run start` on the node-22 template)
- A PostgreSQL driver reading `DATABASE_URL` at runtime (auto-provisioned when omitted, or supplied with `--env`)
- An Ample account token with `servers:write`, `databases:read`

## Exact tested configuration
- **Template**: `node-22`
- **Runtime**: `node`
- **Size**: `s-1vcpu-1gb`
- **Install**: `npm install`
- **Build**: `npm run build --if-present`
- **Start**: `npm run start`

## Steps
1. **Build and start.** `npm install`, `npm run build --if-present`, `npm run start` on the node-22 template. The server must bind 0.0.0.0 on `PORT`.
2. **Implement the pattern on PostgreSQL.** Implement durable job state: a jobs table with a state and attempts counter, processing inside a row-locked transaction. Copy the approach into your schema; keep migrations idempotent and run them with `--release-command`.
3. **Deploy.** Run the synchronous deploy once and read the result (exit 0 live, 1 failed, 2 blocked).
   
   ```
   ample deploy . --name <app-name> --public
   ```
4. **Verify.** Fetch the live URL and the pattern self-test route(s) (`/p/durable-job-state`) from the example; run your checks. On failure, read `ample logs <deployment_id> --kind build` then `--kind runtime`.
   
   ```
   ample logs <deployment_id> --kind build
   ```

## Tested examples
- **Express pattern fixture**: Multi-pattern Express app whose durable job state module was checked live; the module is under tests/deploy-canaries/_pattern-modules.

## Success checks
- App responds on its public URL (`/` on the live URL).
- Durable job state self-test (`/p/durable-job-state` on the live URL).

## Limitations
- Verified on the node-22 template; other sizes, templates, and Express major versions are not verified.
- The AI chat application behavior is not separately tested; the pattern checks are what was verified.
- Auto-pause and wake on requests; always-on is an operator setting, not a plan feature.

## Cost estimate
Estimated 10.00 USD per month.
- App server x1 `s-1vcpu-1gb`: 5.00 USD
- Managed PostgreSQL database x1 `s-1vcpu-1gb`: 5.00 USD

## Verification evidence
- **Canary run** on 2026-09-21: Express pattern fixture deployed on Ample; checks passed for durable-job-state and configuration-secrets.
- **Canary run** on 2026-09-20: Express app deployed with a `--release-command` migration.

## Execution binding
MCP tool `ample_deploy`, schema hash `876465fce906da0c`, binding state `current`, required scopes: `servers:write`, `databases:read`.
