From fe0fc71e0a7626637eebccb10607ad89e1bb6304 Mon Sep 17 00:00:00 2001 From: merge-check <140916359+agentHits@users.noreply.github.com> Date: Wed, 28 Oct 2026 13:58:31 -0400 Subject: [PATCH] fix(db): share one connection pool across the panel's API routers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Что: - `apps/dokploy/server/db/index.ts` больше не создаёт свой пул postgres.js, а переэкспортирует общий клиент из `@dokploy/server/db`. - Тест `__test__/db/app-db-module.test.ts` проверяет, что оба модуля отдают один и тот же клиент. Зачем: - Роутеры `tag`, `network` и `libsql` брали базу из `@/server/db`. В production этот модуль создавал второй пул до 10 соединений рядом с общим, поэтому панель держала до 20 соединений к Postgres вместо 10. Общий модуль уже кеширует клиент в `globalThis`, чтобы на процесс был один пул. - На изолированном стенде под нагрузкой соединений стало 10 вместо 20, память процессов Postgres снизилась со 107 до 91 МБ. Риски: - Роутеры `tag`, `network` и `libsql` теперь делят пул с остальными; лимит в 10 соединений на процесс тот же, что у остальной панели. Скорость API на стенде не изменилась. Проверки: - Команды и результаты: `vitest run __test__/db/app-db-module.test.ts __test__/tag` проходит, новый тест на коде без правки падает; полный `vitest run`: 4293 прошли, 5 упали в `vector-validate.test.ts` (на Mac Colima не монтирует временную папку `docker run`, без правки так же); `tsc --noEmit` в `apps/dokploy` и `packages/server` без ошибок; `biome check` без замечаний. Стенд: нативный arm64-образ этой ветки против образа `AgentHits-Dev` того же коммита в Docker-in-Docker, сценарий из входа, страниц, нагрузки на API, деплоев, логов, терминалов и 120 одновременных запросов к `tag.all` и `project.all`. - Ограничения: стенд на Mac, а не на сервере. What: - `apps/dokploy/server/db/index.ts` no longer creates its own postgres.js pool; it re-exports the shared client from `@dokploy/server/db`. - The test `__test__/db/app-db-module.test.ts` checks that both modules return the same client. Why: - The `tag`, `network` and `libsql` routers took the database from `@/server/db`. In production that module created a second pool of up to 10 connections next to the shared one, so the panel held up to 20 Postgres connections instead of 10. The shared module already caches the client on `globalThis` to keep one pool per process. - On the isolated bench, connections under load went from 20 to 10 and Postgres process memory from 107 to 91 MB. Risks: - The `tag`, `network` and `libsql` routers now share the pool with the rest; the limit of 10 connections per process is the same as for the rest of the panel. API speed on the bench did not change. Checks: - Commands and results: `vitest run __test__/db/app-db-module.test.ts __test__/tag` passes, the new test fails without the change; full `vitest run`: 4293 passed, 5 failed in `vector-validate.test.ts` (Colima on the Mac does not mount the `docker run` temp folder, same without the change); `tsc --noEmit` in `apps/dokploy` and `packages/server` clean; `biome check` clean. Bench: a native arm64 image of this branch against an `AgentHits-Dev` image of the same commit in Docker-in-Docker, a scenario of sign-in, pages, API load, deploys, logs, terminals and 120 concurrent `tag.all` and `project.all` requests. - Limitations: the bench runs on a Mac, not the server. Co-Authored-By: Claude Opus 5.5 --- .../dokploy/__test__/db/app-db-module.test.ts | 9 ++++ apps/dokploy/server/db/index.ts | 41 ++----------------- 2 files changed, 12 insertions(+), 38 deletions(-) create mode 100644 apps/dokploy/__test__/db/app-db-module.test.ts diff --git a/apps/dokploy/__test__/db/app-db-module.test.ts b/apps/dokploy/__test__/db/app-db-module.test.ts new file mode 100644 index 00000000000..6de2696dfb2 --- /dev/null +++ b/apps/dokploy/__test__/db/app-db-module.test.ts @@ -0,0 +1,9 @@ +import { db as sharedDb } from "@dokploy/server/db"; +import { describe, expect, it } from "vitest"; +import { db } from "@/server/db"; + +describe("@/server/db", () => { + it("reuses the shared client instead of opening a second pool", () => { + expect(db).toBe(sharedDb); + }); +}); diff --git a/apps/dokploy/server/db/index.ts b/apps/dokploy/server/db/index.ts index afc10bedf97..01848593548 100644 --- a/apps/dokploy/server/db/index.ts +++ b/apps/dokploy/server/db/index.ts @@ -1,38 +1,3 @@ -import { dbUrl } from "@dokploy/server/db/constants"; -import * as schema from "@dokploy/server/db/schema"; -import { and, eq } from "drizzle-orm"; -import { drizzle, type PostgresJsDatabase } from "drizzle-orm/postgres-js"; -import postgres from "postgres"; - -export { and, eq }; - -type Database = PostgresJsDatabase; -/** - * Evita problemas de redeclaración global en monorepos. - * No usamos `declare global`. - */ -const globalForDb = globalThis as unknown as { - db?: Database; -}; - -let dbConnection: Database; - -if (process.env.NODE_ENV === "production") { - // En producción no usamos global cache - dbConnection = drizzle(postgres(dbUrl), { - schema, - }); -} else { - // En desarrollo reutilizamos conexión para evitar múltiples conexiones - if (!globalForDb.db) { - globalForDb.db = drizzle(postgres(dbUrl), { - schema, - }); - } - - dbConnection = globalForDb.db; -} - -export const db: Database = dbConnection; - -export { dbUrl }; +// A pool of its own here gave the panel a second set of up to 10 Postgres +// connections; the shared module keeps one pool per process. +export { and, db, dbUrl, eq } from "@dokploy/server/db";