feat(deploy): migrations 嵌入二进制,实现真单文件部署

- embed-migrations.ts:扫 ./drizzle/meta/_journal.json,生成 src/server/db/migrations.gen.ts,每条 SQL 通过 `import sql_<idx> from '../../../drizzle/<tag>.sql' with { type: 'text' }` 在 bun build --compile 时被静态嵌入二进制
- migrate.ts 重写:runtime 用 createHash('sha256') 计算迁移哈希,仅用 db.execute(sql) + db.transaction() 公开 API 写入 drizzle.__drizzle_migrations 簿记表(不依赖 @internal 的 db.dialect/db.session)
- db:generate 链 db:embed,保证 SQL 改动总是同步到 migrations.gen.ts
- Dockerfile 删 COPY drizzle/,binary 是部署唯一 artifact
- 同步 README / AGENTS / biome.json
This commit is contained in:
2026-04-25 14:05:58 +08:00
parent e28fe9dc7b
commit 7e27640a26
13 changed files with 200 additions and 33 deletions
+7 -6
View File
@@ -27,8 +27,9 @@ RPC endpoint: `/api/rpc` · OpenAPI docs: `/api/docs` · Spec: `/api/spec.json`
| `bun run test` | `bun test` (colocated `*.test.ts`) |
| `bun run fix` | Biome lint + format + organize imports |
| `bun run db:push` | Dev-only schema sync (no migration files) |
| `bun run db:generate` | Write SQL migrations to `./drizzle` |
| `bun run db:migrate` | Apply migrations locally via drizzle-kit |
| `bun run db:generate` | Write SQL migrations to `./drizzle` and regenerate `migrations.gen.ts` |
| `bun run db:embed` | Regenerate `src/server/db/migrations.gen.ts` from `./drizzle` (run if you hand-edit migrations) |
| `bun run db:migrate` | Apply migrations locally via drizzle-kit (dev convenience) |
| `bun run db:studio` | Drizzle Studio |
Cross-compile: `bun run compile:{linux,darwin,windows}[:arch]`.
@@ -45,18 +46,18 @@ Contract-first, additive. Create or touch files in this order:
6. `src/server/api/routers/index.ts` — add `post` to the `router` object.
7. `src/client/queries/post.ts` — export `useInvalidatePosts` (or finer-grained helpers) for affected list keys.
8. `src/routes/<page>.tsx` — UI with `useSuspenseQuery` + loader `ensureQueryData`; call the helper from mutation `onSuccess`.
9. `bun run db:generate` — emit SQL migrations to `./drizzle`.
9. `bun run db:generate` — emit SQL migrations to `./drizzle` and embed them into `src/server/db/migrations.gen.ts`.
## Deploy
Always **migrate-then-serve**. Migrations are an explicit deploy step, never a server startup hook.
Always **migrate-then-serve**. Migrations are embedded in the binary; the binary is the only artifact you ship.
```bash
./server migrate # applies ./drizzle against $DATABASE_URL
./server migrate # applies embedded migrations against $DATABASE_URL
./server # starts HTTP server (default subcommand)
```
`Dockerfile` copies `./drizzle/` next to the binary. `compose.yaml` models the pattern with a one-shot `migrate` service that `app` depends on (`service_completed_successfully`). On Kubernetes: run `./server migrate` as an initContainer or Helm `pre-upgrade` Job.
`compose.yaml` models the pattern with a one-shot `migrate` service that `app` depends on (`service_completed_successfully`). On Kubernetes: run `./server migrate` as an initContainer or Helm `pre-upgrade` Job.
```bash
docker compose up --build