Deployment Checklist

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

Using a coding agent?

1. Make it work locally first

Do not skip this.

bash
teeny deploy --local
bash
npx teeny deploy --local
bash
teeny dev --local
bash
npx teeny dev --local

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. Create production secrets

bash
cp .dev.vars .prod.vars

Then open .prod.vars and replace every value with a strong random string. Generate one per secret with:

bash
openssl rand -base64 32

At minimum, replace all of these:

  • JWT_SECRET
  • JWT_SECRET_USERS
  • ADMIN_JWT_SECRET
  • ADMIN_SERVICE_TOKEN
  • POCKET_UI_VIEWER_PASSWORD
  • POCKET_UI_EDITOR_PASSWORD

3. Create or reuse your Teenybase Cloud account

First time:

bash
teeny register
bash
npx teeny register

Already have an account:

bash
teeny login
bash
npx teeny login

4. First remote deploy

Before deploying, set RESPOND_WITH_ERRORS to false 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
teeny deploy --remote
bash
npx teeny deploy --remote

On the first remote deploy, teenybase also uploads .prod.vars automatically.

5. Copy the exact production URL

bash
teeny status
bash
npx teeny status

Copy the exact URL it prints.

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.

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
teeny deploy --remote
bash
npx teeny deploy --remote

7. Later secret changes

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

bash
teeny secrets --remote --upload
bash
npx teeny secrets --remote --upload

8. Final pre-launch check

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

  • teeny status shows 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

Get the live URL again:

bash
teeny status
bash
npx teeny status

List your deployed apps:

bash
teeny list
bash
npx teeny list

Delete an app you no longer need:

bash
teeny delete my-app
bash
npx teeny delete my-app

If you self-host on your own Cloudflare account

The flow is mostly the same. The main difference is that your wrangler.jsonc points at your own Cloudflare account instead of Teenybase Cloud.

Authenticate with Cloudflare first:

bash
wrangler login

Then use the same deploy command:

bash
teeny deploy --remote
bash
npx teeny deploy --remote