---
title: "Deployment Checklist"
description: "The steps from a working local teenybase app to production on your Cloudflare account: wrangler login, secrets, first deploy, appUrl, pre-launch checks."
url: https://teenybase.com/docs/deployment-checklist
last_updated: 2026-10-26
---

> Documentation index: https://teenybase.com/llms.txt lists every teenybase docs page with a link to its Markdown version. All docs in one file: https://teenybase.com/llms-full.txt

# Deployment Checklist

The shortest path from "works locally" to a real production URL.

> **Using a coding agent?** Paste this prompt:
>
> Deploy this teenybase app to my own Cloudflare account using the safest simple path (run the CLI as `npx teenybase`, never `npx teeny`). Give me the exact command order for local verification, `npx wrangler login`, the first `npx teenybase deploy --remote --yes`, the appUrl update, and later secret uploads.

## 1. Make it work locally first

Do not skip this.

```bash
npx teenybase deploy --local --yes
npx teenybase dev
```

Before you deploy, verify at least these:

```bash
curl http://localhost:8787/api/v1/health
```

Then check these in the browser:

- `http://localhost:8787/api/v1/doc/ui`
- your main sign-up flow
- your main login flow
- at least one protected write action

## 2. Log in to Cloudflare

Teenybase deploys to your own Cloudflare account (the Workers free plan is enough to start). Authenticate once:

```bash
npx wrangler login
```

In CI or other non-browser setups, set `CLOUDFLARE_API_TOKEN` (Workers Scripts and D1 edit permissions) and `CLOUDFLARE_ACCOUNT_ID` instead.

## 3. Production secrets

The first remote deploy generates any missing secrets into `.prod.vars` with random values and uploads them with the worker:

- `JWT_SECRET`
- `JWT_SECRET_USERS`
- `ADMIN_JWT_SECRET`
- `ADMIN_SERVICE_TOKEN`
- `POCKET_UI_VIEWER_PASSWORD`
- `POCKET_UI_EDITOR_PASSWORD`

To choose your own values, create `.prod.vars` before the first deploy (for example `cp .dev.vars .prod.vars`, then replace every value with the output of `openssl rand -base64 32`). Never reuse the dev defaults. `.prod.vars` is gitignored; keep it private.

## 4. First remote deploy

Make sure `RESPOND_WITH_ERRORS` is not set to `true` in `.prod.vars` or under `vars` in `wrangler.jsonc`, so failed SQL generation/execution errors do not return raw SQL errors to the caller.

```bash
npx teenybase deploy --remote --yes
```

The first remote deploy creates the D1 database (replacing `TEENY_AUTO_CREATE` in `wrangler.jsonc`; commit that file afterwards), uploads the secrets, deploys the worker and applies the migrations.

## 5. Copy the exact production URL

`deploy --remote` prints the worker URL at the end (`+ Deployed: https://...`) and saves it as `apiRoute` in `infra.jsonc`. Copy that exact URL.

Use that exact URL for:

- your frontend API base URL
- Google OAuth callback/origin setup

Set `appUrl` separately based on where users should land after browser auth and where email links should point to:

- frontend app: set `appUrl` to the frontend's public URL
- backend-only app (no frontend yet): set `appUrl` to your real deployed backend URL

For email verification and password reset, `appUrl` is also the base for the link templates teenybase embeds in outgoing emails (`{appUrl}/reset-password/{token}` and `{appUrl}/verify-email/{token}`). Your frontend hosts those routes. See [Email Verification & Password Reset](https://teenybase.com/docs/guides/email-flows).

## 6. Update `appUrl` and deploy again if needed

If `appUrl` was still set to localhost or a placeholder value, fix it now.

```ts
export default {
  appUrl: 'https://YOUR_REAL_FRONTEND_URL_HERE',
  // rest of config
}
```

Then redeploy:

```bash
npx teenybase deploy --remote --yes
```

## 7. Later secret changes

Changing `.prod.vars` locally does nothing until you upload the new values.

```bash
npx teenybase secrets --remote --upload
```

## 8. Final pre-launch check

Before you hand the URL to users, verify all of these:

- `apiRoute` in `infra.jsonc` is the URL you expect
- `appUrl` matches the real deployed URL
- sign-up works in production
- login works in production
- one protected write action works in production
- if you use Google auth, the provider settings match the deployed URL exactly
- if you send emails, password reset and verification work end to end
- `.prod.vars` contains real secrets, not dev defaults

## 9. Useful production commands

Stream logs from the deployed worker:

```bash
npx teenybase logs
```

Back up the production database:

```bash
npx teenybase backup --remote
```

See the [CLI Reference](https://teenybase.com/docs/reference/cli) for all commands.
