Expand admin panel documentation to detail the transition from live env var reading to one-shot seeding for TTS providers in v3.0.0. Add warnings about the impact of rotating AUTH_SECRET on encrypted admin provider keys and the required manual steps after rotation. docs(migrations): add schema migration history table Document the sequence and purpose of each migration introduced in v3.0.0, clarifying upgrade behavior from v2.2.0 and summarizing schema changes. chore(env): remove commented default TTS model example from .env.example
5.4 KiB
| title |
|---|
| Migrations |
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
This page covers migration behavior for both database schema and storage data in OpenReader.
Startup migration behavior
By default, the shared entrypoint runs migrations automatically before app startup in:
- Docker container startup
pnpm devpnpm start
Startup migration phases:
- DB schema migrations (
pnpm migrate) - Storage/data migration (
pnpm migrate-fs) for legacy filesystem content into S3 + DB rows
:::info In most setups, you do not need to run migration commands manually because startup handles this automatically. :::
Schema history
Migrations are applied in order. All of the following ship in v3.0.0; an instance upgrading from v2.2.0 applies 0001–0004 in a single startup pass.
| Migration | Dialects | What it does |
|---|---|---|
0001_tts_segments |
SQLite + Postgres | Creates the original single-table tts_segments used by server-side TTS segment caching. |
0002_add_segment_key_to_tts_segments |
SQLite + Postgres | Adds the segment_key column to tts_segments for stable locator-independent segment identity. |
0003_tts_segments_v2_split |
SQLite + Postgres | Replaces tts_segments with a normalized two-table model: tts_segment_entries (one row per document segment + locator identity) and tts_segment_variants (one row per settings combination, holding the cached audio key, status, and alignment). Drops the original tts_segments table — no released build (v2.2.0 or earlier) ever populated it, so there is no production data to migrate. |
0004_admin_panel |
SQLite + Postgres | Creates admin_providers (encrypted shared TTS provider rows) and admin_settings (runtime site-feature config), and adds the is_admin column to the user table. Backs the Admin Panel. |
To skip automatic startup migrations:
- Set
RUN_DRIZZLE_MIGRATIONS=false - Set
RUN_FS_MIGRATIONS=false
:::warning If you disable startup migrations, ensure your deployment process runs migrations before serving traffic. :::
Apply migrations
In most cases, you do not need manual migration commands because startup runs migrations automatically.
pnpm migrate applies migrations for one database target:
- Postgres when
POSTGRES_URLis set - SQLite when
POSTGRES_URLis unset
You can always override the target explicitly with --config.
# Run pending migrations for one target:
# - Postgres if POSTGRES_URL is set
# - SQLite if POSTGRES_URL is unset
pnpm migrate
# Run storage migration (filesystem -> S3 + DB)
pnpm migrate-fs
# Dry-run storage migration without uploading/deleting
pnpm migrate-fs:dry-run
# Migrate SQLite
pnpm exec drizzle-kit migrate --config drizzle.config.sqlite.ts
# Migrate Postgres
pnpm exec drizzle-kit migrate --config drizzle.config.pg.ts
Generate migrations
pnpm generate is a two-phase script for contributors and schema changes:
- Better Auth schema generation — runs the Better Auth CLI twice (once for SQLite, once for Postgres) to produce auto-generated Drizzle schema files for auth tables (
user,session,account,verification). - Drizzle migration generation — runs
drizzle-kit generatefor bothdrizzle.config.sqlite.tsanddrizzle.config.pg.ts, producing SQL migration files from all schema files (app + auth).
:::note
Most users do not need to run pnpm generate. Use it when contributing or when you have changed Drizzle schema files and need new migration files.
:::
Schema ownership
Auth tables are owned by Better Auth. Their Drizzle schema definitions are auto-generated and should not be hand-edited:
src/db/schema_auth_sqlite.tssrc/db/schema_auth_postgres.ts
App-specific tables are manually maintained in the standard Drizzle schema files:
src/db/schema_sqlite.tssrc/db/schema_postgres.ts
Both sets of schema files are included in the Drizzle configs, so drizzle-kit generate and drizzle-kit migrate handle all tables together.
When app schema changes (for example tts_segments), keep these in sync:
src/db/schema_sqlite.tssrc/db/schema_postgres.tsdrizzle/sqlite/*.sql+drizzle/sqlite/meta/_journal.jsondrizzle/postgres/*.sql+drizzle/postgres/meta/_journal.json
# Full pipeline: Better Auth CLI + Drizzle generate (both dialects)
pnpm generate
# Generate SQLite migrations only (skips Better Auth CLI)
pnpm exec drizzle-kit generate --config drizzle.config.sqlite.ts
# Generate Postgres migrations only (skips Better Auth CLI)
pnpm exec drizzle-kit generate --config drizzle.config.pg.ts
:::warning
Running drizzle-kit generate directly skips the Better Auth CLI step. If auth schema has changed upstream (e.g. after a Better Auth version bump), run pnpm generate instead to regenerate the auth schema files first.
:::