# Deployment options

Most teams use hosted Telltale and never run a server. If you run the server yourself, it is one Node 24 process with no build step; pick the mode that matches who can reach it.

| Option | Database | Sign-in | Who can reach the dashboard |
| --- | --- | --- | --- |
| Hosted Telltale | Postgres (Supabase), managed for you | Telltale accounts: sign-up, email verification, password reset, OAuth, MFA | Your team, after signing in |
| Local | SQLite in `data/` | None | Only this computer (loopback) |
| Self-hosted, one server | SQLite in `data/` | Password mode: owner, admin and viewer roles | Your team, after signing in |
| Self-hosted, production | Postgres | Password mode or Supabase Auth | Your team, after signing in |

## Hosted Telltale

Telltale runs it for you in the United States (us-east-1), on Postgres with row-level security between workspaces. Add the script tag from Settings › Channels and you are done. See [Data location and retention](/docs/data-retention); the security overview is available on request from jad@heypharos.com.

## Local

```bash
npm start
```

No sign-in, SQLite in `data/`, and the server binds only to loopback (`127.0.0.1`). It refuses to start in this mode if `PUBLIC_ORIGIN` is not a loopback address, so a tunnel or proxy cannot expose a dashboard without sign-in. Good for trying Telltale and for development; not production authentication.

## Self-hosted, one server

```bash
AUTH_MODE=password npm start
```

Create the first owner before you put a reverse proxy in front. Password mode gives you roles, workspaces, hashed passwords, expiring sign-in cookies and invitation links. Back up the whole `data/` directory together: it holds the database and the signing and encryption keys.

## Self-hosted, production

- `STORAGE=postgres` with `DATABASE_URL` (the application role, under row-level security) and `DATABASE_MAINTENANCE_URL` (a separate maintenance role). The two must be different roles.
- `AUTH_MODE=supabase` for people to create their own accounts, or `AUTH_MODE=password`.
- Set `HOST=0.0.0.0` inside a container so the load balancer can reach it, and `PUBLIC_ORIGIN` to your HTTPS address.
- The repository's `Dockerfile` builds the image. Its only runtime dependency is the exact-pinned Postgres driver, installed in the image.

[Server API and recovery](/docs/server) lists every configuration variable.

## Never public

Whatever you choose: the dashboard and admin routes are only reachable after real sign-in, a sign-in-free dashboard is only reachable from the same computer, and server keys stay on your backend. A separate public listener (`EDGE_PORT`) can serve only the collector, SDK, server API and docs paths, never the dashboard.
