Skip to content

Deploy to Modal

Deploy the Modal backend first. The Cloudflare Worker forwards work into this backend, so the public URL is not useful until Modal is healthy.

Before You Start

  • Python 3.11+
  • uv
  • a Modal account
  • uv run modal setup
  • a local .env file with INTERNAL_AUTH_SECRET

Repo setup:

cp .env.example .env
# edit .env and set INTERNAL_AUTH_SECRET=<shared-internal-secret>
uv sync --extra dev
source .venv/bin/activate
uv run modal setup

Required Modal Secrets

Create the default Modal secrets before serving or deploying the app:

uv run modal secret create openai-secret OPENAI_API_KEY=<your-openai-key>
uv run modal secret create internal-auth-secret \
  INTERNAL_AUTH_SECRET=<same-value-as-.env>
uv run modal secret create modal-auth-secret \
  SANDBOX_MODAL_TOKEN_ID=<token-id> \
  SANDBOX_MODAL_TOKEN_SECRET=<token-secret>

Optional tracing secret:

uv run modal secret create langsmith-secret \
  LANGSMITH_API_KEY=<your-langsmith-key> \
  LANGSMITH_PROJECT=<your-project>

Local Development

Use this when you want the Worker dev server to call a local Modal dev app:

uv run modal serve -m modal_backend.main

Production Deploy

Use the production deployment entrypoint when you want a hosted Modal backend:

uv run modal deploy -m modal_backend.deploy

Quick Backend Check

Before you move on to Cloudflare, confirm Modal can answer a one-off run:

uv run modal run -m modal_backend.main

Important Notes

  • INTERNAL_AUTH_SECRET must match the Worker secret of the same name.
  • Keep the production Modal URL for the Worker's MODAL_API_BASE_URL.
  • Use modal serve -m modal_backend.main for local development and modal deploy -m modal_backend.deploy for the hosted deployment path.