
Openship 数据库层完整解析Drizzle ORM 与 Postgres/PGlite 内嵌数据库迁移指南【免费下载链接】openshipSelf-hosted deployment platform项目地址: https://gitcode.com/GitHub_Trending/ope/openshipOpenship是一款自托管部署平台Self-hosted Deployment Platform而支撑它的全部数据能力就是位于 packages/db/ 下的数据库层。这一层以Drizzle ORM为核心同时支持两种数据库驱动生产级的Postgres以及零配置即可运行的PGlite 内嵌数据库WASM 版 PostgreSQL无需安装任何服务。所有数据库迁移Migration在应用启动时自动执行迁移链已从0000一路演进到0116。本文将带你快速看懂驱动如何选择、迁移链如何自动运行、PGlite 如何避免数据损坏以及数据导出恢复怎么做。一图看懂为什么部署平台需要「双驱动」数据库层上面就是 Openship 的控制台界面。界面上的每一个项目、部署记录、域名、服务器和通知背后都对应数据库中的一张表。Openship 的数据库层解决了一个典型矛盾开发者体验希望clone仓库就能跑起来不想先装 Docker 和 Postgres生产部署希望用标准的 Postgres获得并发、备份和运维工具链的完整能力。解决方案就是一套接口两种驱动场景驱动数据存放位置生产 / Docker 自托管node-postgres 连接真实 Postgres你的 Postgres 服务本地开发 / 桌面端PGlite 内嵌数据库默认~/.openship/data可用PGLITE_DATA_DIR指定选择逻辑很简单配置了DATABASE_URL或POSTGRES_HOST/POSTGRES_PASSWORD等变量就连 Postgres否则自动降级为 PGlite真正做到零配置启动。统一接口上层代码不关心底层是哪个数据库数据库客户端的工厂逻辑集中在 client.ts 中postgresql://开头的连接串 → 创建node-postgres 连接池 Drizzle实例连接池上限 20见 client.ts空或未配置 → 创建PGlite 内嵌数据库实例。两种驱动最终都归一为同一个Database类型所有仓库层Repo和服务拿到的是同一个接口完全不知道底层跑的是哪种数据库。这也是 Drizzle ORM 的价值类型安全 一套查询语法覆盖两种后端。 小细节测试环境下VITESTPGlite 会自动切换到内存模式memory://保证测试永不污染磁盘上的开发数据——见 client.ts。迁移链解析从 0000 到 0116 的自动演进Openship 的迁移文件全部存放在 packages/db/drizzle/ 目录目前已积累117 个迁移 SQL 文件起点0000_init.sql —— 初始建表近期演进示例0084_analytics_daily_rollup.sql分析日汇总、0108_credential.sql凭据表、0116_domain_ssl_challenge.sql域名 SSL 验证。迁移如何自动运行无论使用哪种驱动应用启动时都会调用 Drizzle 的migrate()把packages/db/drizzle/目录里尚未执行的迁移按顺序、每条一个事务地应用完——见 client.tsPostgres 驱动与 client.tsPGlite 驱动。开发者的日常工作流只需三步修改表定义packages/db/src/schema/下对应文件运行db:generate脚本基于 drizzle-kit配置见 drizzle.config.ts生成新的迁移 SQL提交迁移文件重启应用——迁移自动完成。⚠️ 特别提醒迁移目录通过OPENSHIP_MIGRATIONS_DIR环境变量可被重定向。桌面端 App 是bun build --compile编译的单体二进制SQL 文件不在文件系统里而是作为数据资源随二进制一起发布这个变量就是为它准备的。领域化 Schema49 个文件一个业务域一个表集合表定义不是一团乱麻而是按业务域拆分成 packages/db/src/schema/ 下的近 50 个文件并在 index.ts 统一导出部署核心project.ts、deployment.ts、service.ts网络与边缘domain.ts、route-rule.ts、edge-target-verification.ts基础设施servers.ts、server-container-status.ts、server-tunnel.ts商业化billing.ts、oauth.ts运维backup.ts、notification.ts、service-incident.ts以 deployment.ts 为例可以看到典型的 Drizzle 写法text主键带dep_前缀、外键引用 project 和 organization 并配置级联删除onDelete: cascade、trigger字段记录部署由 webhook 还是回滚触发。所有字段都有清晰的注释文档读 Schema 就像读 API 文档。所有数据库访问都被收口到仓库层Repos——见 packages/db/src/index.ts 的导出注释“所有 DB 访问都经过这里”。业务代码不直接拼查询而是调用createProjectRepo、createDeploymentRepo等工厂这是全项目可测试性的关键。避坑指南PGlite 单进程锁与 Postgres 启动等待内嵌数据库最大的风险是两个进程同时打开同一份数据导致不可逆损坏。Openship 在这里做了两重工程保障① PGlite 单实例文件锁— 实现见 pglite-lock.ts用原子创建O_EXCL在数据目录旁生成dir.lock锁文件保证同一时刻只有一个进程持有数据目录锁内记录操作系统级的机器标识machine-id / MachineGuid区分「本机崩溃残留」和「另一台机器占用」崩溃自愈发现前一个进程已死亡死 PID立即回收锁SIGKILL不会把目录锁死锁文件刻意放在数据目录外部因为 PGlite 首次初始化拒绝非空目录。热重载场景下新进程会最多等待 30 秒让旧进程优雅释放数据库避免开发时反复出现 “already using the database” 报错。② Postgres 就绪等待— 实现见 client.ts启动时最多等待90 秒每 1 秒重试一次覆盖宿主重启后 Postgres 崩溃恢复的慢启动致命错误立即失败而非空等28P01/28000密码错误通常是.env与数据卷不匹配和3D000数据库不存在会立刻抛出可读的错误帮你省下几十分钟排查时间连接池挂载了空闲连接错误监听Postgres 重启不会让整个 API 进程崩溃退出。 配套工具package.json提供了db:heal-pglite、db:heal-orphans等自愈脚本入口在 scripts/heal-pglite.ts遇到极端异常时有标准修复手段。数据层能力延伸导出、恢复与跨实例迁移除了 CRUDpackages/db/ 还内置了一套结构化备份体系核心在 dump.tsdumpDatabase/restoreDatabase整库按拓扑顺序导出与恢复dumpSubgraph/restoreSubgraph项目级子图导出——把单个项目及其关联数据打包带走用于团队模式迁移和项目转让敏感字段自动处理加密列ENCRYPTED_COLUMNS在导出时剥离防止密钥材料泄露到备份文件。命令行入口同样齐备db:dump与db:restore两个脚本scripts/dump.ts / scripts/restore.ts配合桌面端发布打包让「把数据从一台自托管服务器搬到另一台」成为一条命令的事。快速上手5 分钟认识 Openship 数据库层如果你想动手体验先获取代码git clone https://gitcode.com/GitHub_Trending/ope/openship然后按场景二选一零配置模式什么都不配直接启动 API——PGlite 会在~/.openship/data自动建库并跑完全部 117 条迁移Postgres 模式设置DATABASE_URL或直接复用 docker-compose 中的POSTGRES_HOST/POSTGRES_PASSWORD变量名启动时自动连池并执行迁移。 关键文件地图驱动选择与启动等待packages/db/src/client.tsPGlite 单实例锁packages/db/src/pglite-lock.tsPostgres 咨询锁跨进程串行化packages/db/src/advisory-lock.ts迁移 SQL 目录packages/db/drizzle/迁移生成配置packages/db/drizzle.config.ts仓库层出口packages/db/src/repos/总结Openship 的数据库层是一套教科书级的自托管工程实践Drizzle ORM提供类型安全的统一接口Postgres 与 PGlite 双驱动兼顾生产严谨与开发零门槛自动迁移链让 schema 演进零手工干预而单实例锁、启动等待与结构化备份则把内嵌数据库最常见的坑提前堵死。理解了这一层你就掌握了 Openship 所有项目、部署与计费数据的底层脉络。【免费下载链接】openshipSelf-hosted deployment platform项目地址: https://gitcode.com/GitHub_Trending/ope/openship创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考