History

refactor(queues): migrate from BullMQ to p-limit for deployment management

This commit introduces a new queue system using p-limit, addressing resource issues and improving job cancellation capabilities. Key changes include: - Removal of Redis dependency, allowing for in-memory queue management. - Implementation of per-server queues with ordered processing based on server concurrency settings. - Addition of helper functions for job management and status retrieval, ensuring backward compatibility with existing API endpoints. - Updates to database schema to support server concurrency settings. The legacy BullMQ code has been retained for compatibility but is no longer in active use.

Mauricio Siu committed 1 year ago

Commit 2da2b2d1 parent 7273c6314 files · +7217 −174Browse files

Unified · Split

14 files
  1. apps/dokploy/components/dashboard/application/general/show.tsx +1 −1
  2. apps/dokploy/drizzle/0107_calm_power_pack.sql +2 −0
  3. apps/dokploy/drizzle/meta/0107_snapshot.json +6438 −0
  4. apps/dokploy/drizzle/meta/_journal.json +7 −0
  5. apps/dokploy/package.json +1 −1
  6. apps/dokploy/server/api/routers/application.ts +6 −9
  7. apps/dokploy/server/queues/README.md +104 −0
  8. apps/dokploy/server/queues/deployments-queue.ts +54 −118
  9. apps/dokploy/server/queues/queueSetup.ts +91 −34
  10. apps/dokploy/server/queues/redis-connection.ts +0 −8
  11. apps/dokploy/server/queues/service-queue.ts +500 −0
  12. packages/server/src/db/schema/server.ts +1 −0
  13. packages/server/src/db/schema/user.ts +1 −0
  14. pnpm-lock.yaml +11 −3
apps/dokploy/components/dashboard/application/general/show.tsx+1−1
@@ -79,7 +79,7 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => { · 78 unmodified lines
7979 >
8080 <Button
8181 variant="default"
82− isLoading={data?.applicationStatus === "running"}
82+ // isLoading={data?.applicationStatus === "running"}
8383 className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
8484 >
8585 <Tooltip>
apps/dokploy/drizzle/0107_calm_power_pack.sql+2−0
@@ -0,0 +1,2 @@
1+ALTER TABLE "user_temp" ADD COLUMN "serverConcurrency" integer DEFAULT 1 NOT NULL;--> statement-breakpoint
2+ALTER TABLE "server" ADD COLUMN "concurrency" integer DEFAULT 1 NOT NULL;
apps/dokploy/drizzle/meta/0107_snapshot.json+6438−0
@@ -0,0 +1,6438 @@
1+{
2+ "id": "c1520c6a-965f-4977-9e0e-ec8e402af35c",
3+ "prevId": "5568024c-5daa-4554-a224-8a005a53f97c",
4+ "version": "7",
5+ "dialect": "postgresql",
6+ "tables": {
7+ "public.account": {
8+ "name": "account",
9+ "schema": "",
10+ "columns": {
11+ "id": {
12+ "name": "id",
13+ "type": "text",
14+ "primaryKey": true,
15+ "notNull": true
16+ },
17+ "account_id": {
18+ "name": "account_id",
19+ "type": "text",
20+ "primaryKey": false,
21+ "notNull": true
22+ },
23+ "provider_id": {
24+ "name": "provider_id",
25+ "type": "text",
26+ "primaryKey": false,
27+ "notNull": true
28+ },
29+ "user_id": {
30+ "name": "user_id",
31+ "type": "text",
32+ "primaryKey": false,
33+ "notNull": true
34+ },
35+ "access_token": {
36+ "name": "access_token",
37+ "type": "text",
38+ "primaryKey": false,
39+ "notNull": false
40+ },
41+ "refresh_token": {
42+ "name": "refresh_token",
43+ "type": "text",
44+ "primaryKey": false,
45+ "notNull": false
46+ },
47+ "id_token": {
48+ "name": "id_token",
49+ "type": "text",
50+ "primaryKey": false,
51+ "notNull": false
52+ },
53+ "access_token_expires_at": {
54+ "name": "access_token_expires_at",
55+ "type": "timestamp",
56+ "primaryKey": false,
57+ "notNull": false
58+ },
59+ "refresh_token_expires_at": {
60+ "name": "refresh_token_expires_at",
61+ "type": "timestamp",
62+ "primaryKey": false,
63+ "notNull": false
64+ },
65+ "scope": {
66+ "name": "scope",
67+ "type": "text",
68+ "primaryKey": false,
69+ "notNull": false
70+ },
71+ "password": {
72+ "name": "password",
73+ "type": "text",
74+ "primaryKey": false,
75+ "notNull": false
76+ },
77+ "is2FAEnabled": {
78+ "name": "is2FAEnabled",
79+ "type": "boolean",
80+ "primaryKey": false,
81+ "notNull": true,
82+ "default": false
83+ },
84+ "created_at": {
85+ "name": "created_at",
86+ "type": "timestamp",
87+ "primaryKey": false,
88+ "notNull": true
89+ },
90+ "updated_at": {
91+ "name": "updated_at",
92+ "type": "timestamp",
93+ "primaryKey": false,
94+ "notNull": true
95+ },
96+ "resetPasswordToken": {
97+ "name": "resetPasswordToken",
98+ "type": "text",
99+ "primaryKey": false,
100+ "notNull": false
101+ },
102+ "resetPasswordExpiresAt": {
103+ "name": "resetPasswordExpiresAt",
104+ "type": "text",
105+ "primaryKey": false,
106+ "notNull": false
107+ },
108+ "confirmationToken": {
109+ "name": "confirmationToken",
110+ "type": "text",
111+ "primaryKey": false,
112+ "notNull": false
113+ },
114+ "confirmationExpiresAt": {
115+ "name": "confirmationExpiresAt",
116+ "type": "text",
117+ "primaryKey": false,
118+ "notNull": false
119+ }
120+ },
121+ "indexes": {},
122+ "foreignKeys": {
123+ "account_user_id_user_temp_id_fk": {
124+ "name": "account_user_id_user_temp_id_fk",
125+ "tableFrom": "account",
126+ "tableTo": "user_temp",
127+ "columnsFrom": [
128+ "user_id"
129+ ],
130+ "columnsTo": [
131+ "id"
132+ ],
133+ "onDelete": "cascade",
134+ "onUpdate": "no action"
135+ }
136+ },
137+ "compositePrimaryKeys": {},
138+ "uniqueConstraints": {},
139+ "policies": {},
140+ "checkConstraints": {},
141+ "isRLSEnabled": false
142+ },
143+ "public.apikey": {
144+ "name": "apikey",
145+ "schema": "",
146+ "columns": {
147+ "id": {
148+ "name": "id",
149+ "type": "text",
150+ "primaryKey": true,
151+ "notNull": true
152+ },
153+ "name": {
154+ "name": "name",
155+ "type": "text",
156+ "primaryKey": false,
157+ "notNull": false
158+ },
159+ "start": {
160+ "name": "start",
161+ "type": "text",
162+ "primaryKey": false,
163+ "notNull": false
164+ },
165+ "prefix": {
166+ "name": "prefix",
167+ "type": "text",
168+ "primaryKey": false,
169+ "notNull": false
170+ },
171+ "key": {
172+ "name": "key",
173+ "type": "text",
174+ "primaryKey": false,
175+ "notNull": true
176+ },
177+ "user_id": {
178+ "name": "user_id",
179+ "type": "text",
180+ "primaryKey": false,
181+ "notNull": true
182+ },
183+ "refill_interval": {
184+ "name": "refill_interval",
185+ "type": "integer",
186+ "primaryKey": false,
187+ "notNull": false
188+ },
189+ "refill_amount": {
190+ "name": "refill_amount",
191+ "type": "integer",
192+ "primaryKey": false,
193+ "notNull": false
194+ },
195+ "last_refill_at": {
196+ "name": "last_refill_at",
197+ "type": "timestamp",
198+ "primaryKey": false,
199+ "notNull": false
200+ },
201+ "enabled": {
202+ "name": "enabled",
203+ "type": "boolean",
204+ "primaryKey": false,
205+ "notNull": false
206+ },
207+ "rate_limit_enabled": {
208+ "name": "rate_limit_enabled",
209+ "type": "boolean",
210+ "primaryKey": false,
211+ "notNull": false
212+ },
213+ "rate_limit_time_window": {
214+ "name": "rate_limit_time_window",
215+ "type": "integer",
216+ "primaryKey": false,
217+ "notNull": false
218+ },
219+ "rate_limit_max": {
220+ "name": "rate_limit_max",
221+ "type": "integer",
222+ "primaryKey": false,
223+ "notNull": false
224+ },
225+ "request_count": {
226+ "name": "request_count",
227+ "type": "integer",
228+ "primaryKey": false,
229+ "notNull": false
230+ },
231+ "remaining": {
232+ "name": "remaining",
233+ "type": "integer",
234+ "primaryKey": false,
235+ "notNull": false
236+ },
237+ "last_request": {
238+ "name": "last_request",
239+ "type": "timestamp",
240+ "primaryKey": false,
241+ "notNull": false
242+ },
243+ "expires_at": {
244+ "name": "expires_at",
245+ "type": "timestamp",
246+ "primaryKey": false,
247+ "notNull": false
248+ },
249+ "created_at": {
250+ "name": "created_at",
251+ "type": "timestamp",
252+ "primaryKey": false,
253+ "notNull": true
254+ },
255+ "updated_at": {
256+ "name": "updated_at",
257+ "type": "timestamp",
258+ "primaryKey": false,
259+ "notNull": true
260+ },
261+ "permissions": {
262+ "name": "permissions",
263+ "type": "text",
264+ "primaryKey": false,
265+ "notNull": false
266+ },
267+ "metadata": {
268+ "name": "metadata",
269+ "type": "text",
270+ "primaryKey": false,
271+ "notNull": false
272+ }
273+ },
274+ "indexes": {},
275+ "foreignKeys": {
276+ "apikey_user_id_user_temp_id_fk": {
277+ "name": "apikey_user_id_user_temp_id_fk",
278+ "tableFrom": "apikey",
279+ "tableTo": "user_temp",
280+ "columnsFrom": [
281+ "user_id"
282+ ],
283+ "columnsTo": [
284+ "id"
285+ ],
286+ "onDelete": "cascade",
287+ "onUpdate": "no action"
288+ }
289+ },
290+ "compositePrimaryKeys": {},
291+ "uniqueConstraints": {},
292+ "policies": {},
293+ "checkConstraints": {},
294+ "isRLSEnabled": false
295+ },
296+ "public.invitation": {
297+ "name": "invitation",
298+ "schema": "",
299+ "columns": {
300+ "id": {
301+ "name": "id",
302+ "type": "text",
303+ "primaryKey": true,
304+ "notNull": true
305+ },
306+ "organization_id": {
307+ "name": "organization_id",
308+ "type": "text",
309+ "primaryKey": false,
310+ "notNull": true
311+ },
312+ "email": {
313+ "name": "email",
314+ "type": "text",
315+ "primaryKey": false,
316+ "notNull": true
317+ },
318+ "role": {
319+ "name": "role",
320+ "type": "text",
321+ "primaryKey": false,
322+ "notNull": false
323+ },
324+ "status": {
325+ "name": "status",
326+ "type": "text",
327+ "primaryKey": false,
328+ "notNull": true
329+ },
330+ "expires_at": {
331+ "name": "expires_at",
332+ "type": "timestamp",
333+ "primaryKey": false,
334+ "notNull": true
335+ },
336+ "inviter_id": {
337+ "name": "inviter_id",
338+ "type": "text",
339+ "primaryKey": false,
340+ "notNull": true
341+ },
342+ "team_id": {
343+ "name": "team_id",
344+ "type": "text",
345+ "primaryKey": false,
346+ "notNull": false
347+ }
348+ },
349+ "indexes": {},
350+ "foreignKeys": {
351+ "invitation_organization_id_organization_id_fk": {
352+ "name": "invitation_organization_id_organization_id_fk",
353+ "tableFrom": "invitation",
354+ "tableTo": "organization",
355+ "columnsFrom": [
356+ "organization_id"
357+ ],
358+ "columnsTo": [
359+ "id"
360+ ],
361+ "onDelete": "cascade",
362+ "onUpdate": "no action"
363+ },
364+ "invitation_inviter_id_user_temp_id_fk": {
365+ "name": "invitation_inviter_id_user_temp_id_fk",
366+ "tableFrom": "invitation",
367+ "tableTo": "user_temp",
368+ "columnsFrom": [
369+ "inviter_id"
370+ ],
371+ "columnsTo": [
372+ "id"
373+ ],
374+ "onDelete": "cascade",
375+ "onUpdate": "no action"
376+ }
377+ },
378+ "compositePrimaryKeys": {},
379+ "uniqueConstraints": {},
380+ "policies": {},
381+ "checkConstraints": {},
382+ "isRLSEnabled": false
383+ },
384+ "public.member": {
385+ "name": "member",
386+ "schema": "",
387+ "columns": {
388+ "id": {
389+ "name": "id",
390+ "type": "text",
391+ "primaryKey": true,
392+ "notNull": true
393+ },
394+ "organization_id": {
395+ "name": "organization_id",
396+ "type": "text",
397+ "primaryKey": false,
398+ "notNull": true
399+ },
400+ "user_id": {
401+ "name": "user_id",
402+ "type": "text",
403+ "primaryKey": false,
404+ "notNull": true
405+ },
406+ "role": {
407+ "name": "role",
408+ "type": "text",
409+ "primaryKey": false,
410+ "notNull": true
411+ },
412+ "created_at": {
413+ "name": "created_at",
414+ "type": "timestamp",
415+ "primaryKey": false,
416+ "notNull": true
417+ },
418+ "team_id": {
419+ "name": "team_id",
420+ "type": "text",
421+ "primaryKey": false,
422+ "notNull": false
423+ },
424+ "canCreateProjects": {
425+ "name": "canCreateProjects",
426+ "type": "boolean",
427+ "primaryKey": false,
428+ "notNull": true,
429+ "default": false
430+ },
431+ "canAccessToSSHKeys": {
432+ "name": "canAccessToSSHKeys",
433+ "type": "boolean",
434+ "primaryKey": false,
435+ "notNull": true,
436+ "default": false
437+ },
438+ "canCreateServices": {
439+ "name": "canCreateServices",
440+ "type": "boolean",
441+ "primaryKey": false,
442+ "notNull": true,
443+ "default": false
444+ },
445+ "canDeleteProjects": {
446+ "name": "canDeleteProjects",
447+ "type": "boolean",
448+ "primaryKey": false,
449+ "notNull": true,
450+ "default": false
451+ },
452+ "canDeleteServices": {
453+ "name": "canDeleteServices",
454+ "type": "boolean",
455+ "primaryKey": false,
456+ "notNull": true,
457+ "default": false
458+ },
459+ "canAccessToDocker": {
460+ "name": "canAccessToDocker",
461+ "type": "boolean",
462+ "primaryKey": false,
463+ "notNull": true,
464+ "default": false
465+ },
466+ "canAccessToAPI": {
467+ "name": "canAccessToAPI",
468+ "type": "boolean",
469+ "primaryKey": false,
470+ "notNull": true,
471+ "default": false
472+ },
473+ "canAccessToGitProviders": {
474+ "name": "canAccessToGitProviders",
475+ "type": "boolean",
476+ "primaryKey": false,
477+ "notNull": true,
478+ "default": false
479+ },
480+ "canAccessToTraefikFiles": {
481+ "name": "canAccessToTraefikFiles",
482+ "type": "boolean",
483+ "primaryKey": false,
484+ "notNull": true,
485+ "default": false
486+ },
487+ "accesedProjects": {
488+ "name": "accesedProjects",
489+ "type": "text[]",
490+ "primaryKey": false,
491+ "notNull": true,
492+ "default": "ARRAY[]::text[]"
493+ },
494+ "accesedServices": {
495+ "name": "accesedServices",
496+ "type": "text[]",
497+ "primaryKey": false,
498+ "notNull": true,
499+ "default": "ARRAY[]::text[]"
500+ }
501+ },
502+ "indexes": {},
503+ "foreignKeys": {
504+ "member_organization_id_organization_id_fk": {
505+ "name": "member_organization_id_organization_id_fk",
506+ "tableFrom": "member",
507+ "tableTo": "organization",
508+ "columnsFrom": [
509+ "organization_id"
510+ ],
511+ "columnsTo": [
512+ "id"
513+ ],
514+ "onDelete": "cascade",
515+ "onUpdate": "no action"
516+ },
517+ "member_user_id_user_temp_id_fk": {
518+ "name": "member_user_id_user_temp_id_fk",
519+ "tableFrom": "member",
520+ "tableTo": "user_temp",
521+ "columnsFrom": [
522+ "user_id"
523+ ],
524+ "columnsTo": [
525+ "id"
526+ ],
527+ "onDelete": "cascade",
528+ "onUpdate": "no action"
529+ }
530+ },
531+ "compositePrimaryKeys": {},
532+ "uniqueConstraints": {},
533+ "policies": {},
534+ "checkConstraints": {},
535+ "isRLSEnabled": false
536+ },
537+ "public.organization": {
538+ "name": "organization",
539+ "schema": "",
540+ "columns": {
541+ "id": {
542+ "name": "id",
543+ "type": "text",
544+ "primaryKey": true,
545+ "notNull": true
546+ },
547+ "name": {
548+ "name": "name",
549+ "type": "text",
550+ "primaryKey": false,
551+ "notNull": true
552+ },
553+ "slug": {
554+ "name": "slug",
555+ "type": "text",
556+ "primaryKey": false,
557+ "notNull": false
558+ },
559+ "logo": {
560+ "name": "logo",
561+ "type": "text",
562+ "primaryKey": false,
563+ "notNull": false
564+ },
565+ "created_at": {
566+ "name": "created_at",
567+ "type": "timestamp",
568+ "primaryKey": false,
569+ "notNull": true
570+ },
571+ "metadata": {
572+ "name": "metadata",
573+ "type": "text",
574+ "primaryKey": false,
575+ "notNull": false
576+ },
577+ "owner_id": {
578+ "name": "owner_id",
579+ "type": "text",
580+ "primaryKey": false,
581+ "notNull": true
582+ }
583+ },
584+ "indexes": {},
585+ "foreignKeys": {
586+ "organization_owner_id_user_temp_id_fk": {
587+ "name": "organization_owner_id_user_temp_id_fk",
588+ "tableFrom": "organization",
589+ "tableTo": "user_temp",
590+ "columnsFrom": [
591+ "owner_id"
592+ ],
593+ "columnsTo": [
594+ "id"
595+ ],
596+ "onDelete": "cascade",
597+ "onUpdate": "no action"
598+ }
599+ },
600+ "compositePrimaryKeys": {},
601+ "uniqueConstraints": {
602+ "organization_slug_unique": {
603+ "name": "organization_slug_unique",
604+ "nullsNotDistinct": false,
605+ "columns": [
606+ "slug"
607+ ]
608+ }
609+ },
610+ "policies": {},
611+ "checkConstraints": {},
612+ "isRLSEnabled": false
613+ },
614+ "public.two_factor": {
615+ "name": "two_factor",
616+ "schema": "",
617+ "columns": {
618+ "id": {
619+ "name": "id",
620+ "type": "text",
621+ "primaryKey": true,
622+ "notNull": true
623+ },
624+ "secret": {
625+ "name": "secret",
626+ "type": "text",
627+ "primaryKey": false,
628+ "notNull": true
629+ },
630+ "backup_codes": {
631+ "name": "backup_codes",
632+ "type": "text",
633+ "primaryKey": false,
634+ "notNull": true
635+ },
636+ "user_id": {
637+ "name": "user_id",
638+ "type": "text",
639+ "primaryKey": false,
640+ "notNull": true
641+ }
642+ },
643+ "indexes": {},
644+ "foreignKeys": {
645+ "two_factor_user_id_user_temp_id_fk": {
646+ "name": "two_factor_user_id_user_temp_id_fk",
647+ "tableFrom": "two_factor",
648+ "tableTo": "user_temp",
649+ "columnsFrom": [
650+ "user_id"
651+ ],
652+ "columnsTo": [
653+ "id"
654+ ],
655+ "onDelete": "cascade",
656+ "onUpdate": "no action"
657+ }
658+ },
659+ "compositePrimaryKeys": {},
660+ "uniqueConstraints": {},
661+ "policies": {},
662+ "checkConstraints": {},
663+ "isRLSEnabled": false
664+ },
665+ "public.verification": {
666+ "name": "verification",
667+ "schema": "",
668+ "columns": {
669+ "id": {
670+ "name": "id",
671+ "type": "text",
672+ "primaryKey": true,
673+ "notNull": true
674+ },
675+ "identifier": {
676+ "name": "identifier",
677+ "type": "text",
678+ "primaryKey": false,
679+ "notNull": true
680+ },
681+ "value": {
682+ "name": "value",
683+ "type": "text",
684+ "primaryKey": false,
685+ "notNull": true
686+ },
687+ "expires_at": {
688+ "name": "expires_at",
689+ "type": "timestamp",
690+ "primaryKey": false,
691+ "notNull": true
692+ },
693+ "created_at": {
694+ "name": "created_at",
695+ "type": "timestamp",
696+ "primaryKey": false,
697+ "notNull": false
698+ },
699+ "updated_at": {
700+ "name": "updated_at",
701+ "type": "timestamp",
702+ "primaryKey": false,
703+ "notNull": false
704+ }
705+ },
706+ "indexes": {},
707+ "foreignKeys": {},
708+ "compositePrimaryKeys": {},
709+ "uniqueConstraints": {},
710+ "policies": {},
711+ "checkConstraints": {},
712+ "isRLSEnabled": false
713+ },
714+ "public.ai": {
715+ "name": "ai",
716+ "schema": "",
717+ "columns": {
718+ "aiId": {
719+ "name": "aiId",
720+ "type": "text",
721+ "primaryKey": true,
722+ "notNull": true
723+ },
724+ "name": {
725+ "name": "name",
726+ "type": "text",
727+ "primaryKey": false,
728+ "notNull": true
729+ },
730+ "apiUrl": {
731+ "name": "apiUrl",
732+ "type": "text",
733+ "primaryKey": false,
734+ "notNull": true
735+ },
736+ "apiKey": {
737+ "name": "apiKey",
738+ "type": "text",
739+ "primaryKey": false,
740+ "notNull": true
741+ },
742+ "model": {
743+ "name": "model",
744+ "type": "text",
745+ "primaryKey": false,
746+ "notNull": true
747+ },
748+ "isEnabled": {
749+ "name": "isEnabled",
750+ "type": "boolean",
751+ "primaryKey": false,
752+ "notNull": true,
753+ "default": true
754+ },
755+ "organizationId": {
756+ "name": "organizationId",
757+ "type": "text",
758+ "primaryKey": false,
759+ "notNull": true
760+ },
761+ "createdAt": {
762+ "name": "createdAt",
763+ "type": "text",
764+ "primaryKey": false,
765+ "notNull": true
766+ }
767+ },
768+ "indexes": {},
769+ "foreignKeys": {
770+ "ai_organizationId_organization_id_fk": {
771+ "name": "ai_organizationId_organization_id_fk",
772+ "tableFrom": "ai",
773+ "tableTo": "organization",
774+ "columnsFrom": [
775+ "organizationId"
776+ ],
777+ "columnsTo": [
778+ "id"
779+ ],
780+ "onDelete": "cascade",
781+ "onUpdate": "no action"
782+ }
783+ },
784+ "compositePrimaryKeys": {},
785+ "uniqueConstraints": {},
786+ "policies": {},
787+ "checkConstraints": {},
788+ "isRLSEnabled": false
789+ },
790+ "public.application": {
791+ "name": "application",
792+ "schema": "",
793+ "columns": {
794+ "applicationId": {
795+ "name": "applicationId",
796+ "type": "text",
797+ "primaryKey": true,
798+ "notNull": true
799+ },
800+ "name": {
801+ "name": "name",
802+ "type": "text",
803+ "primaryKey": false,
804+ "notNull": true
805+ },
806+ "appName": {
807+ "name": "appName",
808+ "type": "text",
809+ "primaryKey": false,
810+ "notNull": true
811+ },
812+ "description": {
813+ "name": "description",
814+ "type": "text",
815+ "primaryKey": false,
816+ "notNull": false
817+ },
818+ "env": {
819+ "name": "env",
820+ "type": "text",
821+ "primaryKey": false,
822+ "notNull": false
823+ },
824+ "previewEnv": {
825+ "name": "previewEnv",
826+ "type": "text",
827+ "primaryKey": false,
828+ "notNull": false
829+ },
830+ "watchPaths": {
831+ "name": "watchPaths",
832+ "type": "text[]",
833+ "primaryKey": false,
834+ "notNull": false
835+ },
836+ "previewBuildArgs": {
837+ "name": "previewBuildArgs",
838+ "type": "text",
839+ "primaryKey": false,
840+ "notNull": false
841+ },
842+ "previewLabels": {
843+ "name": "previewLabels",
844+ "type": "text[]",
845+ "primaryKey": false,
846+ "notNull": false
847+ },
848+ "previewWildcard": {
849+ "name": "previewWildcard",
850+ "type": "text",
851+ "primaryKey": false,
852+ "notNull": false
853+ },
854+ "previewPort": {
855+ "name": "previewPort",
856+ "type": "integer",
857+ "primaryKey": false,
858+ "notNull": false,
859+ "default": 3000
860+ },
861+ "previewHttps": {
862+ "name": "previewHttps",
863+ "type": "boolean",
864+ "primaryKey": false,
865+ "notNull": true,
866+ "default": false
867+ },
868+ "previewPath": {
869+ "name": "previewPath",
870+ "type": "text",
871+ "primaryKey": false,
872+ "notNull": false,
873+ "default": "'/'"
874+ },
875+ "certificateType": {
876+ "name": "certificateType",
877+ "type": "certificateType",
878+ "typeSchema": "public",
879+ "primaryKey": false,
880+ "notNull": true,
881+ "default": "'none'"
882+ },
883+ "previewCustomCertResolver": {
884+ "name": "previewCustomCertResolver",
885+ "type": "text",
886+ "primaryKey": false,
887+ "notNull": false
888+ },
889+ "previewLimit": {
890+ "name": "previewLimit",
891+ "type": "integer",
892+ "primaryKey": false,
893+ "notNull": false,
894+ "default": 3
895+ },
896+ "isPreviewDeploymentsActive": {
897+ "name": "isPreviewDeploymentsActive",
898+ "type": "boolean",
899+ "primaryKey": false,
900+ "notNull": false,
901+ "default": false
902+ },
903+ "previewRequireCollaboratorPermissions": {
904+ "name": "previewRequireCollaboratorPermissions",
905+ "type": "boolean",
906+ "primaryKey": false,
907+ "notNull": false,
908+ "default": true
909+ },
910+ "rollbackActive": {
911+ "name": "rollbackActive",
912+ "type": "boolean",
913+ "primaryKey": false,
914+ "notNull": false,
915+ "default": false
916+ },
917+ "buildArgs": {
918+ "name": "buildArgs",
919+ "type": "text",
920+ "primaryKey": false,
921+ "notNull": false
922+ },
923+ "memoryReservation": {
924+ "name": "memoryReservation",
925+ "type": "text",
926+ "primaryKey": false,
927+ "notNull": false
928+ },
929+ "memoryLimit": {
930+ "name": "memoryLimit",
931+ "type": "text",
932+ "primaryKey": false,
933+ "notNull": false
934+ },
935+ "cpuReservation": {
936+ "name": "cpuReservation",
937+ "type": "text",
938+ "primaryKey": false,
939+ "notNull": false
940+ },
941+ "cpuLimit": {
942+ "name": "cpuLimit",
943+ "type": "text",
944+ "primaryKey": false,
945+ "notNull": false
946+ },
947+ "title": {
948+ "name": "title",
949+ "type": "text",
950+ "primaryKey": false,
951+ "notNull": false
952+ },
953+ "enabled": {
954+ "name": "enabled",
955+ "type": "boolean",
956+ "primaryKey": false,
957+ "notNull": false
958+ },
959+ "subtitle": {
960+ "name": "subtitle",
961+ "type": "text",
962+ "primaryKey": false,
963+ "notNull": false
964+ },
965+ "command": {
966+ "name": "command",
967+ "type": "text",
968+ "primaryKey": false,
969+ "notNull": false
970+ },
971+ "refreshToken": {
972+ "name": "refreshToken",
973+ "type": "text",
974+ "primaryKey": false,
975+ "notNull": false
976+ },
977+ "sourceType": {
978+ "name": "sourceType",
979+ "type": "sourceType",
980+ "typeSchema": "public",
981+ "primaryKey": false,
982+ "notNull": true,
983+ "default": "'github'"
984+ },
985+ "cleanCache": {
986+ "name": "cleanCache",
987+ "type": "boolean",
988+ "primaryKey": false,
989+ "notNull": false,
990+ "default": false
991+ },
992+ "repository": {
993+ "name": "repository",
994+ "type": "text",
995+ "primaryKey": false,
996+ "notNull": false
997+ },
998+ "owner": {
999+ "name": "owner",
1000+ "type": "text",
1001+ "primaryKey": false,
1002+ "notNull": false
1003+ },
1004+ "branch": {
1005+ "name": "branch",
1006+ "type": "text",
1007+ "primaryKey": false,
1008+ "notNull": false
1009+ },
1010+ "buildPath": {
1011+ "name": "buildPath",
1012+ "type": "text",
1013+ "primaryKey": false,
1014+ "notNull": false,
1015+ "default": "'/'"
1016+ },
1017+ "triggerType": {
1018+ "name": "triggerType",
1019+ "type": "triggerType",
1020+ "typeSchema": "public",
1021+ "primaryKey": false,
1022+ "notNull": false,
1023+ "default": "'push'"
1024+ },
1025+ "autoDeploy": {
1026+ "name": "autoDeploy",
1027+ "type": "boolean",
1028+ "primaryKey": false,
1029+ "notNull": false
1030+ },
1031+ "gitlabProjectId": {
1032+ "name": "gitlabProjectId",
1033+ "type": "integer",
1034+ "primaryKey": false,
1035+ "notNull": false
1036+ },
1037+ "gitlabRepository": {
1038+ "name": "gitlabRepository",
1039+ "type": "text",
1040+ "primaryKey": false,
1041+ "notNull": false
1042+ },
1043+ "gitlabOwner": {
1044+ "name": "gitlabOwner",
1045+ "type": "text",
1046+ "primaryKey": false,
1047+ "notNull": false
1048+ },
1049+ "gitlabBranch": {
1050+ "name": "gitlabBranch",
1051+ "type": "text",
1052+ "primaryKey": false,
1053+ "notNull": false
1054+ },
1055+ "gitlabBuildPath": {
1056+ "name": "gitlabBuildPath",
1057+ "type": "text",
1058+ "primaryKey": false,
1059+ "notNull": false,
1060+ "default": "'/'"
1061+ },
1062+ "gitlabPathNamespace": {
1063+ "name": "gitlabPathNamespace",
1064+ "type": "text",
1065+ "primaryKey": false,
1066+ "notNull": false
1067+ },
1068+ "giteaRepository": {
1069+ "name": "giteaRepository",
1070+ "type": "text",
1071+ "primaryKey": false,
1072+ "notNull": false
1073+ },
1074+ "giteaOwner": {
1075+ "name": "giteaOwner",
1076+ "type": "text",
1077+ "primaryKey": false,
1078+ "notNull": false
1079+ },
1080+ "giteaBranch": {
1081+ "name": "giteaBranch",
1082+ "type": "text",
1083+ "primaryKey": false,
1084+ "notNull": false
1085+ },
1086+ "giteaBuildPath": {
1087+ "name": "giteaBuildPath",
1088+ "type": "text",
1089+ "primaryKey": false,
1090+ "notNull": false,
1091+ "default": "'/'"
1092+ },
1093+ "bitbucketRepository": {
1094+ "name": "bitbucketRepository",
1095+ "type": "text",
1096+ "primaryKey": false,
1097+ "notNull": false
1098+ },
1099+ "bitbucketOwner": {
1100+ "name": "bitbucketOwner",
1101+ "type": "text",
1102+ "primaryKey": false,
1103+ "notNull": false
1104+ },
1105+ "bitbucketBranch": {
1106+ "name": "bitbucketBranch",
1107+ "type": "text",
1108+ "primaryKey": false,
1109+ "notNull": false
1110+ },
1111+ "bitbucketBuildPath": {
1112+ "name": "bitbucketBuildPath",
1113+ "type": "text",
1114+ "primaryKey": false,
1115+ "notNull": false,
1116+ "default": "'/'"
1117+ },
1118+ "username": {
1119+ "name": "username",
1120+ "type": "text",
1121+ "primaryKey": false,
1122+ "notNull": false
1123+ },
1124+ "password": {
1125+ "name": "password",
1126+ "type": "text",
1127+ "primaryKey": false,
1128+ "notNull": false
1129+ },
1130+ "dockerImage": {
1131+ "name": "dockerImage",
1132+ "type": "text",
1133+ "primaryKey": false,
1134+ "notNull": false
1135+ },
1136+ "registryUrl": {
1137+ "name": "registryUrl",
1138+ "type": "text",
1139+ "primaryKey": false,
1140+ "notNull": false
1141+ },
1142+ "customGitUrl": {
1143+ "name": "customGitUrl",
1144+ "type": "text",
1145+ "primaryKey": false,
1146+ "notNull": false
1147+ },
1148+ "customGitBranch": {
1149+ "name": "customGitBranch",
1150+ "type": "text",
1151+ "primaryKey": false,
1152+ "notNull": false
1153+ },
1154+ "customGitBuildPath": {
1155+ "name": "customGitBuildPath",
1156+ "type": "text",
1157+ "primaryKey": false,
1158+ "notNull": false
1159+ },
1160+ "customGitSSHKeyId": {
1161+ "name": "customGitSSHKeyId",
1162+ "type": "text",
1163+ "primaryKey": false,
1164+ "notNull": false
1165+ },
1166+ "enableSubmodules": {
1167+ "name": "enableSubmodules",
1168+ "type": "boolean",
1169+ "primaryKey": false,
1170+ "notNull": true,
1171+ "default": false
1172+ },
1173+ "dockerfile": {
1174+ "name": "dockerfile",
1175+ "type": "text",
1176+ "primaryKey": false,
1177+ "notNull": false
1178+ },
1179+ "dockerContextPath": {
1180+ "name": "dockerContextPath",
1181+ "type": "text",
1182+ "primaryKey": false,
1183+ "notNull": false
1184+ },
1185+ "dockerBuildStage": {
1186+ "name": "dockerBuildStage",
1187+ "type": "text",
1188+ "primaryKey": false,
1189+ "notNull": false
1190+ },
1191+ "dropBuildPath": {
1192+ "name": "dropBuildPath",
1193+ "type": "text",
1194+ "primaryKey": false,
1195+ "notNull": false
1196+ },
1197+ "healthCheckSwarm": {
1198+ "name": "healthCheckSwarm",
1199+ "type": "json",
1200+ "primaryKey": false,
1201+ "notNull": false
1202+ },
1203+ "restartPolicySwarm": {
1204+ "name": "restartPolicySwarm",
1205+ "type": "json",
1206+ "primaryKey": false,
1207+ "notNull": false
1208+ },
1209+ "placementSwarm": {
1210+ "name": "placementSwarm",
1211+ "type": "json",
1212+ "primaryKey": false,
1213+ "notNull": false
1214+ },
1215+ "updateConfigSwarm": {
1216+ "name": "updateConfigSwarm",
1217+ "type": "json",
1218+ "primaryKey": false,
1219+ "notNull": false
1220+ },
1221+ "rollbackConfigSwarm": {
1222+ "name": "rollbackConfigSwarm",
1223+ "type": "json",
1224+ "primaryKey": false,
1225+ "notNull": false
1226+ },
1227+ "modeSwarm": {
1228+ "name": "modeSwarm",
1229+ "type": "json",
1230+ "primaryKey": false,
1231+ "notNull": false
1232+ },
1233+ "labelsSwarm": {
1234+ "name": "labelsSwarm",
1235+ "type": "json",
1236+ "primaryKey": false,
1237+ "notNull": false
1238+ },
1239+ "networkSwarm": {
1240+ "name": "networkSwarm",
1241+ "type": "json",
1242+ "primaryKey": false,
1243+ "notNull": false
1244+ },
1245+ "replicas": {
1246+ "name": "replicas",
1247+ "type": "integer",
1248+ "primaryKey": false,
1249+ "notNull": true,
1250+ "default": 1
1251+ },
1252+ "applicationStatus": {
1253+ "name": "applicationStatus",
1254+ "type": "applicationStatus",
1255+ "typeSchema": "public",
1256+ "primaryKey": false,
1257+ "notNull": true,
1258+ "default": "'idle'"
1259+ },
1260+ "buildType": {
1261+ "name": "buildType",
1262+ "type": "buildType",
1263+ "typeSchema": "public",
1264+ "primaryKey": false,
1265+ "notNull": true,
1266+ "default": "'nixpacks'"
1267+ },
1268+ "railpackVersion": {
1269+ "name": "railpackVersion",
1270+ "type": "text",
1271+ "primaryKey": false,
1272+ "notNull": false,
1273+ "default": "'0.2.2'"
1274+ },
1275+ "herokuVersion": {
1276+ "name": "herokuVersion",
1277+ "type": "text",
1278+ "primaryKey": false,
1279+ "notNull": false,
1280+ "default": "'24'"
1281+ },
1282+ "publishDirectory": {
1283+ "name": "publishDirectory",
1284+ "type": "text",
1285+ "primaryKey": false,
1286+ "notNull": false
1287+ },
1288+ "isStaticSpa": {
1289+ "name": "isStaticSpa",
1290+ "type": "boolean",
1291+ "primaryKey": false,
1292+ "notNull": false
1293+ },
1294+ "createdAt": {
1295+ "name": "createdAt",
1296+ "type": "text",
1297+ "primaryKey": false,
1298+ "notNull": true
1299+ },
1300+ "registryId": {
1301+ "name": "registryId",
1302+ "type": "text",
1303+ "primaryKey": false,
1304+ "notNull": false
1305+ },
1306+ "projectId": {
1307+ "name": "projectId",
1308+ "type": "text",
1309+ "primaryKey": false,
1310+ "notNull": true
1311+ },
1312+ "githubId": {
1313+ "name": "githubId",
1314+ "type": "text",
1315+ "primaryKey": false,
1316+ "notNull": false
1317+ },
1318+ "gitlabId": {
1319+ "name": "gitlabId",
1320+ "type": "text",
1321+ "primaryKey": false,
1322+ "notNull": false
1323+ },
1324+ "giteaId": {
1325+ "name": "giteaId",
1326+ "type": "text",
1327+ "primaryKey": false,
1328+ "notNull": false
1329+ },
1330+ "bitbucketId": {
1331+ "name": "bitbucketId",
1332+ "type": "text",
1333+ "primaryKey": false,
1334+ "notNull": false
1335+ },
1336+ "serverId": {
1337+ "name": "serverId",
1338+ "type": "text",
1339+ "primaryKey": false,
1340+ "notNull": false
1341+ }
1342+ },
1343+ "indexes": {},
1344+ "foreignKeys": {
1345+ "application_customGitSSHKeyId_ssh-key_sshKeyId_fk": {
1346+ "name": "application_customGitSSHKeyId_ssh-key_sshKeyId_fk",
1347+ "tableFrom": "application",
1348+ "tableTo": "ssh-key",
1349+ "columnsFrom": [
1350+ "customGitSSHKeyId"
1351+ ],
1352+ "columnsTo": [
1353+ "sshKeyId"
1354+ ],
1355+ "onDelete": "set null",
1356+ "onUpdate": "no action"
1357+ },
1358+ "application_registryId_registry_registryId_fk": {
1359+ "name": "application_registryId_registry_registryId_fk",
1360+ "tableFrom": "application",
1361+ "tableTo": "registry",
1362+ "columnsFrom": [
1363+ "registryId"
1364+ ],
1365+ "columnsTo": [
1366+ "registryId"
1367+ ],
1368+ "onDelete": "set null",
1369+ "onUpdate": "no action"
1370+ },
1371+ "application_projectId_project_projectId_fk": {
1372+ "name": "application_projectId_project_projectId_fk",
1373+ "tableFrom": "application",
1374+ "tableTo": "project",
1375+ "columnsFrom": [
1376+ "projectId"
1377+ ],
1378+ "columnsTo": [
1379+ "projectId"
1380+ ],
1381+ "onDelete": "cascade",
1382+ "onUpdate": "no action"
1383+ },
1384+ "application_githubId_github_githubId_fk": {
1385+ "name": "application_githubId_github_githubId_fk",
1386+ "tableFrom": "application",
1387+ "tableTo": "github",
1388+ "columnsFrom": [
1389+ "githubId"
1390+ ],
1391+ "columnsTo": [
1392+ "githubId"
1393+ ],
1394+ "onDelete": "set null",
1395+ "onUpdate": "no action"
1396+ },
1397+ "application_gitlabId_gitlab_gitlabId_fk": {
1398+ "name": "application_gitlabId_gitlab_gitlabId_fk",
1399+ "tableFrom": "application",
1400+ "tableTo": "gitlab",
1401+ "columnsFrom": [
1402+ "gitlabId"
1403+ ],
1404+ "columnsTo": [
1405+ "gitlabId"
1406+ ],
1407+ "onDelete": "set null",
1408+ "onUpdate": "no action"
1409+ },
1410+ "application_giteaId_gitea_giteaId_fk": {
1411+ "name": "application_giteaId_gitea_giteaId_fk",
1412+ "tableFrom": "application",
1413+ "tableTo": "gitea",
1414+ "columnsFrom": [
1415+ "giteaId"
1416+ ],
1417+ "columnsTo": [
1418+ "giteaId"
1419+ ],
1420+ "onDelete": "set null",
1421+ "onUpdate": "no action"
1422+ },
1423+ "application_bitbucketId_bitbucket_bitbucketId_fk": {
1424+ "name": "application_bitbucketId_bitbucket_bitbucketId_fk",
1425+ "tableFrom": "application",
1426+ "tableTo": "bitbucket",
1427+ "columnsFrom": [
1428+ "bitbucketId"
1429+ ],
1430+ "columnsTo": [
1431+ "bitbucketId"
1432+ ],
1433+ "onDelete": "set null",
1434+ "onUpdate": "no action"
1435+ },
1436+ "application_serverId_server_serverId_fk": {
1437+ "name": "application_serverId_server_serverId_fk",
1438+ "tableFrom": "application",
1439+ "tableTo": "server",
1440+ "columnsFrom": [
1441+ "serverId"
1442+ ],
1443+ "columnsTo": [
1444+ "serverId"
1445+ ],
1446+ "onDelete": "cascade",
1447+ "onUpdate": "no action"
1448+ }
1449+ },
1450+ "compositePrimaryKeys": {},
1451+ "uniqueConstraints": {
1452+ "application_appName_unique": {
1453+ "name": "application_appName_unique",
1454+ "nullsNotDistinct": false,
1455+ "columns": [
1456+ "appName"
1457+ ]
1458+ }
1459+ },
1460+ "policies": {},
1461+ "checkConstraints": {},
1462+ "isRLSEnabled": false
1463+ },
1464+ "public.backup": {
1465+ "name": "backup",
1466+ "schema": "",
1467+ "columns": {
1468+ "backupId": {
1469+ "name": "backupId",
1470+ "type": "text",
1471+ "primaryKey": true,
1472+ "notNull": true
1473+ },
1474+ "appName": {
1475+ "name": "appName",
1476+ "type": "text",
1477+ "primaryKey": false,
1478+ "notNull": true
1479+ },
1480+ "schedule": {
1481+ "name": "schedule",
1482+ "type": "text",
1483+ "primaryKey": false,
1484+ "notNull": true
1485+ },
1486+ "enabled": {
1487+ "name": "enabled",
1488+ "type": "boolean",
1489+ "primaryKey": false,
1490+ "notNull": false
1491+ },
1492+ "database": {
1493+ "name": "database",
1494+ "type": "text",
1495+ "primaryKey": false,
1496+ "notNull": true
1497+ },
1498+ "prefix": {
1499+ "name": "prefix",
1500+ "type": "text",
1501+ "primaryKey": false,
1502+ "notNull": true
1503+ },
1504+ "serviceName": {
1505+ "name": "serviceName",
1506+ "type": "text",
1507+ "primaryKey": false,
1508+ "notNull": false
1509+ },
1510+ "destinationId": {
1511+ "name": "destinationId",
1512+ "type": "text",
1513+ "primaryKey": false,
1514+ "notNull": true
1515+ },
1516+ "keepLatestCount": {
1517+ "name": "keepLatestCount",
1518+ "type": "integer",
1519+ "primaryKey": false,
1520+ "notNull": false
1521+ },
1522+ "backupType": {
1523+ "name": "backupType",
1524+ "type": "backupType",
1525+ "typeSchema": "public",
1526+ "primaryKey": false,
1527+ "notNull": true,
1528+ "default": "'database'"
1529+ },
1530+ "databaseType": {
1531+ "name": "databaseType",
1532+ "type": "databaseType",
1533+ "typeSchema": "public",
1534+ "primaryKey": false,
1535+ "notNull": true
1536+ },
1537+ "composeId": {
1538+ "name": "composeId",
1539+ "type": "text",
1540+ "primaryKey": false,
1541+ "notNull": false
1542+ },
1543+ "postgresId": {
1544+ "name": "postgresId",
1545+ "type": "text",
1546+ "primaryKey": false,
1547+ "notNull": false
1548+ },
1549+ "mariadbId": {
1550+ "name": "mariadbId",
1551+ "type": "text",
1552+ "primaryKey": false,
1553+ "notNull": false
1554+ },
1555+ "mysqlId": {
1556+ "name": "mysqlId",
1557+ "type": "text",
1558+ "primaryKey": false,
1559+ "notNull": false
1560+ },
1561+ "mongoId": {
1562+ "name": "mongoId",
1563+ "type": "text",
1564+ "primaryKey": false,
1565+ "notNull": false
1566+ },
1567+ "userId": {
1568+ "name": "userId",
1569+ "type": "text",
1570+ "primaryKey": false,
1571+ "notNull": false
1572+ },
1573+ "metadata": {
1574+ "name": "metadata",
1575+ "type": "jsonb",
1576+ "primaryKey": false,
1577+ "notNull": false
1578+ }
1579+ },
1580+ "indexes": {},
1581+ "foreignKeys": {
1582+ "backup_destinationId_destination_destinationId_fk": {
1583+ "name": "backup_destinationId_destination_destinationId_fk",
1584+ "tableFrom": "backup",
1585+ "tableTo": "destination",
1586+ "columnsFrom": [
1587+ "destinationId"
1588+ ],
1589+ "columnsTo": [
1590+ "destinationId"
1591+ ],
1592+ "onDelete": "cascade",
1593+ "onUpdate": "no action"
1594+ },
1595+ "backup_composeId_compose_composeId_fk": {
1596+ "name": "backup_composeId_compose_composeId_fk",
1597+ "tableFrom": "backup",
1598+ "tableTo": "compose",
1599+ "columnsFrom": [
1600+ "composeId"
1601+ ],
1602+ "columnsTo": [
1603+ "composeId"
1604+ ],
1605+ "onDelete": "cascade",
1606+ "onUpdate": "no action"
1607+ },
1608+ "backup_postgresId_postgres_postgresId_fk": {
1609+ "name": "backup_postgresId_postgres_postgresId_fk",
1610+ "tableFrom": "backup",
1611+ "tableTo": "postgres",
1612+ "columnsFrom": [
1613+ "postgresId"
1614+ ],
1615+ "columnsTo": [
1616+ "postgresId"
1617+ ],
1618+ "onDelete": "cascade",
1619+ "onUpdate": "no action"
1620+ },
1621+ "backup_mariadbId_mariadb_mariadbId_fk": {
1622+ "name": "backup_mariadbId_mariadb_mariadbId_fk",
1623+ "tableFrom": "backup",
1624+ "tableTo": "mariadb",
1625+ "columnsFrom": [
1626+ "mariadbId"
1627+ ],
1628+ "columnsTo": [
1629+ "mariadbId"
1630+ ],
1631+ "onDelete": "cascade",
1632+ "onUpdate": "no action"
1633+ },
1634+ "backup_mysqlId_mysql_mysqlId_fk": {
1635+ "name": "backup_mysqlId_mysql_mysqlId_fk",
1636+ "tableFrom": "backup",
1637+ "tableTo": "mysql",
1638+ "columnsFrom": [
1639+ "mysqlId"
1640+ ],
1641+ "columnsTo": [
1642+ "mysqlId"
1643+ ],
1644+ "onDelete": "cascade",
1645+ "onUpdate": "no action"
1646+ },
1647+ "backup_mongoId_mongo_mongoId_fk": {
1648+ "name": "backup_mongoId_mongo_mongoId_fk",
1649+ "tableFrom": "backup",
1650+ "tableTo": "mongo",
1651+ "columnsFrom": [
1652+ "mongoId"
1653+ ],
1654+ "columnsTo": [
1655+ "mongoId"
1656+ ],
1657+ "onDelete": "cascade",
1658+ "onUpdate": "no action"
1659+ },
1660+ "backup_userId_user_temp_id_fk": {
1661+ "name": "backup_userId_user_temp_id_fk",
1662+ "tableFrom": "backup",
1663+ "tableTo": "user_temp",
1664+ "columnsFrom": [
1665+ "userId"
1666+ ],
1667+ "columnsTo": [
1668+ "id"
1669+ ],
1670+ "onDelete": "no action",
1671+ "onUpdate": "no action"
1672+ }
1673+ },
1674+ "compositePrimaryKeys": {},
1675+ "uniqueConstraints": {
1676+ "backup_appName_unique": {
1677+ "name": "backup_appName_unique",
1678+ "nullsNotDistinct": false,
1679+ "columns": [
1680+ "appName"
1681+ ]
1682+ }
1683+ },
1684+ "policies": {},
1685+ "checkConstraints": {},
1686+ "isRLSEnabled": false
1687+ },
1688+ "public.bitbucket": {
1689+ "name": "bitbucket",
1690+ "schema": "",
1691+ "columns": {
1692+ "bitbucketId": {
1693+ "name": "bitbucketId",
1694+ "type": "text",
1695+ "primaryKey": true,
1696+ "notNull": true
1697+ },
1698+ "bitbucketUsername": {
1699+ "name": "bitbucketUsername",
1700+ "type": "text",
1701+ "primaryKey": false,
1702+ "notNull": false
1703+ },
1704+ "appPassword": {
1705+ "name": "appPassword",
1706+ "type": "text",
1707+ "primaryKey": false,
1708+ "notNull": false
1709+ },
1710+ "bitbucketWorkspaceName": {
1711+ "name": "bitbucketWorkspaceName",
1712+ "type": "text",
1713+ "primaryKey": false,
1714+ "notNull": false
1715+ },
1716+ "gitProviderId": {
1717+ "name": "gitProviderId",
1718+ "type": "text",
1719+ "primaryKey": false,
1720+ "notNull": true
1721+ }
1722+ },
1723+ "indexes": {},
1724+ "foreignKeys": {
1725+ "bitbucket_gitProviderId_git_provider_gitProviderId_fk": {
1726+ "name": "bitbucket_gitProviderId_git_provider_gitProviderId_fk",
1727+ "tableFrom": "bitbucket",
1728+ "tableTo": "git_provider",
1729+ "columnsFrom": [
1730+ "gitProviderId"
1731+ ],
1732+ "columnsTo": [
1733+ "gitProviderId"
1734+ ],
1735+ "onDelete": "cascade",
1736+ "onUpdate": "no action"
1737+ }
1738+ },
1739+ "compositePrimaryKeys": {},
1740+ "uniqueConstraints": {},
1741+ "policies": {},
1742+ "checkConstraints": {},
1743+ "isRLSEnabled": false
1744+ },
1745+ "public.certificate": {
1746+ "name": "certificate",
1747+ "schema": "",
1748+ "columns": {
1749+ "certificateId": {
1750+ "name": "certificateId",
1751+ "type": "text",
1752+ "primaryKey": true,
1753+ "notNull": true
1754+ },
1755+ "name": {
1756+ "name": "name",
1757+ "type": "text",
1758+ "primaryKey": false,
1759+ "notNull": true
1760+ },
1761+ "certificateData": {
1762+ "name": "certificateData",
1763+ "type": "text",
1764+ "primaryKey": false,
1765+ "notNull": true
1766+ },
1767+ "privateKey": {
1768+ "name": "privateKey",
1769+ "type": "text",
1770+ "primaryKey": false,
1771+ "notNull": true
1772+ },
1773+ "certificatePath": {
1774+ "name": "certificatePath",
1775+ "type": "text",
1776+ "primaryKey": false,
1777+ "notNull": true
1778+ },
1779+ "autoRenew": {
1780+ "name": "autoRenew",
1781+ "type": "boolean",
1782+ "primaryKey": false,
1783+ "notNull": false
1784+ },
1785+ "organizationId": {
1786+ "name": "organizationId",
1787+ "type": "text",
1788+ "primaryKey": false,
1789+ "notNull": true
1790+ },
1791+ "serverId": {
1792+ "name": "serverId",
1793+ "type": "text",
1794+ "primaryKey": false,
1795+ "notNull": false
1796+ }
1797+ },
1798+ "indexes": {},
1799+ "foreignKeys": {
1800+ "certificate_organizationId_organization_id_fk": {
1801+ "name": "certificate_organizationId_organization_id_fk",
1802+ "tableFrom": "certificate",
1803+ "tableTo": "organization",
1804+ "columnsFrom": [
1805+ "organizationId"
1806+ ],
1807+ "columnsTo": [
1808+ "id"
1809+ ],
1810+ "onDelete": "cascade",
1811+ "onUpdate": "no action"
1812+ },
1813+ "certificate_serverId_server_serverId_fk": {
1814+ "name": "certificate_serverId_server_serverId_fk",
1815+ "tableFrom": "certificate",
1816+ "tableTo": "server",
1817+ "columnsFrom": [
1818+ "serverId"
1819+ ],
1820+ "columnsTo": [
1821+ "serverId"
1822+ ],
1823+ "onDelete": "cascade",
1824+ "onUpdate": "no action"
1825+ }
1826+ },
1827+ "compositePrimaryKeys": {},
1828+ "uniqueConstraints": {
1829+ "certificate_certificatePath_unique": {
1830+ "name": "certificate_certificatePath_unique",
1831+ "nullsNotDistinct": false,
1832+ "columns": [
1833+ "certificatePath"
1834+ ]
1835+ }
1836+ },
1837+ "policies": {},
1838+ "checkConstraints": {},
1839+ "isRLSEnabled": false
1840+ },
1841+ "public.compose": {
1842+ "name": "compose",
1843+ "schema": "",
1844+ "columns": {
1845+ "composeId": {
1846+ "name": "composeId",
1847+ "type": "text",
1848+ "primaryKey": true,
1849+ "notNull": true
1850+ },
1851+ "name": {
1852+ "name": "name",
1853+ "type": "text",
1854+ "primaryKey": false,
1855+ "notNull": true
1856+ },
1857+ "appName": {
1858+ "name": "appName",
1859+ "type": "text",
1860+ "primaryKey": false,
1861+ "notNull": true
1862+ },
1863+ "description": {
1864+ "name": "description",
1865+ "type": "text",
1866+ "primaryKey": false,
1867+ "notNull": false
1868+ },
1869+ "env": {
1870+ "name": "env",
1871+ "type": "text",
1872+ "primaryKey": false,
1873+ "notNull": false
1874+ },
1875+ "composeFile": {
1876+ "name": "composeFile",
1877+ "type": "text",
1878+ "primaryKey": false,
1879+ "notNull": true,
1880+ "default": "''"
1881+ },
1882+ "refreshToken": {
1883+ "name": "refreshToken",
1884+ "type": "text",
1885+ "primaryKey": false,
1886+ "notNull": false
1887+ },
1888+ "sourceType": {
1889+ "name": "sourceType",
1890+ "type": "sourceTypeCompose",
1891+ "typeSchema": "public",
1892+ "primaryKey": false,
1893+ "notNull": true,
1894+ "default": "'github'"
1895+ },
1896+ "composeType": {
1897+ "name": "composeType",
1898+ "type": "composeType",
1899+ "typeSchema": "public",
1900+ "primaryKey": false,
1901+ "notNull": true,
1902+ "default": "'docker-compose'"
1903+ },
1904+ "repository": {
1905+ "name": "repository",
1906+ "type": "text",
1907+ "primaryKey": false,
1908+ "notNull": false
1909+ },
1910+ "owner": {
1911+ "name": "owner",
1912+ "type": "text",
1913+ "primaryKey": false,
1914+ "notNull": false
1915+ },
1916+ "branch": {
1917+ "name": "branch",
1918+ "type": "text",
1919+ "primaryKey": false,
1920+ "notNull": false
1921+ },
1922+ "autoDeploy": {
1923+ "name": "autoDeploy",
1924+ "type": "boolean",
1925+ "primaryKey": false,
1926+ "notNull": false
1927+ },
1928+ "gitlabProjectId": {
1929+ "name": "gitlabProjectId",
1930+ "type": "integer",
1931+ "primaryKey": false,
1932+ "notNull": false
1933+ },
1934+ "gitlabRepository": {
1935+ "name": "gitlabRepository",
1936+ "type": "text",
1937+ "primaryKey": false,
1938+ "notNull": false
1939+ },
1940+ "gitlabOwner": {
1941+ "name": "gitlabOwner",
1942+ "type": "text",
1943+ "primaryKey": false,
1944+ "notNull": false
1945+ },
1946+ "gitlabBranch": {
1947+ "name": "gitlabBranch",
1948+ "type": "text",
1949+ "primaryKey": false,
1950+ "notNull": false
1951+ },
1952+ "gitlabPathNamespace": {
1953+ "name": "gitlabPathNamespace",
1954+ "type": "text",
1955+ "primaryKey": false,
1956+ "notNull": false
1957+ },
1958+ "bitbucketRepository": {
1959+ "name": "bitbucketRepository",
1960+ "type": "text",
1961+ "primaryKey": false,
1962+ "notNull": false
1963+ },
1964+ "bitbucketOwner": {
1965+ "name": "bitbucketOwner",
1966+ "type": "text",
1967+ "primaryKey": false,
1968+ "notNull": false
1969+ },
1970+ "bitbucketBranch": {
1971+ "name": "bitbucketBranch",
1972+ "type": "text",
1973+ "primaryKey": false,
1974+ "notNull": false
1975+ },
1976+ "giteaRepository": {
1977+ "name": "giteaRepository",
1978+ "type": "text",
1979+ "primaryKey": false,
1980+ "notNull": false
1981+ },
1982+ "giteaOwner": {
1983+ "name": "giteaOwner",
1984+ "type": "text",
1985+ "primaryKey": false,
1986+ "notNull": false
1987+ },
1988+ "giteaBranch": {
1989+ "name": "giteaBranch",
1990+ "type": "text",
1991+ "primaryKey": false,
1992+ "notNull": false
1993+ },
1994+ "customGitUrl": {
1995+ "name": "customGitUrl",
1996+ "type": "text",
1997+ "primaryKey": false,
1998+ "notNull": false
1999+ },
2000+ "customGitBranch": {
2001+ "name": "customGitBranch",
2002+ "type": "text",
2003+ "primaryKey": false,
2004+ "notNull": false
2005+ },
2006+ "customGitSSHKeyId": {
2007+ "name": "customGitSSHKeyId",
2008+ "type": "text",
2009+ "primaryKey": false,
2010+ "notNull": false
2011+ },
2012+ "command": {
2013+ "name": "command",
2014+ "type": "text",
2015+ "primaryKey": false,
2016+ "notNull": true,
2017+ "default": "''"
2018+ },
2019+ "enableSubmodules": {
2020+ "name": "enableSubmodules",
2021+ "type": "boolean",
2022+ "primaryKey": false,
2023+ "notNull": true,
2024+ "default": false
2025+ },
2026+ "composePath": {
2027+ "name": "composePath",
2028+ "type": "text",
2029+ "primaryKey": false,
2030+ "notNull": true,
2031+ "default": "'./docker-compose.yml'"
2032+ },
2033+ "suffix": {
2034+ "name": "suffix",
2035+ "type": "text",
2036+ "primaryKey": false,
2037+ "notNull": true,
2038+ "default": "''"
2039+ },
2040+ "randomize": {
2041+ "name": "randomize",
2042+ "type": "boolean",
2043+ "primaryKey": false,
2044+ "notNull": true,
2045+ "default": false
2046+ },
2047+ "isolatedDeployment": {
2048+ "name": "isolatedDeployment",
2049+ "type": "boolean",
2050+ "primaryKey": false,
2051+ "notNull": true,
2052+ "default": false
2053+ },
2054+ "isolatedDeploymentsVolume": {
2055+ "name": "isolatedDeploymentsVolume",
2056+ "type": "boolean",
2057+ "primaryKey": false,
2058+ "notNull": true,
2059+ "default": false
2060+ },
2061+ "triggerType": {
2062+ "name": "triggerType",
2063+ "type": "triggerType",
2064+ "typeSchema": "public",
2065+ "primaryKey": false,
2066+ "notNull": false,
2067+ "default": "'push'"
2068+ },
2069+ "composeStatus": {
2070+ "name": "composeStatus",
2071+ "type": "applicationStatus",
2072+ "typeSchema": "public",
2073+ "primaryKey": false,
2074+ "notNull": true,
2075+ "default": "'idle'"
2076+ },
2077+ "projectId": {
2078+ "name": "projectId",
2079+ "type": "text",
2080+ "primaryKey": false,
2081+ "notNull": true
2082+ },
2083+ "createdAt": {
2084+ "name": "createdAt",
2085+ "type": "text",
2086+ "primaryKey": false,
2087+ "notNull": true
2088+ },
2089+ "watchPaths": {
2090+ "name": "watchPaths",
2091+ "type": "text[]",
2092+ "primaryKey": false,
2093+ "notNull": false
2094+ },
2095+ "githubId": {
2096+ "name": "githubId",
2097+ "type": "text",
2098+ "primaryKey": false,
2099+ "notNull": false
2100+ },
2101+ "gitlabId": {
2102+ "name": "gitlabId",
2103+ "type": "text",
2104+ "primaryKey": false,
2105+ "notNull": false
2106+ },
2107+ "bitbucketId": {
2108+ "name": "bitbucketId",
2109+ "type": "text",
2110+ "primaryKey": false,
2111+ "notNull": false
2112+ },
2113+ "giteaId": {
2114+ "name": "giteaId",
2115+ "type": "text",
2116+ "primaryKey": false,
2117+ "notNull": false
2118+ },
2119+ "serverId": {
2120+ "name": "serverId",
2121+ "type": "text",
2122+ "primaryKey": false,
2123+ "notNull": false
2124+ }
2125+ },
2126+ "indexes": {},
2127+ "foreignKeys": {
2128+ "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk": {
2129+ "name": "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk",
2130+ "tableFrom": "compose",
2131+ "tableTo": "ssh-key",
2132+ "columnsFrom": [
2133+ "customGitSSHKeyId"
2134+ ],
2135+ "columnsTo": [
2136+ "sshKeyId"
2137+ ],
2138+ "onDelete": "set null",
2139+ "onUpdate": "no action"
2140+ },
2141+ "compose_projectId_project_projectId_fk": {
2142+ "name": "compose_projectId_project_projectId_fk",
2143+ "tableFrom": "compose",
2144+ "tableTo": "project",
2145+ "columnsFrom": [
2146+ "projectId"
2147+ ],
2148+ "columnsTo": [
2149+ "projectId"
2150+ ],
2151+ "onDelete": "cascade",
2152+ "onUpdate": "no action"
2153+ },
2154+ "compose_githubId_github_githubId_fk": {
2155+ "name": "compose_githubId_github_githubId_fk",
2156+ "tableFrom": "compose",
2157+ "tableTo": "github",
2158+ "columnsFrom": [
2159+ "githubId"
2160+ ],
2161+ "columnsTo": [
2162+ "githubId"
2163+ ],
2164+ "onDelete": "set null",
2165+ "onUpdate": "no action"
2166+ },
2167+ "compose_gitlabId_gitlab_gitlabId_fk": {
2168+ "name": "compose_gitlabId_gitlab_gitlabId_fk",
2169+ "tableFrom": "compose",
2170+ "tableTo": "gitlab",
2171+ "columnsFrom": [
2172+ "gitlabId"
2173+ ],
2174+ "columnsTo": [
2175+ "gitlabId"
2176+ ],
2177+ "onDelete": "set null",
2178+ "onUpdate": "no action"
2179+ },
2180+ "compose_bitbucketId_bitbucket_bitbucketId_fk": {
2181+ "name": "compose_bitbucketId_bitbucket_bitbucketId_fk",
2182+ "tableFrom": "compose",
2183+ "tableTo": "bitbucket",
2184+ "columnsFrom": [
2185+ "bitbucketId"
2186+ ],
2187+ "columnsTo": [
2188+ "bitbucketId"
2189+ ],
2190+ "onDelete": "set null",
2191+ "onUpdate": "no action"
2192+ },
2193+ "compose_giteaId_gitea_giteaId_fk": {
2194+ "name": "compose_giteaId_gitea_giteaId_fk",
2195+ "tableFrom": "compose",
2196+ "tableTo": "gitea",
2197+ "columnsFrom": [
2198+ "giteaId"
2199+ ],
2200+ "columnsTo": [
2201+ "giteaId"
2202+ ],
2203+ "onDelete": "set null",
2204+ "onUpdate": "no action"
2205+ },
2206+ "compose_serverId_server_serverId_fk": {
2207+ "name": "compose_serverId_server_serverId_fk",
2208+ "tableFrom": "compose",
2209+ "tableTo": "server",
2210+ "columnsFrom": [
2211+ "serverId"
2212+ ],
2213+ "columnsTo": [
2214+ "serverId"
2215+ ],
2216+ "onDelete": "cascade",
2217+ "onUpdate": "no action"
2218+ }
2219+ },
2220+ "compositePrimaryKeys": {},
2221+ "uniqueConstraints": {},
2222+ "policies": {},
2223+ "checkConstraints": {},
2224+ "isRLSEnabled": false
2225+ },
2226+ "public.deployment": {
2227+ "name": "deployment",
2228+ "schema": "",
2229+ "columns": {
2230+ "deploymentId": {
2231+ "name": "deploymentId",
2232+ "type": "text",
2233+ "primaryKey": true,
2234+ "notNull": true
2235+ },
2236+ "title": {
2237+ "name": "title",
2238+ "type": "text",
2239+ "primaryKey": false,
2240+ "notNull": true
2241+ },
2242+ "description": {
2243+ "name": "description",
2244+ "type": "text",
2245+ "primaryKey": false,
2246+ "notNull": false
2247+ },
2248+ "status": {
2249+ "name": "status",
2250+ "type": "deploymentStatus",
2251+ "typeSchema": "public",
2252+ "primaryKey": false,
2253+ "notNull": false,
2254+ "default": "'running'"
2255+ },
2256+ "logPath": {
2257+ "name": "logPath",
2258+ "type": "text",
2259+ "primaryKey": false,
2260+ "notNull": true
2261+ },
2262+ "pid": {
2263+ "name": "pid",
2264+ "type": "text",
2265+ "primaryKey": false,
2266+ "notNull": false
2267+ },
2268+ "applicationId": {
2269+ "name": "applicationId",
2270+ "type": "text",
2271+ "primaryKey": false,
2272+ "notNull": false
2273+ },
2274+ "composeId": {
2275+ "name": "composeId",
2276+ "type": "text",
2277+ "primaryKey": false,
2278+ "notNull": false
2279+ },
2280+ "serverId": {
2281+ "name": "serverId",
2282+ "type": "text",
2283+ "primaryKey": false,
2284+ "notNull": false
2285+ },
2286+ "isPreviewDeployment": {
2287+ "name": "isPreviewDeployment",
2288+ "type": "boolean",
2289+ "primaryKey": false,
2290+ "notNull": false,
2291+ "default": false
2292+ },
2293+ "previewDeploymentId": {
2294+ "name": "previewDeploymentId",
2295+ "type": "text",
2296+ "primaryKey": false,
2297+ "notNull": false
2298+ },
2299+ "createdAt": {
2300+ "name": "createdAt",
2301+ "type": "text",
2302+ "primaryKey": false,
2303+ "notNull": true
2304+ },
2305+ "startedAt": {
2306+ "name": "startedAt",
2307+ "type": "text",
2308+ "primaryKey": false,
2309+ "notNull": false
2310+ },
2311+ "finishedAt": {
2312+ "name": "finishedAt",
2313+ "type": "text",
2314+ "primaryKey": false,
2315+ "notNull": false
2316+ },
2317+ "errorMessage": {
2318+ "name": "errorMessage",
2319+ "type": "text",
2320+ "primaryKey": false,
2321+ "notNull": false
2322+ },
2323+ "scheduleId": {
2324+ "name": "scheduleId",
2325+ "type": "text",
2326+ "primaryKey": false,
2327+ "notNull": false
2328+ },
2329+ "backupId": {
2330+ "name": "backupId",
2331+ "type": "text",
2332+ "primaryKey": false,
2333+ "notNull": false
2334+ },
2335+ "rollbackId": {
2336+ "name": "rollbackId",
2337+ "type": "text",
2338+ "primaryKey": false,
2339+ "notNull": false
2340+ },
2341+ "volumeBackupId": {
2342+ "name": "volumeBackupId",
2343+ "type": "text",
2344+ "primaryKey": false,
2345+ "notNull": false
2346+ }
2347+ },
2348+ "indexes": {},
2349+ "foreignKeys": {
2350+ "deployment_applicationId_application_applicationId_fk": {
2351+ "name": "deployment_applicationId_application_applicationId_fk",
2352+ "tableFrom": "deployment",
2353+ "tableTo": "application",
2354+ "columnsFrom": [
2355+ "applicationId"
2356+ ],
2357+ "columnsTo": [
2358+ "applicationId"
2359+ ],
2360+ "onDelete": "cascade",
2361+ "onUpdate": "no action"
2362+ },
2363+ "deployment_composeId_compose_composeId_fk": {
2364+ "name": "deployment_composeId_compose_composeId_fk",
2365+ "tableFrom": "deployment",
2366+ "tableTo": "compose",
2367+ "columnsFrom": [
2368+ "composeId"
2369+ ],
2370+ "columnsTo": [
2371+ "composeId"
2372+ ],
2373+ "onDelete": "cascade",
2374+ "onUpdate": "no action"
2375+ },
2376+ "deployment_serverId_server_serverId_fk": {
2377+ "name": "deployment_serverId_server_serverId_fk",
2378+ "tableFrom": "deployment",
2379+ "tableTo": "server",
2380+ "columnsFrom": [
2381+ "serverId"
2382+ ],
2383+ "columnsTo": [
2384+ "serverId"
2385+ ],
2386+ "onDelete": "cascade",
2387+ "onUpdate": "no action"
2388+ },
2389+ "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
2390+ "name": "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
2391+ "tableFrom": "deployment",
2392+ "tableTo": "preview_deployments",
2393+ "columnsFrom": [
2394+ "previewDeploymentId"
2395+ ],
2396+ "columnsTo": [
2397+ "previewDeploymentId"
2398+ ],
2399+ "onDelete": "cascade",
2400+ "onUpdate": "no action"
2401+ },
2402+ "deployment_scheduleId_schedule_scheduleId_fk": {
2403+ "name": "deployment_scheduleId_schedule_scheduleId_fk",
2404+ "tableFrom": "deployment",
2405+ "tableTo": "schedule",
2406+ "columnsFrom": [
2407+ "scheduleId"
2408+ ],
2409+ "columnsTo": [
2410+ "scheduleId"
2411+ ],
2412+ "onDelete": "cascade",
2413+ "onUpdate": "no action"
2414+ },
2415+ "deployment_backupId_backup_backupId_fk": {
2416+ "name": "deployment_backupId_backup_backupId_fk",
2417+ "tableFrom": "deployment",
2418+ "tableTo": "backup",
2419+ "columnsFrom": [
2420+ "backupId"
2421+ ],
2422+ "columnsTo": [
2423+ "backupId"
2424+ ],
2425+ "onDelete": "cascade",
2426+ "onUpdate": "no action"
2427+ },
2428+ "deployment_rollbackId_rollback_rollbackId_fk": {
2429+ "name": "deployment_rollbackId_rollback_rollbackId_fk",
2430+ "tableFrom": "deployment",
2431+ "tableTo": "rollback",
2432+ "columnsFrom": [
2433+ "rollbackId"
2434+ ],
2435+ "columnsTo": [
2436+ "rollbackId"
2437+ ],
2438+ "onDelete": "cascade",
2439+ "onUpdate": "no action"
2440+ },
2441+ "deployment_volumeBackupId_volume_backup_volumeBackupId_fk": {
2442+ "name": "deployment_volumeBackupId_volume_backup_volumeBackupId_fk",
2443+ "tableFrom": "deployment",
2444+ "tableTo": "volume_backup",
2445+ "columnsFrom": [
2446+ "volumeBackupId"
2447+ ],
2448+ "columnsTo": [
2449+ "volumeBackupId"
2450+ ],
2451+ "onDelete": "cascade",
2452+ "onUpdate": "no action"
2453+ }
2454+ },
2455+ "compositePrimaryKeys": {},
2456+ "uniqueConstraints": {},
2457+ "policies": {},
2458+ "checkConstraints": {},
2459+ "isRLSEnabled": false
2460+ },
2461+ "public.destination": {
2462+ "name": "destination",
2463+ "schema": "",
2464+ "columns": {
2465+ "destinationId": {
2466+ "name": "destinationId",
2467+ "type": "text",
2468+ "primaryKey": true,
2469+ "notNull": true
2470+ },
2471+ "name": {
2472+ "name": "name",
2473+ "type": "text",
2474+ "primaryKey": false,
2475+ "notNull": true
2476+ },
2477+ "provider": {
2478+ "name": "provider",
2479+ "type": "text",
2480+ "primaryKey": false,
2481+ "notNull": false
2482+ },
2483+ "accessKey": {
2484+ "name": "accessKey",
2485+ "type": "text",
2486+ "primaryKey": false,
2487+ "notNull": true
2488+ },
2489+ "secretAccessKey": {
2490+ "name": "secretAccessKey",
2491+ "type": "text",
2492+ "primaryKey": false,
2493+ "notNull": true
2494+ },
2495+ "bucket": {
2496+ "name": "bucket",
2497+ "type": "text",
2498+ "primaryKey": false,
2499+ "notNull": true
2500+ },
2501+ "region": {
2502+ "name": "region",
2503+ "type": "text",
2504+ "primaryKey": false,
2505+ "notNull": true
2506+ },
2507+ "endpoint": {
2508+ "name": "endpoint",
2509+ "type": "text",
2510+ "primaryKey": false,
2511+ "notNull": true
2512+ },
2513+ "organizationId": {
2514+ "name": "organizationId",
2515+ "type": "text",
2516+ "primaryKey": false,
2517+ "notNull": true
2518+ },
2519+ "createdAt": {
2520+ "name": "createdAt",
2521+ "type": "timestamp",
2522+ "primaryKey": false,
2523+ "notNull": true,
2524+ "default": "now()"
2525+ }
2526+ },
2527+ "indexes": {},
2528+ "foreignKeys": {
2529+ "destination_organizationId_organization_id_fk": {
2530+ "name": "destination_organizationId_organization_id_fk",
2531+ "tableFrom": "destination",
2532+ "tableTo": "organization",
2533+ "columnsFrom": [
2534+ "organizationId"
2535+ ],
2536+ "columnsTo": [
2537+ "id"
2538+ ],
2539+ "onDelete": "cascade",
2540+ "onUpdate": "no action"
2541+ }
2542+ },
2543+ "compositePrimaryKeys": {},
2544+ "uniqueConstraints": {},
2545+ "policies": {},
2546+ "checkConstraints": {},
2547+ "isRLSEnabled": false
2548+ },
2549+ "public.domain": {
2550+ "name": "domain",
2551+ "schema": "",
2552+ "columns": {
2553+ "domainId": {
2554+ "name": "domainId",
2555+ "type": "text",
2556+ "primaryKey": true,
2557+ "notNull": true
2558+ },
2559+ "host": {
2560+ "name": "host",
2561+ "type": "text",
2562+ "primaryKey": false,
2563+ "notNull": true
2564+ },
2565+ "https": {
2566+ "name": "https",
2567+ "type": "boolean",
2568+ "primaryKey": false,
2569+ "notNull": true,
2570+ "default": false
2571+ },
2572+ "port": {
2573+ "name": "port",
2574+ "type": "integer",
2575+ "primaryKey": false,
2576+ "notNull": false,
2577+ "default": 3000
2578+ },
2579+ "path": {
2580+ "name": "path",
2581+ "type": "text",
2582+ "primaryKey": false,
2583+ "notNull": false,
2584+ "default": "'/'"
2585+ },
2586+ "serviceName": {
2587+ "name": "serviceName",
2588+ "type": "text",
2589+ "primaryKey": false,
2590+ "notNull": false
2591+ },
2592+ "domainType": {
2593+ "name": "domainType",
2594+ "type": "domainType",
2595+ "typeSchema": "public",
2596+ "primaryKey": false,
2597+ "notNull": false,
2598+ "default": "'application'"
2599+ },
2600+ "uniqueConfigKey": {
2601+ "name": "uniqueConfigKey",
2602+ "type": "serial",
2603+ "primaryKey": false,
2604+ "notNull": true
2605+ },
2606+ "createdAt": {
2607+ "name": "createdAt",
2608+ "type": "text",
2609+ "primaryKey": false,
2610+ "notNull": true
2611+ },
2612+ "composeId": {
2613+ "name": "composeId",
2614+ "type": "text",
2615+ "primaryKey": false,
2616+ "notNull": false
2617+ },
2618+ "customCertResolver": {
2619+ "name": "customCertResolver",
2620+ "type": "text",
2621+ "primaryKey": false,
2622+ "notNull": false
2623+ },
2624+ "applicationId": {
2625+ "name": "applicationId",
2626+ "type": "text",
2627+ "primaryKey": false,
2628+ "notNull": false
2629+ },
2630+ "previewDeploymentId": {
2631+ "name": "previewDeploymentId",
2632+ "type": "text",
2633+ "primaryKey": false,
2634+ "notNull": false
2635+ },
2636+ "certificateType": {
2637+ "name": "certificateType",
2638+ "type": "certificateType",
2639+ "typeSchema": "public",
2640+ "primaryKey": false,
2641+ "notNull": true,
2642+ "default": "'none'"
2643+ },
2644+ "internalPath": {
2645+ "name": "internalPath",
2646+ "type": "text",
2647+ "primaryKey": false,
2648+ "notNull": false,
2649+ "default": "'/'"
2650+ },
2651+ "stripPath": {
2652+ "name": "stripPath",
2653+ "type": "boolean",
2654+ "primaryKey": false,
2655+ "notNull": true,
2656+ "default": false
2657+ }
2658+ },
2659+ "indexes": {},
2660+ "foreignKeys": {
2661+ "domain_composeId_compose_composeId_fk": {
2662+ "name": "domain_composeId_compose_composeId_fk",
2663+ "tableFrom": "domain",
2664+ "tableTo": "compose",
2665+ "columnsFrom": [
2666+ "composeId"
2667+ ],
2668+ "columnsTo": [
2669+ "composeId"
2670+ ],
2671+ "onDelete": "cascade",
2672+ "onUpdate": "no action"
2673+ },
2674+ "domain_applicationId_application_applicationId_fk": {
2675+ "name": "domain_applicationId_application_applicationId_fk",
2676+ "tableFrom": "domain",
2677+ "tableTo": "application",
2678+ "columnsFrom": [
2679+ "applicationId"
2680+ ],
2681+ "columnsTo": [
2682+ "applicationId"
2683+ ],
2684+ "onDelete": "cascade",
2685+ "onUpdate": "no action"
2686+ },
2687+ "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
2688+ "name": "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
2689+ "tableFrom": "domain",
2690+ "tableTo": "preview_deployments",
2691+ "columnsFrom": [
2692+ "previewDeploymentId"
2693+ ],
2694+ "columnsTo": [
2695+ "previewDeploymentId"
2696+ ],
2697+ "onDelete": "cascade",
2698+ "onUpdate": "no action"
2699+ }
2700+ },
2701+ "compositePrimaryKeys": {},
2702+ "uniqueConstraints": {},
2703+ "policies": {},
2704+ "checkConstraints": {},
2705+ "isRLSEnabled": false
2706+ },
2707+ "public.git_provider": {
2708+ "name": "git_provider",
2709+ "schema": "",
2710+ "columns": {
2711+ "gitProviderId": {
2712+ "name": "gitProviderId",
2713+ "type": "text",
2714+ "primaryKey": true,
2715+ "notNull": true
2716+ },
2717+ "name": {
2718+ "name": "name",
2719+ "type": "text",
2720+ "primaryKey": false,
2721+ "notNull": true
2722+ },
2723+ "providerType": {
2724+ "name": "providerType",
2725+ "type": "gitProviderType",
2726+ "typeSchema": "public",
2727+ "primaryKey": false,
2728+ "notNull": true,
2729+ "default": "'github'"
2730+ },
2731+ "createdAt": {
2732+ "name": "createdAt",
2733+ "type": "text",
2734+ "primaryKey": false,
2735+ "notNull": true
2736+ },
2737+ "organizationId": {
2738+ "name": "organizationId",
2739+ "type": "text",
2740+ "primaryKey": false,
2741+ "notNull": true
2742+ },
2743+ "userId": {
2744+ "name": "userId",
2745+ "type": "text",
2746+ "primaryKey": false,
2747+ "notNull": true
2748+ }
2749+ },
2750+ "indexes": {},
2751+ "foreignKeys": {
2752+ "git_provider_organizationId_organization_id_fk": {
2753+ "name": "git_provider_organizationId_organization_id_fk",
2754+ "tableFrom": "git_provider",
2755+ "tableTo": "organization",
2756+ "columnsFrom": [
2757+ "organizationId"
2758+ ],
2759+ "columnsTo": [
2760+ "id"
2761+ ],
2762+ "onDelete": "cascade",
2763+ "onUpdate": "no action"
2764+ },
2765+ "git_provider_userId_user_temp_id_fk": {
2766+ "name": "git_provider_userId_user_temp_id_fk",
2767+ "tableFrom": "git_provider",
2768+ "tableTo": "user_temp",
2769+ "columnsFrom": [
2770+ "userId"
2771+ ],
2772+ "columnsTo": [
2773+ "id"
2774+ ],
2775+ "onDelete": "cascade",
2776+ "onUpdate": "no action"
2777+ }
2778+ },
2779+ "compositePrimaryKeys": {},
2780+ "uniqueConstraints": {},
2781+ "policies": {},
2782+ "checkConstraints": {},
2783+ "isRLSEnabled": false
2784+ },
2785+ "public.gitea": {
2786+ "name": "gitea",
2787+ "schema": "",
2788+ "columns": {
2789+ "giteaId": {
2790+ "name": "giteaId",
2791+ "type": "text",
2792+ "primaryKey": true,
2793+ "notNull": true
2794+ },
2795+ "giteaUrl": {
2796+ "name": "giteaUrl",
2797+ "type": "text",
2798+ "primaryKey": false,
2799+ "notNull": true,
2800+ "default": "'https://gitea.com'"
2801+ },
2802+ "redirect_uri": {
2803+ "name": "redirect_uri",
2804+ "type": "text",
2805+ "primaryKey": false,
2806+ "notNull": false
2807+ },
2808+ "client_id": {
2809+ "name": "client_id",
2810+ "type": "text",
2811+ "primaryKey": false,
2812+ "notNull": false
2813+ },
2814+ "client_secret": {
2815+ "name": "client_secret",
2816+ "type": "text",
2817+ "primaryKey": false,
2818+ "notNull": false
2819+ },
2820+ "gitProviderId": {
2821+ "name": "gitProviderId",
2822+ "type": "text",
2823+ "primaryKey": false,
2824+ "notNull": true
2825+ },
2826+ "access_token": {
2827+ "name": "access_token",
2828+ "type": "text",
2829+ "primaryKey": false,
2830+ "notNull": false
2831+ },
2832+ "refresh_token": {
2833+ "name": "refresh_token",
2834+ "type": "text",
2835+ "primaryKey": false,
2836+ "notNull": false
2837+ },
2838+ "expires_at": {
2839+ "name": "expires_at",
2840+ "type": "integer",
2841+ "primaryKey": false,
2842+ "notNull": false
2843+ },
2844+ "scopes": {
2845+ "name": "scopes",
2846+ "type": "text",
2847+ "primaryKey": false,
2848+ "notNull": false,
2849+ "default": "'repo,repo:status,read:user,read:org'"
2850+ },
2851+ "last_authenticated_at": {
2852+ "name": "last_authenticated_at",
2853+ "type": "integer",
2854+ "primaryKey": false,
2855+ "notNull": false
2856+ }
2857+ },
2858+ "indexes": {},
2859+ "foreignKeys": {
2860+ "gitea_gitProviderId_git_provider_gitProviderId_fk": {
2861+ "name": "gitea_gitProviderId_git_provider_gitProviderId_fk",
2862+ "tableFrom": "gitea",
2863+ "tableTo": "git_provider",
2864+ "columnsFrom": [
2865+ "gitProviderId"
2866+ ],
2867+ "columnsTo": [
2868+ "gitProviderId"
2869+ ],
2870+ "onDelete": "cascade",
2871+ "onUpdate": "no action"
2872+ }
2873+ },
2874+ "compositePrimaryKeys": {},
2875+ "uniqueConstraints": {},
2876+ "policies": {},
2877+ "checkConstraints": {},
2878+ "isRLSEnabled": false
2879+ },
2880+ "public.github": {
2881+ "name": "github",
2882+ "schema": "",
2883+ "columns": {
2884+ "githubId": {
2885+ "name": "githubId",
2886+ "type": "text",
2887+ "primaryKey": true,
2888+ "notNull": true
2889+ },
2890+ "githubAppName": {
2891+ "name": "githubAppName",
2892+ "type": "text",
2893+ "primaryKey": false,
2894+ "notNull": false
2895+ },
2896+ "githubAppId": {
2897+ "name": "githubAppId",
2898+ "type": "integer",
2899+ "primaryKey": false,
2900+ "notNull": false
2901+ },
2902+ "githubClientId": {
2903+ "name": "githubClientId",
2904+ "type": "text",
2905+ "primaryKey": false,
2906+ "notNull": false
2907+ },
2908+ "githubClientSecret": {
2909+ "name": "githubClientSecret",
2910+ "type": "text",
2911+ "primaryKey": false,
2912+ "notNull": false
2913+ },
2914+ "githubInstallationId": {
2915+ "name": "githubInstallationId",
2916+ "type": "text",
2917+ "primaryKey": false,
2918+ "notNull": false
2919+ },
2920+ "githubPrivateKey": {
2921+ "name": "githubPrivateKey",
2922+ "type": "text",
2923+ "primaryKey": false,
2924+ "notNull": false
2925+ },
2926+ "githubWebhookSecret": {
2927+ "name": "githubWebhookSecret",
2928+ "type": "text",
2929+ "primaryKey": false,
2930+ "notNull": false
2931+ },
2932+ "gitProviderId": {
2933+ "name": "gitProviderId",
2934+ "type": "text",
2935+ "primaryKey": false,
2936+ "notNull": true
2937+ }
2938+ },
2939+ "indexes": {},
2940+ "foreignKeys": {
2941+ "github_gitProviderId_git_provider_gitProviderId_fk": {
2942+ "name": "github_gitProviderId_git_provider_gitProviderId_fk",
2943+ "tableFrom": "github",
2944+ "tableTo": "git_provider",
2945+ "columnsFrom": [
2946+ "gitProviderId"
2947+ ],
2948+ "columnsTo": [
2949+ "gitProviderId"
2950+ ],
2951+ "onDelete": "cascade",
2952+ "onUpdate": "no action"
2953+ }
2954+ },
2955+ "compositePrimaryKeys": {},
2956+ "uniqueConstraints": {},
2957+ "policies": {},
2958+ "checkConstraints": {},
2959+ "isRLSEnabled": false
2960+ },
2961+ "public.gitlab": {
2962+ "name": "gitlab",
2963+ "schema": "",
2964+ "columns": {
2965+ "gitlabId": {
2966+ "name": "gitlabId",
2967+ "type": "text",
2968+ "primaryKey": true,
2969+ "notNull": true
2970+ },
2971+ "gitlabUrl": {
2972+ "name": "gitlabUrl",
2973+ "type": "text",
2974+ "primaryKey": false,
2975+ "notNull": true,
2976+ "default": "'https://gitlab.com'"
2977+ },
2978+ "application_id": {
2979+ "name": "application_id",
2980+ "type": "text",
2981+ "primaryKey": false,
2982+ "notNull": false
2983+ },
2984+ "redirect_uri": {
2985+ "name": "redirect_uri",
2986+ "type": "text",
2987+ "primaryKey": false,
2988+ "notNull": false
2989+ },
2990+ "secret": {
2991+ "name": "secret",
2992+ "type": "text",
2993+ "primaryKey": false,
2994+ "notNull": false
2995+ },
2996+ "access_token": {
2997+ "name": "access_token",
2998+ "type": "text",
2999+ "primaryKey": false,
3000+ "notNull": false
3001+ },
3002+ "refresh_token": {
3003+ "name": "refresh_token",
3004+ "type": "text",
3005+ "primaryKey": false,
3006+ "notNull": false
3007+ },
3008+ "group_name": {
3009+ "name": "group_name",
3010+ "type": "text",
3011+ "primaryKey": false,
3012+ "notNull": false
3013+ },
3014+ "expires_at": {
3015+ "name": "expires_at",
3016+ "type": "integer",
3017+ "primaryKey": false,
3018+ "notNull": false
3019+ },
3020+ "gitProviderId": {
3021+ "name": "gitProviderId",
3022+ "type": "text",
3023+ "primaryKey": false,
3024+ "notNull": true
3025+ }
3026+ },
3027+ "indexes": {},
3028+ "foreignKeys": {
3029+ "gitlab_gitProviderId_git_provider_gitProviderId_fk": {
3030+ "name": "gitlab_gitProviderId_git_provider_gitProviderId_fk",
3031+ "tableFrom": "gitlab",
3032+ "tableTo": "git_provider",
3033+ "columnsFrom": [
3034+ "gitProviderId"
3035+ ],
3036+ "columnsTo": [
3037+ "gitProviderId"
3038+ ],
3039+ "onDelete": "cascade",
3040+ "onUpdate": "no action"
3041+ }
3042+ },
3043+ "compositePrimaryKeys": {},
3044+ "uniqueConstraints": {},
3045+ "policies": {},
3046+ "checkConstraints": {},
3047+ "isRLSEnabled": false
3048+ },
3049+ "public.mariadb": {
3050+ "name": "mariadb",
3051+ "schema": "",
3052+ "columns": {
3053+ "mariadbId": {
3054+ "name": "mariadbId",
3055+ "type": "text",
3056+ "primaryKey": true,
3057+ "notNull": true
3058+ },
3059+ "name": {
3060+ "name": "name",
3061+ "type": "text",
3062+ "primaryKey": false,
3063+ "notNull": true
3064+ },
3065+ "appName": {
3066+ "name": "appName",
3067+ "type": "text",
3068+ "primaryKey": false,
3069+ "notNull": true
3070+ },
3071+ "description": {
3072+ "name": "description",
3073+ "type": "text",
3074+ "primaryKey": false,
3075+ "notNull": false
3076+ },
3077+ "databaseName": {
3078+ "name": "databaseName",
3079+ "type": "text",
3080+ "primaryKey": false,
3081+ "notNull": true
3082+ },
3083+ "databaseUser": {
3084+ "name": "databaseUser",
3085+ "type": "text",
3086+ "primaryKey": false,
3087+ "notNull": true
3088+ },
3089+ "databasePassword": {
3090+ "name": "databasePassword",
3091+ "type": "text",
3092+ "primaryKey": false,
3093+ "notNull": true
3094+ },
3095+ "rootPassword": {
3096+ "name": "rootPassword",
3097+ "type": "text",
3098+ "primaryKey": false,
3099+ "notNull": true
3100+ },
3101+ "dockerImage": {
3102+ "name": "dockerImage",
3103+ "type": "text",
3104+ "primaryKey": false,
3105+ "notNull": true
3106+ },
3107+ "command": {
3108+ "name": "command",
3109+ "type": "text",
3110+ "primaryKey": false,
3111+ "notNull": false
3112+ },
3113+ "env": {
3114+ "name": "env",
3115+ "type": "text",
3116+ "primaryKey": false,
3117+ "notNull": false
3118+ },
3119+ "memoryReservation": {
3120+ "name": "memoryReservation",
3121+ "type": "text",
3122+ "primaryKey": false,
3123+ "notNull": false
3124+ },
3125+ "memoryLimit": {
3126+ "name": "memoryLimit",
3127+ "type": "text",
3128+ "primaryKey": false,
3129+ "notNull": false
3130+ },
3131+ "cpuReservation": {
3132+ "name": "cpuReservation",
3133+ "type": "text",
3134+ "primaryKey": false,
3135+ "notNull": false
3136+ },
3137+ "cpuLimit": {
3138+ "name": "cpuLimit",
3139+ "type": "text",
3140+ "primaryKey": false,
3141+ "notNull": false
3142+ },
3143+ "externalPort": {
3144+ "name": "externalPort",
3145+ "type": "integer",
3146+ "primaryKey": false,
3147+ "notNull": false
3148+ },
3149+ "applicationStatus": {
3150+ "name": "applicationStatus",
3151+ "type": "applicationStatus",
3152+ "typeSchema": "public",
3153+ "primaryKey": false,
3154+ "notNull": true,
3155+ "default": "'idle'"
3156+ },
3157+ "healthCheckSwarm": {
3158+ "name": "healthCheckSwarm",
3159+ "type": "json",
3160+ "primaryKey": false,
3161+ "notNull": false
3162+ },
3163+ "restartPolicySwarm": {
3164+ "name": "restartPolicySwarm",
3165+ "type": "json",
3166+ "primaryKey": false,
3167+ "notNull": false
3168+ },
3169+ "placementSwarm": {
3170+ "name": "placementSwarm",
3171+ "type": "json",
3172+ "primaryKey": false,
3173+ "notNull": false
3174+ },
3175+ "updateConfigSwarm": {
3176+ "name": "updateConfigSwarm",
3177+ "type": "json",
3178+ "primaryKey": false,
3179+ "notNull": false
3180+ },
3181+ "rollbackConfigSwarm": {
3182+ "name": "rollbackConfigSwarm",
3183+ "type": "json",
3184+ "primaryKey": false,
3185+ "notNull": false
3186+ },
3187+ "modeSwarm": {
3188+ "name": "modeSwarm",
3189+ "type": "json",
3190+ "primaryKey": false,
3191+ "notNull": false
3192+ },
3193+ "labelsSwarm": {
3194+ "name": "labelsSwarm",
3195+ "type": "json",
3196+ "primaryKey": false,
3197+ "notNull": false
3198+ },
3199+ "networkSwarm": {
3200+ "name": "networkSwarm",
3201+ "type": "json",
3202+ "primaryKey": false,
3203+ "notNull": false
3204+ },
3205+ "replicas": {
3206+ "name": "replicas",
3207+ "type": "integer",
3208+ "primaryKey": false,
3209+ "notNull": true,
3210+ "default": 1
3211+ },
3212+ "createdAt": {
3213+ "name": "createdAt",
3214+ "type": "text",
3215+ "primaryKey": false,
3216+ "notNull": true
3217+ },
3218+ "projectId": {
3219+ "name": "projectId",
3220+ "type": "text",
3221+ "primaryKey": false,
3222+ "notNull": true
3223+ },
3224+ "serverId": {
3225+ "name": "serverId",
3226+ "type": "text",
3227+ "primaryKey": false,
3228+ "notNull": false
3229+ }
3230+ },
3231+ "indexes": {},
3232+ "foreignKeys": {
3233+ "mariadb_projectId_project_projectId_fk": {
3234+ "name": "mariadb_projectId_project_projectId_fk",
3235+ "tableFrom": "mariadb",
3236+ "tableTo": "project",
3237+ "columnsFrom": [
3238+ "projectId"
3239+ ],
3240+ "columnsTo": [
3241+ "projectId"
3242+ ],
3243+ "onDelete": "cascade",
3244+ "onUpdate": "no action"
3245+ },
3246+ "mariadb_serverId_server_serverId_fk": {
3247+ "name": "mariadb_serverId_server_serverId_fk",
3248+ "tableFrom": "mariadb",
3249+ "tableTo": "server",
3250+ "columnsFrom": [
3251+ "serverId"
3252+ ],
3253+ "columnsTo": [
3254+ "serverId"
3255+ ],
3256+ "onDelete": "cascade",
3257+ "onUpdate": "no action"
3258+ }
3259+ },
3260+ "compositePrimaryKeys": {},
3261+ "uniqueConstraints": {
3262+ "mariadb_appName_unique": {
3263+ "name": "mariadb_appName_unique",
3264+ "nullsNotDistinct": false,
3265+ "columns": [
3266+ "appName"
3267+ ]
3268+ }
3269+ },
3270+ "policies": {},
3271+ "checkConstraints": {},
3272+ "isRLSEnabled": false
3273+ },
3274+ "public.mongo": {
3275+ "name": "mongo",
3276+ "schema": "",
3277+ "columns": {
3278+ "mongoId": {
3279+ "name": "mongoId",
3280+ "type": "text",
3281+ "primaryKey": true,
3282+ "notNull": true
3283+ },
3284+ "name": {
3285+ "name": "name",
3286+ "type": "text",
3287+ "primaryKey": false,
3288+ "notNull": true
3289+ },
3290+ "appName": {
3291+ "name": "appName",
3292+ "type": "text",
3293+ "primaryKey": false,
3294+ "notNull": true
3295+ },
3296+ "description": {
3297+ "name": "description",
3298+ "type": "text",
3299+ "primaryKey": false,
3300+ "notNull": false
3301+ },
3302+ "databaseUser": {
3303+ "name": "databaseUser",
3304+ "type": "text",
3305+ "primaryKey": false,
3306+ "notNull": true
3307+ },
3308+ "databasePassword": {
3309+ "name": "databasePassword",
3310+ "type": "text",
3311+ "primaryKey": false,
3312+ "notNull": true
3313+ },
3314+ "dockerImage": {
3315+ "name": "dockerImage",
3316+ "type": "text",
3317+ "primaryKey": false,
3318+ "notNull": true
3319+ },
3320+ "command": {
3321+ "name": "command",
3322+ "type": "text",
3323+ "primaryKey": false,
3324+ "notNull": false
3325+ },
3326+ "env": {
3327+ "name": "env",
3328+ "type": "text",
3329+ "primaryKey": false,
3330+ "notNull": false
3331+ },
3332+ "memoryReservation": {
3333+ "name": "memoryReservation",
3334+ "type": "text",
3335+ "primaryKey": false,
3336+ "notNull": false
3337+ },
3338+ "memoryLimit": {
3339+ "name": "memoryLimit",
3340+ "type": "text",
3341+ "primaryKey": false,
3342+ "notNull": false
3343+ },
3344+ "cpuReservation": {
3345+ "name": "cpuReservation",
3346+ "type": "text",
3347+ "primaryKey": false,
3348+ "notNull": false
3349+ },
3350+ "cpuLimit": {
3351+ "name": "cpuLimit",
3352+ "type": "text",
3353+ "primaryKey": false,
3354+ "notNull": false
3355+ },
3356+ "externalPort": {
3357+ "name": "externalPort",
3358+ "type": "integer",
3359+ "primaryKey": false,
3360+ "notNull": false
3361+ },
3362+ "applicationStatus": {
3363+ "name": "applicationStatus",
3364+ "type": "applicationStatus",
3365+ "typeSchema": "public",
3366+ "primaryKey": false,
3367+ "notNull": true,
3368+ "default": "'idle'"
3369+ },
3370+ "healthCheckSwarm": {
3371+ "name": "healthCheckSwarm",
3372+ "type": "json",
3373+ "primaryKey": false,
3374+ "notNull": false
3375+ },
3376+ "restartPolicySwarm": {
3377+ "name": "restartPolicySwarm",
3378+ "type": "json",
3379+ "primaryKey": false,
3380+ "notNull": false
3381+ },
3382+ "placementSwarm": {
3383+ "name": "placementSwarm",
3384+ "type": "json",
3385+ "primaryKey": false,
3386+ "notNull": false
3387+ },
3388+ "updateConfigSwarm": {
3389+ "name": "updateConfigSwarm",
3390+ "type": "json",
3391+ "primaryKey": false,
3392+ "notNull": false
3393+ },
3394+ "rollbackConfigSwarm": {
3395+ "name": "rollbackConfigSwarm",
3396+ "type": "json",
3397+ "primaryKey": false,
3398+ "notNull": false
3399+ },
3400+ "modeSwarm": {
3401+ "name": "modeSwarm",
3402+ "type": "json",
3403+ "primaryKey": false,
3404+ "notNull": false
3405+ },
3406+ "labelsSwarm": {
3407+ "name": "labelsSwarm",
3408+ "type": "json",
3409+ "primaryKey": false,
3410+ "notNull": false
3411+ },
3412+ "networkSwarm": {
3413+ "name": "networkSwarm",
3414+ "type": "json",
3415+ "primaryKey": false,
3416+ "notNull": false
3417+ },
3418+ "replicas": {
3419+ "name": "replicas",
3420+ "type": "integer",
3421+ "primaryKey": false,
3422+ "notNull": true,
3423+ "default": 1
3424+ },
3425+ "createdAt": {
3426+ "name": "createdAt",
3427+ "type": "text",
3428+ "primaryKey": false,
3429+ "notNull": true
3430+ },
3431+ "projectId": {
3432+ "name": "projectId",
3433+ "type": "text",
3434+ "primaryKey": false,
3435+ "notNull": true
3436+ },
3437+ "serverId": {
3438+ "name": "serverId",
3439+ "type": "text",
3440+ "primaryKey": false,
3441+ "notNull": false
3442+ },
3443+ "replicaSets": {
3444+ "name": "replicaSets",
3445+ "type": "boolean",
3446+ "primaryKey": false,
3447+ "notNull": false,
3448+ "default": false
3449+ }
3450+ },
3451+ "indexes": {},
3452+ "foreignKeys": {
3453+ "mongo_projectId_project_projectId_fk": {
3454+ "name": "mongo_projectId_project_projectId_fk",
3455+ "tableFrom": "mongo",
3456+ "tableTo": "project",
3457+ "columnsFrom": [
3458+ "projectId"
3459+ ],
3460+ "columnsTo": [
3461+ "projectId"
3462+ ],
3463+ "onDelete": "cascade",
3464+ "onUpdate": "no action"
3465+ },
3466+ "mongo_serverId_server_serverId_fk": {
3467+ "name": "mongo_serverId_server_serverId_fk",
3468+ "tableFrom": "mongo",
3469+ "tableTo": "server",
3470+ "columnsFrom": [
3471+ "serverId"
3472+ ],
3473+ "columnsTo": [
3474+ "serverId"
3475+ ],
3476+ "onDelete": "cascade",
3477+ "onUpdate": "no action"
3478+ }
3479+ },
3480+ "compositePrimaryKeys": {},
3481+ "uniqueConstraints": {
3482+ "mongo_appName_unique": {
3483+ "name": "mongo_appName_unique",
3484+ "nullsNotDistinct": false,
3485+ "columns": [
3486+ "appName"
3487+ ]
3488+ }
3489+ },
3490+ "policies": {},
3491+ "checkConstraints": {},
3492+ "isRLSEnabled": false
3493+ },
3494+ "public.mount": {
3495+ "name": "mount",
3496+ "schema": "",
3497+ "columns": {
3498+ "mountId": {
3499+ "name": "mountId",
3500+ "type": "text",
3501+ "primaryKey": true,
3502+ "notNull": true
3503+ },
3504+ "type": {
3505+ "name": "type",
3506+ "type": "mountType",
3507+ "typeSchema": "public",
3508+ "primaryKey": false,
3509+ "notNull": true
3510+ },
3511+ "hostPath": {
3512+ "name": "hostPath",
3513+ "type": "text",
3514+ "primaryKey": false,
3515+ "notNull": false
3516+ },
3517+ "volumeName": {
3518+ "name": "volumeName",
3519+ "type": "text",
3520+ "primaryKey": false,
3521+ "notNull": false
3522+ },
3523+ "filePath": {
3524+ "name": "filePath",
3525+ "type": "text",
3526+ "primaryKey": false,
3527+ "notNull": false
3528+ },
3529+ "content": {
3530+ "name": "content",
3531+ "type": "text",
3532+ "primaryKey": false,
3533+ "notNull": false
3534+ },
3535+ "serviceType": {
3536+ "name": "serviceType",
3537+ "type": "serviceType",
3538+ "typeSchema": "public",
3539+ "primaryKey": false,
3540+ "notNull": true,
3541+ "default": "'application'"
3542+ },
3543+ "mountPath": {
3544+ "name": "mountPath",
3545+ "type": "text",
3546+ "primaryKey": false,
3547+ "notNull": true
3548+ },
3549+ "applicationId": {
3550+ "name": "applicationId",
3551+ "type": "text",
3552+ "primaryKey": false,
3553+ "notNull": false
3554+ },
3555+ "postgresId": {
3556+ "name": "postgresId",
3557+ "type": "text",
3558+ "primaryKey": false,
3559+ "notNull": false
3560+ },
3561+ "mariadbId": {
3562+ "name": "mariadbId",
3563+ "type": "text",
3564+ "primaryKey": false,
3565+ "notNull": false
3566+ },
3567+ "mongoId": {
3568+ "name": "mongoId",
3569+ "type": "text",
3570+ "primaryKey": false,
3571+ "notNull": false
3572+ },
3573+ "mysqlId": {
3574+ "name": "mysqlId",
3575+ "type": "text",
3576+ "primaryKey": false,
3577+ "notNull": false
3578+ },
3579+ "redisId": {
3580+ "name": "redisId",
3581+ "type": "text",
3582+ "primaryKey": false,
3583+ "notNull": false
3584+ },
3585+ "composeId": {
3586+ "name": "composeId",
3587+ "type": "text",
3588+ "primaryKey": false,
3589+ "notNull": false
3590+ }
3591+ },
3592+ "indexes": {},
3593+ "foreignKeys": {
3594+ "mount_applicationId_application_applicationId_fk": {
3595+ "name": "mount_applicationId_application_applicationId_fk",
3596+ "tableFrom": "mount",
3597+ "tableTo": "application",
3598+ "columnsFrom": [
3599+ "applicationId"
3600+ ],
3601+ "columnsTo": [
3602+ "applicationId"
3603+ ],
3604+ "onDelete": "cascade",
3605+ "onUpdate": "no action"
3606+ },
3607+ "mount_postgresId_postgres_postgresId_fk": {
3608+ "name": "mount_postgresId_postgres_postgresId_fk",
3609+ "tableFrom": "mount",
3610+ "tableTo": "postgres",
3611+ "columnsFrom": [
3612+ "postgresId"
3613+ ],
3614+ "columnsTo": [
3615+ "postgresId"
3616+ ],
3617+ "onDelete": "cascade",
3618+ "onUpdate": "no action"
3619+ },
3620+ "mount_mariadbId_mariadb_mariadbId_fk": {
3621+ "name": "mount_mariadbId_mariadb_mariadbId_fk",
3622+ "tableFrom": "mount",
3623+ "tableTo": "mariadb",
3624+ "columnsFrom": [
3625+ "mariadbId"
3626+ ],
3627+ "columnsTo": [
3628+ "mariadbId"
3629+ ],
3630+ "onDelete": "cascade",
3631+ "onUpdate": "no action"
3632+ },
3633+ "mount_mongoId_mongo_mongoId_fk": {
3634+ "name": "mount_mongoId_mongo_mongoId_fk",
3635+ "tableFrom": "mount",
3636+ "tableTo": "mongo",
3637+ "columnsFrom": [
3638+ "mongoId"
3639+ ],
3640+ "columnsTo": [
3641+ "mongoId"
3642+ ],
3643+ "onDelete": "cascade",
3644+ "onUpdate": "no action"
3645+ },
3646+ "mount_mysqlId_mysql_mysqlId_fk": {
3647+ "name": "mount_mysqlId_mysql_mysqlId_fk",
3648+ "tableFrom": "mount",
3649+ "tableTo": "mysql",
3650+ "columnsFrom": [
3651+ "mysqlId"
3652+ ],
3653+ "columnsTo": [
3654+ "mysqlId"
3655+ ],
3656+ "onDelete": "cascade",
3657+ "onUpdate": "no action"
3658+ },
3659+ "mount_redisId_redis_redisId_fk": {
3660+ "name": "mount_redisId_redis_redisId_fk",
3661+ "tableFrom": "mount",
3662+ "tableTo": "redis",
3663+ "columnsFrom": [
3664+ "redisId"
3665+ ],
3666+ "columnsTo": [
3667+ "redisId"
3668+ ],
3669+ "onDelete": "cascade",
3670+ "onUpdate": "no action"
3671+ },
3672+ "mount_composeId_compose_composeId_fk": {
3673+ "name": "mount_composeId_compose_composeId_fk",
3674+ "tableFrom": "mount",
3675+ "tableTo": "compose",
3676+ "columnsFrom": [
3677+ "composeId"
3678+ ],
3679+ "columnsTo": [
3680+ "composeId"
3681+ ],
3682+ "onDelete": "cascade",
3683+ "onUpdate": "no action"
3684+ }
3685+ },
3686+ "compositePrimaryKeys": {},
3687+ "uniqueConstraints": {},
3688+ "policies": {},
3689+ "checkConstraints": {},
3690+ "isRLSEnabled": false
3691+ },
3692+ "public.mysql": {
3693+ "name": "mysql",
3694+ "schema": "",
3695+ "columns": {
3696+ "mysqlId": {
3697+ "name": "mysqlId",
3698+ "type": "text",
3699+ "primaryKey": true,
3700+ "notNull": true
3701+ },
3702+ "name": {
3703+ "name": "name",
3704+ "type": "text",
3705+ "primaryKey": false,
3706+ "notNull": true
3707+ },
3708+ "appName": {
3709+ "name": "appName",
3710+ "type": "text",
3711+ "primaryKey": false,
3712+ "notNull": true
3713+ },
3714+ "description": {
3715+ "name": "description",
3716+ "type": "text",
3717+ "primaryKey": false,
3718+ "notNull": false
3719+ },
3720+ "databaseName": {
3721+ "name": "databaseName",
3722+ "type": "text",
3723+ "primaryKey": false,
3724+ "notNull": true
3725+ },
3726+ "databaseUser": {
3727+ "name": "databaseUser",
3728+ "type": "text",
3729+ "primaryKey": false,
3730+ "notNull": true
3731+ },
3732+ "databasePassword": {
3733+ "name": "databasePassword",
3734+ "type": "text",
3735+ "primaryKey": false,
3736+ "notNull": true
3737+ },
3738+ "rootPassword": {
3739+ "name": "rootPassword",
3740+ "type": "text",
3741+ "primaryKey": false,
3742+ "notNull": true
3743+ },
3744+ "dockerImage": {
3745+ "name": "dockerImage",
3746+ "type": "text",
3747+ "primaryKey": false,
3748+ "notNull": true
3749+ },
3750+ "command": {
3751+ "name": "command",
3752+ "type": "text",
3753+ "primaryKey": false,
3754+ "notNull": false
3755+ },
3756+ "env": {
3757+ "name": "env",
3758+ "type": "text",
3759+ "primaryKey": false,
3760+ "notNull": false
3761+ },
3762+ "memoryReservation": {
3763+ "name": "memoryReservation",
3764+ "type": "text",
3765+ "primaryKey": false,
3766+ "notNull": false
3767+ },
3768+ "memoryLimit": {
3769+ "name": "memoryLimit",
3770+ "type": "text",
3771+ "primaryKey": false,
3772+ "notNull": false
3773+ },
3774+ "cpuReservation": {
3775+ "name": "cpuReservation",
3776+ "type": "text",
3777+ "primaryKey": false,
3778+ "notNull": false
3779+ },
3780+ "cpuLimit": {
3781+ "name": "cpuLimit",
3782+ "type": "text",
3783+ "primaryKey": false,
3784+ "notNull": false
3785+ },
3786+ "externalPort": {
3787+ "name": "externalPort",
3788+ "type": "integer",
3789+ "primaryKey": false,
3790+ "notNull": false
3791+ },
3792+ "applicationStatus": {
3793+ "name": "applicationStatus",
3794+ "type": "applicationStatus",
3795+ "typeSchema": "public",
3796+ "primaryKey": false,
3797+ "notNull": true,
3798+ "default": "'idle'"
3799+ },
3800+ "healthCheckSwarm": {
3801+ "name": "healthCheckSwarm",
3802+ "type": "json",
3803+ "primaryKey": false,
3804+ "notNull": false
3805+ },
3806+ "restartPolicySwarm": {
3807+ "name": "restartPolicySwarm",
3808+ "type": "json",
3809+ "primaryKey": false,
3810+ "notNull": false
3811+ },
3812+ "placementSwarm": {
3813+ "name": "placementSwarm",
3814+ "type": "json",
3815+ "primaryKey": false,
3816+ "notNull": false
3817+ },
3818+ "updateConfigSwarm": {
3819+ "name": "updateConfigSwarm",
3820+ "type": "json",
3821+ "primaryKey": false,
3822+ "notNull": false
3823+ },
3824+ "rollbackConfigSwarm": {
3825+ "name": "rollbackConfigSwarm",
3826+ "type": "json",
3827+ "primaryKey": false,
3828+ "notNull": false
3829+ },
3830+ "modeSwarm": {
3831+ "name": "modeSwarm",
3832+ "type": "json",
3833+ "primaryKey": false,
3834+ "notNull": false
3835+ },
3836+ "labelsSwarm": {
3837+ "name": "labelsSwarm",
3838+ "type": "json",
3839+ "primaryKey": false,
3840+ "notNull": false
3841+ },
3842+ "networkSwarm": {
3843+ "name": "networkSwarm",
3844+ "type": "json",
3845+ "primaryKey": false,
3846+ "notNull": false
3847+ },
3848+ "replicas": {
3849+ "name": "replicas",
3850+ "type": "integer",
3851+ "primaryKey": false,
3852+ "notNull": true,
3853+ "default": 1
3854+ },
3855+ "createdAt": {
3856+ "name": "createdAt",
3857+ "type": "text",
3858+ "primaryKey": false,
3859+ "notNull": true
3860+ },
3861+ "projectId": {
3862+ "name": "projectId",
3863+ "type": "text",
3864+ "primaryKey": false,
3865+ "notNull": true
3866+ },
3867+ "serverId": {
3868+ "name": "serverId",
3869+ "type": "text",
3870+ "primaryKey": false,
3871+ "notNull": false
3872+ }
3873+ },
3874+ "indexes": {},
3875+ "foreignKeys": {
3876+ "mysql_projectId_project_projectId_fk": {
3877+ "name": "mysql_projectId_project_projectId_fk",
3878+ "tableFrom": "mysql",
3879+ "tableTo": "project",
3880+ "columnsFrom": [
3881+ "projectId"
3882+ ],
3883+ "columnsTo": [
3884+ "projectId"
3885+ ],
3886+ "onDelete": "cascade",
3887+ "onUpdate": "no action"
3888+ },
3889+ "mysql_serverId_server_serverId_fk": {
3890+ "name": "mysql_serverId_server_serverId_fk",
3891+ "tableFrom": "mysql",
3892+ "tableTo": "server",
3893+ "columnsFrom": [
3894+ "serverId"
3895+ ],
3896+ "columnsTo": [
3897+ "serverId"
3898+ ],
3899+ "onDelete": "cascade",
3900+ "onUpdate": "no action"
3901+ }
3902+ },
3903+ "compositePrimaryKeys": {},
3904+ "uniqueConstraints": {
3905+ "mysql_appName_unique": {
3906+ "name": "mysql_appName_unique",
3907+ "nullsNotDistinct": false,
3908+ "columns": [
3909+ "appName"
3910+ ]
3911+ }
3912+ },
3913+ "policies": {},
3914+ "checkConstraints": {},
3915+ "isRLSEnabled": false
3916+ },
3917+ "public.discord": {
3918+ "name": "discord",
3919+ "schema": "",
3920+ "columns": {
3921+ "discordId": {
3922+ "name": "discordId",
3923+ "type": "text",
3924+ "primaryKey": true,
3925+ "notNull": true
3926+ },
3927+ "webhookUrl": {
3928+ "name": "webhookUrl",
3929+ "type": "text",
3930+ "primaryKey": false,
3931+ "notNull": true
3932+ },
3933+ "decoration": {
3934+ "name": "decoration",
3935+ "type": "boolean",
3936+ "primaryKey": false,
3937+ "notNull": false
3938+ }
3939+ },
3940+ "indexes": {},
3941+ "foreignKeys": {},
3942+ "compositePrimaryKeys": {},
3943+ "uniqueConstraints": {},
3944+ "policies": {},
3945+ "checkConstraints": {},
3946+ "isRLSEnabled": false
3947+ },
3948+ "public.email": {
3949+ "name": "email",
3950+ "schema": "",
3951+ "columns": {
3952+ "emailId": {
3953+ "name": "emailId",
3954+ "type": "text",
3955+ "primaryKey": true,
3956+ "notNull": true
3957+ },
3958+ "smtpServer": {
3959+ "name": "smtpServer",
3960+ "type": "text",
3961+ "primaryKey": false,
3962+ "notNull": true
3963+ },
3964+ "smtpPort": {
3965+ "name": "smtpPort",
3966+ "type": "integer",
3967+ "primaryKey": false,
3968+ "notNull": true
3969+ },
3970+ "username": {
3971+ "name": "username",
3972+ "type": "text",
3973+ "primaryKey": false,
3974+ "notNull": true
3975+ },
3976+ "password": {
3977+ "name": "password",
3978+ "type": "text",
3979+ "primaryKey": false,
3980+ "notNull": true
3981+ },
3982+ "fromAddress": {
3983+ "name": "fromAddress",
3984+ "type": "text",
3985+ "primaryKey": false,
3986+ "notNull": true
3987+ },
3988+ "toAddress": {
3989+ "name": "toAddress",
3990+ "type": "text[]",
3991+ "primaryKey": false,
3992+ "notNull": true
3993+ }
3994+ },
3995+ "indexes": {},
3996+ "foreignKeys": {},
3997+ "compositePrimaryKeys": {},
3998+ "uniqueConstraints": {},
3999+ "policies": {},
4000+ "checkConstraints": {},
4001+ "isRLSEnabled": false
4002+ },
4003+ "public.gotify": {
4004+ "name": "gotify",
4005+ "schema": "",
4006+ "columns": {
4007+ "gotifyId": {
4008+ "name": "gotifyId",
4009+ "type": "text",
4010+ "primaryKey": true,
4011+ "notNull": true
4012+ },
4013+ "serverUrl": {
4014+ "name": "serverUrl",
4015+ "type": "text",
4016+ "primaryKey": false,
4017+ "notNull": true
4018+ },
4019+ "appToken": {
4020+ "name": "appToken",
4021+ "type": "text",
4022+ "primaryKey": false,
4023+ "notNull": true
4024+ },
4025+ "priority": {
4026+ "name": "priority",
4027+ "type": "integer",
4028+ "primaryKey": false,
4029+ "notNull": true,
4030+ "default": 5
4031+ },
4032+ "decoration": {
4033+ "name": "decoration",
4034+ "type": "boolean",
4035+ "primaryKey": false,
4036+ "notNull": false
4037+ }
4038+ },
4039+ "indexes": {},
4040+ "foreignKeys": {},
4041+ "compositePrimaryKeys": {},
4042+ "uniqueConstraints": {},
4043+ "policies": {},
4044+ "checkConstraints": {},
4045+ "isRLSEnabled": false
4046+ },
4047+ "public.notification": {
4048+ "name": "notification",
4049+ "schema": "",
4050+ "columns": {
4051+ "notificationId": {
4052+ "name": "notificationId",
4053+ "type": "text",
4054+ "primaryKey": true,
4055+ "notNull": true
4056+ },
4057+ "name": {
4058+ "name": "name",
4059+ "type": "text",
4060+ "primaryKey": false,
4061+ "notNull": true
4062+ },
4063+ "appDeploy": {
4064+ "name": "appDeploy",
4065+ "type": "boolean",
4066+ "primaryKey": false,
4067+ "notNull": true,
4068+ "default": false
4069+ },
4070+ "appBuildError": {
4071+ "name": "appBuildError",
4072+ "type": "boolean",
4073+ "primaryKey": false,
4074+ "notNull": true,
4075+ "default": false
4076+ },
4077+ "databaseBackup": {
4078+ "name": "databaseBackup",
4079+ "type": "boolean",
4080+ "primaryKey": false,
4081+ "notNull": true,
4082+ "default": false
4083+ },
4084+ "dokployRestart": {
4085+ "name": "dokployRestart",
4086+ "type": "boolean",
4087+ "primaryKey": false,
4088+ "notNull": true,
4089+ "default": false
4090+ },
4091+ "dockerCleanup": {
4092+ "name": "dockerCleanup",
4093+ "type": "boolean",
4094+ "primaryKey": false,
4095+ "notNull": true,
4096+ "default": false
4097+ },
4098+ "serverThreshold": {
4099+ "name": "serverThreshold",
4100+ "type": "boolean",
4101+ "primaryKey": false,
4102+ "notNull": true,
4103+ "default": false
4104+ },
4105+ "notificationType": {
4106+ "name": "notificationType",
4107+ "type": "notificationType",
4108+ "typeSchema": "public",
4109+ "primaryKey": false,
4110+ "notNull": true
4111+ },
4112+ "createdAt": {
4113+ "name": "createdAt",
4114+ "type": "text",
4115+ "primaryKey": false,
4116+ "notNull": true
4117+ },
4118+ "slackId": {
4119+ "name": "slackId",
4120+ "type": "text",
4121+ "primaryKey": false,
4122+ "notNull": false
4123+ },
4124+ "telegramId": {
4125+ "name": "telegramId",
4126+ "type": "text",
4127+ "primaryKey": false,
4128+ "notNull": false
4129+ },
4130+ "discordId": {
4131+ "name": "discordId",
4132+ "type": "text",
4133+ "primaryKey": false,
4134+ "notNull": false
4135+ },
4136+ "emailId": {
4137+ "name": "emailId",
4138+ "type": "text",
4139+ "primaryKey": false,
4140+ "notNull": false
4141+ },
4142+ "gotifyId": {
4143+ "name": "gotifyId",
4144+ "type": "text",
4145+ "primaryKey": false,
4146+ "notNull": false
4147+ },
4148+ "organizationId": {
4149+ "name": "organizationId",
4150+ "type": "text",
4151+ "primaryKey": false,
4152+ "notNull": true
4153+ }
4154+ },
4155+ "indexes": {},
4156+ "foreignKeys": {
4157+ "notification_slackId_slack_slackId_fk": {
4158+ "name": "notification_slackId_slack_slackId_fk",
4159+ "tableFrom": "notification",
4160+ "tableTo": "slack",
4161+ "columnsFrom": [
4162+ "slackId"
4163+ ],
4164+ "columnsTo": [
4165+ "slackId"
4166+ ],
4167+ "onDelete": "cascade",
4168+ "onUpdate": "no action"
4169+ },
4170+ "notification_telegramId_telegram_telegramId_fk": {
4171+ "name": "notification_telegramId_telegram_telegramId_fk",
4172+ "tableFrom": "notification",
4173+ "tableTo": "telegram",
4174+ "columnsFrom": [
4175+ "telegramId"
4176+ ],
4177+ "columnsTo": [
4178+ "telegramId"
4179+ ],
4180+ "onDelete": "cascade",
4181+ "onUpdate": "no action"
4182+ },
4183+ "notification_discordId_discord_discordId_fk": {
4184+ "name": "notification_discordId_discord_discordId_fk",
4185+ "tableFrom": "notification",
4186+ "tableTo": "discord",
4187+ "columnsFrom": [
4188+ "discordId"
4189+ ],
4190+ "columnsTo": [
4191+ "discordId"
4192+ ],
4193+ "onDelete": "cascade",
4194+ "onUpdate": "no action"
4195+ },
4196+ "notification_emailId_email_emailId_fk": {
4197+ "name": "notification_emailId_email_emailId_fk",
4198+ "tableFrom": "notification",
4199+ "tableTo": "email",
4200+ "columnsFrom": [
4201+ "emailId"
4202+ ],
4203+ "columnsTo": [
4204+ "emailId"
4205+ ],
4206+ "onDelete": "cascade",
4207+ "onUpdate": "no action"
4208+ },
4209+ "notification_gotifyId_gotify_gotifyId_fk": {
4210+ "name": "notification_gotifyId_gotify_gotifyId_fk",
4211+ "tableFrom": "notification",
4212+ "tableTo": "gotify",
4213+ "columnsFrom": [
4214+ "gotifyId"
4215+ ],
4216+ "columnsTo": [
4217+ "gotifyId"
4218+ ],
4219+ "onDelete": "cascade",
4220+ "onUpdate": "no action"
4221+ },
4222+ "notification_organizationId_organization_id_fk": {
4223+ "name": "notification_organizationId_organization_id_fk",
4224+ "tableFrom": "notification",
4225+ "tableTo": "organization",
4226+ "columnsFrom": [
4227+ "organizationId"
4228+ ],
4229+ "columnsTo": [
4230+ "id"
4231+ ],
4232+ "onDelete": "cascade",
4233+ "onUpdate": "no action"
4234+ }
4235+ },
4236+ "compositePrimaryKeys": {},
4237+ "uniqueConstraints": {},
4238+ "policies": {},
4239+ "checkConstraints": {},
4240+ "isRLSEnabled": false
4241+ },
4242+ "public.slack": {
4243+ "name": "slack",
4244+ "schema": "",
4245+ "columns": {
4246+ "slackId": {
4247+ "name": "slackId",
4248+ "type": "text",
4249+ "primaryKey": true,
4250+ "notNull": true
4251+ },
4252+ "webhookUrl": {
4253+ "name": "webhookUrl",
4254+ "type": "text",
4255+ "primaryKey": false,
4256+ "notNull": true
4257+ },
4258+ "channel": {
4259+ "name": "channel",
4260+ "type": "text",
4261+ "primaryKey": false,
4262+ "notNull": false
4263+ }
4264+ },
4265+ "indexes": {},
4266+ "foreignKeys": {},
4267+ "compositePrimaryKeys": {},
4268+ "uniqueConstraints": {},
4269+ "policies": {},
4270+ "checkConstraints": {},
4271+ "isRLSEnabled": false
4272+ },
4273+ "public.telegram": {
4274+ "name": "telegram",
4275+ "schema": "",
4276+ "columns": {
4277+ "telegramId": {
4278+ "name": "telegramId",
4279+ "type": "text",
4280+ "primaryKey": true,
4281+ "notNull": true
4282+ },
4283+ "botToken": {
4284+ "name": "botToken",
4285+ "type": "text",
4286+ "primaryKey": false,
4287+ "notNull": true
4288+ },
4289+ "chatId": {
4290+ "name": "chatId",
4291+ "type": "text",
4292+ "primaryKey": false,
4293+ "notNull": true
4294+ },
4295+ "messageThreadId": {
4296+ "name": "messageThreadId",
4297+ "type": "text",
4298+ "primaryKey": false,
4299+ "notNull": false
4300+ }
4301+ },
4302+ "indexes": {},
4303+ "foreignKeys": {},
4304+ "compositePrimaryKeys": {},
4305+ "uniqueConstraints": {},
4306+ "policies": {},
4307+ "checkConstraints": {},
4308+ "isRLSEnabled": false
4309+ },
4310+ "public.port": {
4311+ "name": "port",
4312+ "schema": "",
4313+ "columns": {
4314+ "portId": {
4315+ "name": "portId",
4316+ "type": "text",
4317+ "primaryKey": true,
4318+ "notNull": true
4319+ },
4320+ "publishedPort": {
4321+ "name": "publishedPort",
4322+ "type": "integer",
4323+ "primaryKey": false,
4324+ "notNull": true
4325+ },
4326+ "publishMode": {
4327+ "name": "publishMode",
4328+ "type": "publishModeType",
4329+ "typeSchema": "public",
4330+ "primaryKey": false,
4331+ "notNull": true,
4332+ "default": "'host'"
4333+ },
4334+ "targetPort": {
4335+ "name": "targetPort",
4336+ "type": "integer",
4337+ "primaryKey": false,
4338+ "notNull": true
4339+ },
4340+ "protocol": {
4341+ "name": "protocol",
4342+ "type": "protocolType",
4343+ "typeSchema": "public",
4344+ "primaryKey": false,
4345+ "notNull": true
4346+ },
4347+ "applicationId": {
4348+ "name": "applicationId",
4349+ "type": "text",
4350+ "primaryKey": false,
4351+ "notNull": true
4352+ }
4353+ },
4354+ "indexes": {},
4355+ "foreignKeys": {
4356+ "port_applicationId_application_applicationId_fk": {
4357+ "name": "port_applicationId_application_applicationId_fk",
4358+ "tableFrom": "port",
4359+ "tableTo": "application",
4360+ "columnsFrom": [
4361+ "applicationId"
4362+ ],
4363+ "columnsTo": [
4364+ "applicationId"
4365+ ],
4366+ "onDelete": "cascade",
4367+ "onUpdate": "no action"
4368+ }
4369+ },
4370+ "compositePrimaryKeys": {},
4371+ "uniqueConstraints": {},
4372+ "policies": {},
4373+ "checkConstraints": {},
4374+ "isRLSEnabled": false
4375+ },
4376+ "public.postgres": {
4377+ "name": "postgres",
4378+ "schema": "",
4379+ "columns": {
4380+ "postgresId": {
4381+ "name": "postgresId",
4382+ "type": "text",
4383+ "primaryKey": true,
4384+ "notNull": true
4385+ },
4386+ "name": {
4387+ "name": "name",
4388+ "type": "text",
4389+ "primaryKey": false,
4390+ "notNull": true
4391+ },
4392+ "appName": {
4393+ "name": "appName",
4394+ "type": "text",
4395+ "primaryKey": false,
4396+ "notNull": true
4397+ },
4398+ "databaseName": {
4399+ "name": "databaseName",
4400+ "type": "text",
4401+ "primaryKey": false,
4402+ "notNull": true
4403+ },
4404+ "databaseUser": {
4405+ "name": "databaseUser",
4406+ "type": "text",
4407+ "primaryKey": false,
4408+ "notNull": true
4409+ },
4410+ "databasePassword": {
4411+ "name": "databasePassword",
4412+ "type": "text",
4413+ "primaryKey": false,
4414+ "notNull": true
4415+ },
4416+ "description": {
4417+ "name": "description",
4418+ "type": "text",
4419+ "primaryKey": false,
4420+ "notNull": false
4421+ },
4422+ "dockerImage": {
4423+ "name": "dockerImage",
4424+ "type": "text",
4425+ "primaryKey": false,
4426+ "notNull": true
4427+ },
4428+ "command": {
4429+ "name": "command",
4430+ "type": "text",
4431+ "primaryKey": false,
4432+ "notNull": false
4433+ },
4434+ "env": {
4435+ "name": "env",
4436+ "type": "text",
4437+ "primaryKey": false,
4438+ "notNull": false
4439+ },
4440+ "memoryReservation": {
4441+ "name": "memoryReservation",
4442+ "type": "text",
4443+ "primaryKey": false,
4444+ "notNull": false
4445+ },
4446+ "externalPort": {
4447+ "name": "externalPort",
4448+ "type": "integer",
4449+ "primaryKey": false,
4450+ "notNull": false
4451+ },
4452+ "memoryLimit": {
4453+ "name": "memoryLimit",
4454+ "type": "text",
4455+ "primaryKey": false,
4456+ "notNull": false
4457+ },
4458+ "cpuReservation": {
4459+ "name": "cpuReservation",
4460+ "type": "text",
4461+ "primaryKey": false,
4462+ "notNull": false
4463+ },
4464+ "cpuLimit": {
4465+ "name": "cpuLimit",
4466+ "type": "text",
4467+ "primaryKey": false,
4468+ "notNull": false
4469+ },
4470+ "applicationStatus": {
4471+ "name": "applicationStatus",
4472+ "type": "applicationStatus",
4473+ "typeSchema": "public",
4474+ "primaryKey": false,
4475+ "notNull": true,
4476+ "default": "'idle'"
4477+ },
4478+ "healthCheckSwarm": {
4479+ "name": "healthCheckSwarm",
4480+ "type": "json",
4481+ "primaryKey": false,
4482+ "notNull": false
4483+ },
4484+ "restartPolicySwarm": {
4485+ "name": "restartPolicySwarm",
4486+ "type": "json",
4487+ "primaryKey": false,
4488+ "notNull": false
4489+ },
4490+ "placementSwarm": {
4491+ "name": "placementSwarm",
4492+ "type": "json",
4493+ "primaryKey": false,
4494+ "notNull": false
4495+ },
4496+ "updateConfigSwarm": {
4497+ "name": "updateConfigSwarm",
4498+ "type": "json",
4499+ "primaryKey": false,
4500+ "notNull": false
4501+ },
4502+ "rollbackConfigSwarm": {
4503+ "name": "rollbackConfigSwarm",
4504+ "type": "json",
4505+ "primaryKey": false,
4506+ "notNull": false
4507+ },
4508+ "modeSwarm": {
4509+ "name": "modeSwarm",
4510+ "type": "json",
4511+ "primaryKey": false,
4512+ "notNull": false
4513+ },
4514+ "labelsSwarm": {
4515+ "name": "labelsSwarm",
4516+ "type": "json",
4517+ "primaryKey": false,
4518+ "notNull": false
4519+ },
4520+ "networkSwarm": {
4521+ "name": "networkSwarm",
4522+ "type": "json",
4523+ "primaryKey": false,
4524+ "notNull": false
4525+ },
4526+ "replicas": {
4527+ "name": "replicas",
4528+ "type": "integer",
4529+ "primaryKey": false,
4530+ "notNull": true,
4531+ "default": 1
4532+ },
4533+ "createdAt": {
4534+ "name": "createdAt",
4535+ "type": "text",
4536+ "primaryKey": false,
4537+ "notNull": true
4538+ },
4539+ "projectId": {
4540+ "name": "projectId",
4541+ "type": "text",
4542+ "primaryKey": false,
4543+ "notNull": true
4544+ },
4545+ "serverId": {
4546+ "name": "serverId",
4547+ "type": "text",
4548+ "primaryKey": false,
4549+ "notNull": false
4550+ }
4551+ },
4552+ "indexes": {},
4553+ "foreignKeys": {
4554+ "postgres_projectId_project_projectId_fk": {
4555+ "name": "postgres_projectId_project_projectId_fk",
4556+ "tableFrom": "postgres",
4557+ "tableTo": "project",
4558+ "columnsFrom": [
4559+ "projectId"
4560+ ],
4561+ "columnsTo": [
4562+ "projectId"
4563+ ],
4564+ "onDelete": "cascade",
4565+ "onUpdate": "no action"
4566+ },
4567+ "postgres_serverId_server_serverId_fk": {
4568+ "name": "postgres_serverId_server_serverId_fk",
4569+ "tableFrom": "postgres",
4570+ "tableTo": "server",
4571+ "columnsFrom": [
4572+ "serverId"
4573+ ],
4574+ "columnsTo": [
4575+ "serverId"
4576+ ],
4577+ "onDelete": "cascade",
4578+ "onUpdate": "no action"
4579+ }
4580+ },
4581+ "compositePrimaryKeys": {},
4582+ "uniqueConstraints": {
4583+ "postgres_appName_unique": {
4584+ "name": "postgres_appName_unique",
4585+ "nullsNotDistinct": false,
4586+ "columns": [
4587+ "appName"
4588+ ]
4589+ }
4590+ },
4591+ "policies": {},
4592+ "checkConstraints": {},
4593+ "isRLSEnabled": false
4594+ },
4595+ "public.preview_deployments": {
4596+ "name": "preview_deployments",
4597+ "schema": "",
4598+ "columns": {
4599+ "previewDeploymentId": {
4600+ "name": "previewDeploymentId",
4601+ "type": "text",
4602+ "primaryKey": true,
4603+ "notNull": true
4604+ },
4605+ "branch": {
4606+ "name": "branch",
4607+ "type": "text",
4608+ "primaryKey": false,
4609+ "notNull": true
4610+ },
4611+ "pullRequestId": {
4612+ "name": "pullRequestId",
4613+ "type": "text",
4614+ "primaryKey": false,
4615+ "notNull": true
4616+ },
4617+ "pullRequestNumber": {
4618+ "name": "pullRequestNumber",
4619+ "type": "text",
4620+ "primaryKey": false,
4621+ "notNull": true
4622+ },
4623+ "pullRequestURL": {
4624+ "name": "pullRequestURL",
4625+ "type": "text",
4626+ "primaryKey": false,
4627+ "notNull": true
4628+ },
4629+ "pullRequestTitle": {
4630+ "name": "pullRequestTitle",
4631+ "type": "text",
4632+ "primaryKey": false,
4633+ "notNull": true
4634+ },
4635+ "pullRequestCommentId": {
4636+ "name": "pullRequestCommentId",
4637+ "type": "text",
4638+ "primaryKey": false,
4639+ "notNull": true
4640+ },
4641+ "previewStatus": {
4642+ "name": "previewStatus",
4643+ "type": "applicationStatus",
4644+ "typeSchema": "public",
4645+ "primaryKey": false,
4646+ "notNull": true,
4647+ "default": "'idle'"
4648+ },
4649+ "appName": {
4650+ "name": "appName",
4651+ "type": "text",
4652+ "primaryKey": false,
4653+ "notNull": true
4654+ },
4655+ "applicationId": {
4656+ "name": "applicationId",
4657+ "type": "text",
4658+ "primaryKey": false,
4659+ "notNull": true
4660+ },
4661+ "domainId": {
4662+ "name": "domainId",
4663+ "type": "text",
4664+ "primaryKey": false,
4665+ "notNull": false
4666+ },
4667+ "createdAt": {
4668+ "name": "createdAt",
4669+ "type": "text",
4670+ "primaryKey": false,
4671+ "notNull": true
4672+ },
4673+ "expiresAt": {
4674+ "name": "expiresAt",
4675+ "type": "text",
4676+ "primaryKey": false,
4677+ "notNull": false
4678+ }
4679+ },
4680+ "indexes": {},
4681+ "foreignKeys": {
4682+ "preview_deployments_applicationId_application_applicationId_fk": {
4683+ "name": "preview_deployments_applicationId_application_applicationId_fk",
4684+ "tableFrom": "preview_deployments",
4685+ "tableTo": "application",
4686+ "columnsFrom": [
4687+ "applicationId"
4688+ ],
4689+ "columnsTo": [
4690+ "applicationId"
4691+ ],
4692+ "onDelete": "cascade",
4693+ "onUpdate": "no action"
4694+ },
4695+ "preview_deployments_domainId_domain_domainId_fk": {
4696+ "name": "preview_deployments_domainId_domain_domainId_fk",
4697+ "tableFrom": "preview_deployments",
4698+ "tableTo": "domain",
4699+ "columnsFrom": [
4700+ "domainId"
4701+ ],
4702+ "columnsTo": [
4703+ "domainId"
4704+ ],
4705+ "onDelete": "cascade",
4706+ "onUpdate": "no action"
4707+ }
4708+ },
4709+ "compositePrimaryKeys": {},
4710+ "uniqueConstraints": {
4711+ "preview_deployments_appName_unique": {
4712+ "name": "preview_deployments_appName_unique",
4713+ "nullsNotDistinct": false,
4714+ "columns": [
4715+ "appName"
4716+ ]
4717+ }
4718+ },
4719+ "policies": {},
4720+ "checkConstraints": {},
4721+ "isRLSEnabled": false
4722+ },
4723+ "public.project": {
4724+ "name": "project",
4725+ "schema": "",
4726+ "columns": {
4727+ "projectId": {
4728+ "name": "projectId",
4729+ "type": "text",
4730+ "primaryKey": true,
4731+ "notNull": true
4732+ },
4733+ "name": {
4734+ "name": "name",
4735+ "type": "text",
4736+ "primaryKey": false,
4737+ "notNull": true
4738+ },
4739+ "description": {
4740+ "name": "description",
4741+ "type": "text",
4742+ "primaryKey": false,
4743+ "notNull": false
4744+ },
4745+ "createdAt": {
4746+ "name": "createdAt",
4747+ "type": "text",
4748+ "primaryKey": false,
4749+ "notNull": true
4750+ },
4751+ "organizationId": {
4752+ "name": "organizationId",
4753+ "type": "text",
4754+ "primaryKey": false,
4755+ "notNull": true
4756+ },
4757+ "env": {
4758+ "name": "env",
4759+ "type": "text",
4760+ "primaryKey": false,
4761+ "notNull": true,
4762+ "default": "''"
4763+ }
4764+ },
4765+ "indexes": {},
4766+ "foreignKeys": {
4767+ "project_organizationId_organization_id_fk": {
4768+ "name": "project_organizationId_organization_id_fk",
4769+ "tableFrom": "project",
4770+ "tableTo": "organization",
4771+ "columnsFrom": [
4772+ "organizationId"
4773+ ],
4774+ "columnsTo": [
4775+ "id"
4776+ ],
4777+ "onDelete": "cascade",
4778+ "onUpdate": "no action"
4779+ }
4780+ },
4781+ "compositePrimaryKeys": {},
4782+ "uniqueConstraints": {},
4783+ "policies": {},
4784+ "checkConstraints": {},
4785+ "isRLSEnabled": false
4786+ },
4787+ "public.redirect": {
4788+ "name": "redirect",
4789+ "schema": "",
4790+ "columns": {
4791+ "redirectId": {
4792+ "name": "redirectId",
4793+ "type": "text",
4794+ "primaryKey": true,
4795+ "notNull": true
4796+ },
4797+ "regex": {
4798+ "name": "regex",
4799+ "type": "text",
4800+ "primaryKey": false,
4801+ "notNull": true
4802+ },
4803+ "replacement": {
4804+ "name": "replacement",
4805+ "type": "text",
4806+ "primaryKey": false,
4807+ "notNull": true
4808+ },
4809+ "permanent": {
4810+ "name": "permanent",
4811+ "type": "boolean",
4812+ "primaryKey": false,
4813+ "notNull": true,
4814+ "default": false
4815+ },
4816+ "uniqueConfigKey": {
4817+ "name": "uniqueConfigKey",
4818+ "type": "serial",
4819+ "primaryKey": false,
4820+ "notNull": true
4821+ },
4822+ "createdAt": {
4823+ "name": "createdAt",
4824+ "type": "text",
4825+ "primaryKey": false,
4826+ "notNull": true
4827+ },
4828+ "applicationId": {
4829+ "name": "applicationId",
4830+ "type": "text",
4831+ "primaryKey": false,
4832+ "notNull": true
4833+ }
4834+ },
4835+ "indexes": {},
4836+ "foreignKeys": {
4837+ "redirect_applicationId_application_applicationId_fk": {
4838+ "name": "redirect_applicationId_application_applicationId_fk",
4839+ "tableFrom": "redirect",
4840+ "tableTo": "application",
4841+ "columnsFrom": [
4842+ "applicationId"
4843+ ],
4844+ "columnsTo": [
4845+ "applicationId"
4846+ ],
4847+ "onDelete": "cascade",
4848+ "onUpdate": "no action"
4849+ }
4850+ },
4851+ "compositePrimaryKeys": {},
4852+ "uniqueConstraints": {},
4853+ "policies": {},
4854+ "checkConstraints": {},
4855+ "isRLSEnabled": false
4856+ },
4857+ "public.redis": {
4858+ "name": "redis",
4859+ "schema": "",
4860+ "columns": {
4861+ "redisId": {
4862+ "name": "redisId",
4863+ "type": "text",
4864+ "primaryKey": true,
4865+ "notNull": true
4866+ },
4867+ "name": {
4868+ "name": "name",
4869+ "type": "text",
4870+ "primaryKey": false,
4871+ "notNull": true
4872+ },
4873+ "appName": {
4874+ "name": "appName",
4875+ "type": "text",
4876+ "primaryKey": false,
4877+ "notNull": true
4878+ },
4879+ "description": {
4880+ "name": "description",
4881+ "type": "text",
4882+ "primaryKey": false,
4883+ "notNull": false
4884+ },
4885+ "password": {
4886+ "name": "password",
4887+ "type": "text",
4888+ "primaryKey": false,
4889+ "notNull": true
4890+ },
4891+ "dockerImage": {
4892+ "name": "dockerImage",
4893+ "type": "text",
4894+ "primaryKey": false,
4895+ "notNull": true
4896+ },
4897+ "command": {
4898+ "name": "command",
4899+ "type": "text",
4900+ "primaryKey": false,
4901+ "notNull": false
4902+ },
4903+ "env": {
4904+ "name": "env",
4905+ "type": "text",
4906+ "primaryKey": false,
4907+ "notNull": false
4908+ },
4909+ "memoryReservation": {
4910+ "name": "memoryReservation",
4911+ "type": "text",
4912+ "primaryKey": false,
4913+ "notNull": false
4914+ },
4915+ "memoryLimit": {
4916+ "name": "memoryLimit",
4917+ "type": "text",
4918+ "primaryKey": false,
4919+ "notNull": false
4920+ },
4921+ "cpuReservation": {
4922+ "name": "cpuReservation",
4923+ "type": "text",
4924+ "primaryKey": false,
4925+ "notNull": false
4926+ },
4927+ "cpuLimit": {
4928+ "name": "cpuLimit",
4929+ "type": "text",
4930+ "primaryKey": false,
4931+ "notNull": false
4932+ },
4933+ "externalPort": {
4934+ "name": "externalPort",
4935+ "type": "integer",
4936+ "primaryKey": false,
4937+ "notNull": false
4938+ },
4939+ "createdAt": {
4940+ "name": "createdAt",
4941+ "type": "text",
4942+ "primaryKey": false,
4943+ "notNull": true
4944+ },
4945+ "applicationStatus": {
4946+ "name": "applicationStatus",
4947+ "type": "applicationStatus",
4948+ "typeSchema": "public",
4949+ "primaryKey": false,
4950+ "notNull": true,
4951+ "default": "'idle'"
4952+ },
4953+ "healthCheckSwarm": {
4954+ "name": "healthCheckSwarm",
4955+ "type": "json",
4956+ "primaryKey": false,
4957+ "notNull": false
4958+ },
4959+ "restartPolicySwarm": {
4960+ "name": "restartPolicySwarm",
4961+ "type": "json",
4962+ "primaryKey": false,
4963+ "notNull": false
4964+ },
4965+ "placementSwarm": {
4966+ "name": "placementSwarm",
4967+ "type": "json",
4968+ "primaryKey": false,
4969+ "notNull": false
4970+ },
4971+ "updateConfigSwarm": {
4972+ "name": "updateConfigSwarm",
4973+ "type": "json",
4974+ "primaryKey": false,
4975+ "notNull": false
4976+ },
4977+ "rollbackConfigSwarm": {
4978+ "name": "rollbackConfigSwarm",
4979+ "type": "json",
4980+ "primaryKey": false,
4981+ "notNull": false
4982+ },
4983+ "modeSwarm": {
4984+ "name": "modeSwarm",
4985+ "type": "json",
4986+ "primaryKey": false,
4987+ "notNull": false
4988+ },
4989+ "labelsSwarm": {
4990+ "name": "labelsSwarm",
4991+ "type": "json",
4992+ "primaryKey": false,
4993+ "notNull": false
4994+ },
4995+ "networkSwarm": {
4996+ "name": "networkSwarm",
4997+ "type": "json",
4998+ "primaryKey": false,
4999+ "notNull": false

1439 more lines aren’t shown here.

apps/dokploy/drizzle/meta/_journal.json+7−0
@@ -750,6 +750,13 @@ · 749 unmodified lines
750750 "when": 1754912062243,
751751 "tag": "0106_purple_maggott",
752752 "breakpoints": true
753+ },
754+ {
755+ "idx": 107,
756+ "version": "7",
757+ "when": 1756436825081,
758+ "tag": "0107_calm_power_pack",
759+ "breakpoints": true
753760 }
754761 ]
755762 }
apps/dokploy/package.json+1−1
@@ -97,7 +97,6 @@ · 96 unmodified lines
9797 "better-auth": "v1.2.8-beta.7",
9898 "bl": "6.0.11",
9999 "boxen": "^7.1.1",
100− "bullmq": "5.4.2",
101100 "class-variance-authority": "^0.7.1",
102101 "clsx": "^2.1.1",
103102 "cmdk": "^0.2.1",
@@ -126,6 +125,7 @@ · 22 unmodified lines
126125 "nodemailer": "6.9.14",
127126 "octokit": "3.1.2",
128127 "otpauth": "^9.4.0",
128+ "p-limit": "^7.1.1",
129129 "pino": "9.4.0",
130130 "pino-pretty": "11.2.2",
131131 "postgres": "3.4.4",
apps/dokploy/server/api/routers/application.ts+6−9
@@ -54,7 +54,11 @@ import { · 53 unmodified lines
5454 applications,
5555 } from "@/server/db/schema";
5656 import type { DeploymentJob } from "@/server/queues/queue-types";
57−import { cleanQueuesByApplication, myQueue } from "@/server/queues/queueSetup";
57+import {
58+ addJobWithUserContext,
59+ cleanQueuesByApplication,
60+ myQueue,
61+} from "@/server/queues/queueSetup";
5862 import { deploy } from "@/server/utils/deploy";
5963 import { uploadFileSchema } from "@/utils/schema";
6064
@@ -668,14 +672,7 @@ export const applicationRouter = createTRPCRouter({ · 607 unmodified lines
668672
669673 return true;
670674 }
671− await myQueue.add(
672− "deployments",
673− { ...jobData },
674− {
675− removeOnComplete: true,
676− removeOnFail: true,
677− },
678− );
675+ await addJobWithUserContext({ ...jobData }, ctx.user.id);
679676 }),
680677
681678 cleanQueues: protectedProcedure
apps/dokploy/server/queues/README.md+104−0
@@ -0,0 +1,104 @@
1+# Queue System Migration - BullMQ to p-limit
2+
3+This directory contains the new queue system that replaces BullMQ with [p-limit](https://github.com/sindresorhus/p-limit) for deployment queues.
4+
5+## Why the Migration?
6+
7+- **Resource Issues**: Users experienced freezing during builds due to resource constraints
8+- **Cancellation Problems**: BullMQ workers couldn't be properly canceled when Docker processes restart
9+- **Retry Loops**: Unwanted automatic retries when processes are killed
10+
11+## New Architecture
12+
13+### Key Features
14+
15+1. **Per-Server Queues**: Deployments are grouped by server (local "dokploy-server" or remote servers)
16+2. **Ordered Processing**: Within each server, deployments are processed based on server concurrency settings
17+3. **Global User Concurrency**: User's `serverConcurrency` controls total deployments across all servers
18+4. **Proper Cancellation**: Jobs can be canceled using AbortController
19+5. **No Redis Dependency**: In-memory queues eliminate Redis dependency issues
20+
21+### Files
22+
23+- `service-queue.ts` - New p-limit based queue implementation
24+- `queueSetup.ts` - Compatibility layer for existing code
25+- `deployments-queue.ts` - Legacy compatibility exports
26+- `queue-types.ts` - Shared type definitions
27+
28+## Usage Examples
29+
30+```typescript
31+import { addJobWithUserContext, cancelDeploymentJobs, getDeploymentQueueStatus } from './queueSetup';
32+
33+// Add a deployment job with user context (recommended for API routes)
34+const result = await addJobWithUserContext({
35+ applicationType: 'application',
36+ applicationId: '123',
37+ type: 'deploy',
38+ titleLog: 'Deploying app',
39+ descriptionLog: 'Starting deployment',
40+ serverId: 'server-456' // Optional - for remote deployments
41+}, 'user-id-789'); // User ID for concurrency settings
42+
43+// Cancel jobs for a service
44+const cancelled = cancelDeploymentJobs('app-123');
45+
46+// Get queue status
47+const status = getDeploymentQueueStatus('app-123');
48+```
49+
50+### Database-Driven Concurrency
51+
52+The system now automatically reads concurrency settings from the database:
53+
54+1. **Global User Concurrency**: From `users_temp.serverConcurrency` field
55+ - Controls the **TOTAL** number of deployments that can run simultaneously for a user
56+ - Example: If `serverConcurrency = 1`, only 1 deployment across ALL services at a time
57+ - Example: If `serverConcurrency = 3`, maximum 3 deployments can run simultaneously across all services
58+
59+2. **Server Concurrency**: From `server.concurrency` field
60+ - Controls how many deployments can run simultaneously **on a specific server**
61+ - Only applies when deploying to remote servers (`serverId` is present)
62+ - Example: Server A can handle 2 concurrent deployments, Server B can handle 1
63+
64+### Concurrency Hierarchy
65+
66+```
67+User Global Limit (users_temp.serverConcurrency)
68+├── dokploy-server (local deployments)
69+│ ├── App A deployment
70+│ ├── App B deployment
71+│ └── Compose C deployment
72+├── remote-server-1 (server.concurrency = 2)
73+│ ├── App D deployment
74+│ └── App E deployment
75+└── remote-server-2 (server.concurrency = 1)
76+ └── App F deployment
77+```
78+
79+**Example Scenarios:**
80+
81+- **User has `serverConcurrency = 1`**: Only 1 deployment total across ALL servers
82+- **User has `serverConcurrency = 3`**: Maximum 3 deployments simultaneously across all servers
83+- **Local server**: All local apps/compose share the "dokploy-server" queue
84+- **Remote server with `concurrency = 2`**: That server can handle up to 2 concurrent deployments
85+- **Queue grouping**: `app-123` and `app-456` on same server share the same queue
86+
87+## Configuration
88+
89+- **Global Concurrency**: Set how many services can deploy simultaneously
90+- **Service Concurrency**: Each service processes 1 deployment at a time (FIFO)
91+
92+```typescript
93+import { setGlobalConcurrency } from './service-queue';
94+
95+// Allow 5 services to deploy simultaneously
96+setGlobalConcurrency(5);
97+```
98+
99+## Migration Notes
100+
101+- The schedules app still uses BullMQ for cron/repeatable jobs (different use case)
102+- All existing API endpoints work unchanged due to compatibility layer
103+- No breaking changes to existing functionality
104+- Improved resource usage and cancellation capabilities
apps/dokploy/server/queues/deployments-queue.ts+54−118
@@ -1,122 +1,58 @@
1−import {
2− deployApplication,
3− deployCompose,
4− deployPreviewApplication,
5− deployRemoteApplication,
6− deployRemoteCompose,
7− deployRemotePreviewApplication,
8− rebuildApplication,
9− rebuildCompose,
10− rebuildRemoteApplication,
11− rebuildRemoteCompose,
12− updateApplicationStatus,
13− updateCompose,
14− updatePreviewDeployment,
15−} from "@dokploy/server";
16−import { type Job, Worker } from "bullmq";
17−import type { DeploymentJob } from "./queue-types";
18−import { redisConfig } from "./redis-connection";
1+// This file is kept for backward compatibility but now uses the new service-queue system
2+// The actual queue logic has been moved to service-queue.ts using p-limit
193
20−export const deploymentWorker = new Worker(
21− "deployments",
22− async (job: Job<DeploymentJob>) => {
23− try {
24− if (job.data.applicationType === "application") {
25− await updateApplicationStatus(job.data.applicationId, "running");
4+import { serviceQueueManager } from "./service-queue";
265
27− if (job.data.server) {
28− if (job.data.type === "redeploy") {
29− await rebuildRemoteApplication({
30− applicationId: job.data.applicationId,
31− titleLog: job.data.titleLog,
32− descriptionLog: job.data.descriptionLog,
33− });
34− } else if (job.data.type === "deploy") {
35− await deployRemoteApplication({
36− applicationId: job.data.applicationId,
37− titleLog: job.data.titleLog,
38− descriptionLog: job.data.descriptionLog,
39− });
40− }
41− } else {
42− if (job.data.type === "redeploy") {
43− await rebuildApplication({
44− applicationId: job.data.applicationId,
45− titleLog: job.data.titleLog,
46− descriptionLog: job.data.descriptionLog,
47− });
48− } else if (job.data.type === "deploy") {
49− await deployApplication({
50− applicationId: job.data.applicationId,
51− titleLog: job.data.titleLog,
52− descriptionLog: job.data.descriptionLog,
53− });
54− }
55− }
56− } else if (job.data.applicationType === "compose") {
57− await updateCompose(job.data.composeId, {
58− composeStatus: "running",
59− });
60−
61− if (job.data.server) {
62− if (job.data.type === "redeploy") {
63− await rebuildRemoteCompose({
64− composeId: job.data.composeId,
65− titleLog: job.data.titleLog,
66− descriptionLog: job.data.descriptionLog,
67− });
68− } else if (job.data.type === "deploy") {
69− await deployRemoteCompose({
70− composeId: job.data.composeId,
71− titleLog: job.data.titleLog,
72− descriptionLog: job.data.descriptionLog,
73− });
74− }
75− } else {
76− if (job.data.type === "deploy") {
77− await deployCompose({
78− composeId: job.data.composeId,
79− titleLog: job.data.titleLog,
80− descriptionLog: job.data.descriptionLog,
81− });
82− } else if (job.data.type === "redeploy") {
83− await rebuildCompose({
84− composeId: job.data.composeId,
85− titleLog: job.data.titleLog,
86− descriptionLog: job.data.descriptionLog,
87− });
88− }
89− }
90− } else if (job.data.applicationType === "application-preview") {
91− await updatePreviewDeployment(job.data.previewDeploymentId, {
92− previewStatus: "running",
93− });
94− if (job.data.server) {
95− if (job.data.type === "deploy") {
96− await deployRemotePreviewApplication({
97− applicationId: job.data.applicationId,
98− titleLog: job.data.titleLog,
99− descriptionLog: job.data.descriptionLog,
100− previewDeploymentId: job.data.previewDeploymentId,
101− });
102− }
103− } else {
104− if (job.data.type === "deploy") {
105− await deployPreviewApplication({
106− applicationId: job.data.applicationId,
107− titleLog: job.data.titleLog,
108− descriptionLog: job.data.descriptionLog,
109− previewDeploymentId: job.data.previewDeploymentId,
110− });
111− }
112− }
113− }
114− } catch (error) {
115− console.log("Error", error);
116− }
6+// Legacy compatibility - this is no longer used but kept to avoid breaking imports
7+export const deploymentWorker = {
8+ run: async () => {
9+ console.log(
10+ "Legacy deploymentWorker.run() called - now using service-queue system",
11+ );
12+ // The service queue manager starts automatically, no need to do anything
13+ return Promise.resolve();
11714 },
118− {
119− autorun: false,
120− connection: redisConfig,
15+ close: async () => {
16+ console.log("Legacy deploymentWorker.close() called");
17+ return Promise.resolve();
12118 },
122−);
19+};
20+
21+// Legacy exports for backward compatibility
22+export const getWorkersMap = () => {
23+ console.warn(
24+ "getWorkersMap() is deprecated - use serviceQueueManager instead",
25+ );
26+ return {};
27+};
28+
29+export const getWorker = (_serverId?: string) => {
30+ console.warn("getWorker() is deprecated - use serviceQueueManager instead");
31+ return undefined;
32+};
33+
34+export const createDeploymentWorker = (defaultConcurrency = 1) => {
35+ console.warn(
36+ "createDeploymentWorker() is deprecated - use serviceQueueManager instead",
37+ );
38+ serviceQueueManager.setGlobalConcurrency(defaultConcurrency);
39+ return deploymentWorker;
40+};
41+
42+export const createServerDeploymentWorker = (
43+ _serverId: string,
44+ _concurrency = 1,
45+) => {
46+ console.warn(
47+ "createServerDeploymentWorker() is deprecated - use serviceQueueManager instead",
48+ );
49+ // The new system automatically creates queues per service, no need for explicit worker creation
50+ return deploymentWorker;
51+};
52+
53+export const removeServerDeploymentWorker = (serverId: string) => {
54+ console.warn(
55+ "removeServerDeploymentWorker() is deprecated - use removeServiceQueue instead",
56+ );
57+ serviceQueueManager.removeServiceQueue(serverId);
58+};
apps/dokploy/server/queues/queueSetup.ts+91−34
@@ -1,44 +1,101 @@
1−import { Queue } from "bullmq";
2−import { redisConfig } from "./redis-connection";
3−
4−const myQueue = new Queue("deployments", {
5− connection: redisConfig,
6−});
7−
8−process.on("SIGTERM", () => {
9− myQueue.close();
10− process.exit(0);
11−});
12−
13−myQueue.on("error", (error) => {
14− if ((error as any).code === "ECONNREFUSED") {
15− console.error(
16− "Make sure you have installed Redis and it is running.",
17− error,
18− );
1+import type { DeploymentJob } from "./queue-types";
2+import {
3+ addDeploymentJob,
4+ cancelDeploymentJobs,
5+ getDeploymentQueueStatus,
6+ setGlobalConcurrency,
7+} from "./service-queue";
8+
9+// Default queue name for local deployments
10+export const DEFAULT_QUEUE = "default";
11+
12+// Initialize with default concurrency of 3 services
13+setGlobalConcurrency(3);
14+
15+// Helper function to determine service ID from job data
16+// Groups deployments by SERVER, not by individual application/compose
17+const getServiceId = (jobData: DeploymentJob): string => {
18+ // If it has a serverId, group by that server
19+ if (jobData.serverId) {
20+ return jobData.serverId;
1921 }
20−});
22+
23+ // For local deployments (no serverId), group all under the main Dokploy server
24+ return "dokploy-server";
25+};
26+
27+// Compatibility functions to replace BullMQ usage
28+export const myQueue = {
29+ add: async (
30+ _name: string,
31+ jobData: DeploymentJob,
32+ _options?: any,
33+ userId?: string,
34+ ) => {
35+ const serviceId = getServiceId(jobData);
36+ const jobId = await addDeploymentJob(serviceId, jobData, userId);
37+ console.log(`Added deployment job ${jobId} to service ${serviceId}`);
38+ return { id: jobId };
39+ },
40+
41+ close: () => {
42+ console.log("Service queue manager shutdown initiated");
43+ return Promise.resolve();
44+ },
45+};
2146
2247 export const cleanQueuesByApplication = async (applicationId: string) => {
23− const jobs = await myQueue.getJobs(["waiting", "delayed"]);
48+ // Cancel jobs for this specific application across all servers
49+ let totalCancelled = 0;
2450
25− for (const job of jobs) {
26− if (job?.data?.applicationId === applicationId) {
27− await job.remove();
28− console.log(`Removed job ${job.id} for application ${applicationId}`);
29− }
30− }
51+ // Check the local Dokploy server
52+ const localCancelled = cancelDeploymentJobs(
53+ "dokploy-server",
54+ applicationId,
55+ undefined,
56+ );
57+ totalCancelled += localCancelled;
58+
59+ // TODO: Also check remote servers if we need to track which servers have this application
60+ // For now, we only clean from the local server queue
61+
62+ console.log(
63+ `Cancelled ${totalCancelled} jobs for application ${applicationId}`,
64+ );
65+ return totalCancelled;
3166 };
3267
3368 export const cleanQueuesByCompose = async (composeId: string) => {
34− const jobs = await myQueue.getJobs(["waiting", "delayed"]);
69+ // Cancel jobs for this specific compose across all servers
70+ let totalCancelled = 0;
3571
36− for (const job of jobs) {
37− if (job?.data?.composeId === composeId) {
38− await job.remove();
39− console.log(`Removed job ${job.id} for compose ${composeId}`);
40− }
41− }
72+ // Check the local Dokploy server
73+ const localCancelled = cancelDeploymentJobs(
74+ "dokploy-server",
75+ undefined,
76+ composeId,
77+ );
78+ totalCancelled += localCancelled;
79+
80+ // TODO: Also check remote servers if we need to track which servers have this compose
81+ // For now, we only clean from the local server queue
82+
83+ console.log(`Cancelled ${totalCancelled} jobs for compose ${composeId}`);
84+ return totalCancelled;
4285 };
4386
44−export { myQueue };
87+// Export queue status for monitoring
88+export const getQueueStatus = getDeploymentQueueStatus;
89+
90+// New function to add jobs with user context (for API routes)
91+export const addJobWithUserContext = async (
92+ jobData: DeploymentJob,
93+ userId?: string,
94+): Promise<{ id: string }> => {
95+ const serviceId = getServiceId(jobData);
96+ const jobId = await addDeploymentJob(serviceId, jobData, userId);
97+ console.log(
98+ `Added deployment job ${jobId} to service ${serviceId} with user context ${userId || "none"}`,
99+ );
100+ return { id: jobId };
101+};
apps/dokploy/server/queues/redis-connection.ts+0−8
@@ -1,8 +0,0 @@
1−import type { ConnectionOptions } from "bullmq";
2−
3−export const redisConfig: ConnectionOptions = {
4− host:
5− process.env.NODE_ENV === "production"
6− ? process.env.REDIS_HOST || "dokploy-redis"
7− : "127.0.0.1",
8−};
apps/dokploy/server/queues/service-queue.ts+500−0
@@ -0,0 +1,500 @@
1+import {
2+ deployApplication,
3+ deployCompose,
4+ deployPreviewApplication,
5+ deployRemoteApplication,
6+ deployRemoteCompose,
7+ deployRemotePreviewApplication,
8+ findServerById,
9+ rebuildApplication,
10+ rebuildCompose,
11+ rebuildRemoteApplication,
12+ rebuildRemoteCompose,
13+ updateApplicationStatus,
14+ updateCompose,
15+ updatePreviewDeployment,
16+} from "@dokploy/server";
17+import { db } from "@dokploy/server/db";
18+import { users_temp } from "@dokploy/server/db/schema";
19+import { eq } from "drizzle-orm";
20+import pLimit from "p-limit";
21+import type { DeploymentJob } from "./queue-types";
22+
23+// Types for our p-limit based queue system
24+export interface QueueJob {
25+ id: string;
26+ data: DeploymentJob;
27+ createdAt: Date;
28+ status: "waiting" | "processing" | "completed" | "failed" | "cancelled";
29+ abortController: AbortController;
30+ promise?: Promise<void>;
31+}
32+
33+export interface ServiceQueue {
34+ serviceId: string;
35+ jobs: QueueJob[];
36+ limit: ReturnType<typeof pLimit>; // p-limit instance with concurrency 1
37+}
38+
39+// Global queue management using p-limit
40+class ServiceQueueManager {
41+ private queues: Map<string, ServiceQueue> = new Map();
42+ private globalLimit: ReturnType<typeof pLimit>;
43+ private isShuttingDown = false;
44+
45+ constructor(globalConcurrency = 3) {
46+ // Global limit controls how many services can deploy simultaneously
47+ this.globalLimit = pLimit(globalConcurrency);
48+ this.setupShutdownHandlers();
49+ }
50+
51+ // Set global concurrency (how many services can deploy simultaneously)
52+ setGlobalConcurrency(concurrency: number) {
53+ this.globalLimit = pLimit(concurrency);
54+ }
55+
56+ // Get concurrency settings from database
57+ private async getConcurrencySettings(jobData: DeploymentJob): Promise<{
58+ serviceConcurrency: number;
59+ }> {
60+ try {
61+ // Default: Each service processes 1 deployment at a time (FIFO within service)
62+ let serviceConcurrency = 1;
63+
64+ // If it's a server deployment, get server-specific concurrency
65+ // This controls how many deployments can run simultaneously ON THAT SERVER
66+ if (jobData.serverId) {
67+ try {
68+ const serverData = await findServerById(jobData.serverId);
69+ serviceConcurrency = serverData.concurrency || 1;
70+ console.log(
71+ `Server ${jobData.serverId} can handle ${serviceConcurrency} concurrent deployments`,
72+ );
73+ } catch (error) {
74+ console.warn(
75+ `Could not get server concurrency for ${jobData.serverId}, using default: 1`,
76+ );
77+ }
78+ }
79+
80+ return {
81+ serviceConcurrency,
82+ };
83+ } catch (error) {
84+ console.warn(
85+ "Error getting concurrency settings, using defaults:",
86+ error,
87+ );
88+ return {
89+ serviceConcurrency: 1,
90+ };
91+ }
92+ }
93+
94+ // Get or create a queue for a service with dynamic concurrency
95+ private async getOrCreateQueue(
96+ serviceId: string,
97+ jobData?: DeploymentJob,
98+ ): Promise<ServiceQueue> {
99+ if (!this.queues.has(serviceId)) {
100+ let serviceConcurrency = 1; // Default
101+
102+ // Get concurrency from database if we have job data
103+ if (jobData) {
104+ const settings = await this.getConcurrencySettings(jobData);
105+ serviceConcurrency = settings.serviceConcurrency;
106+ }
107+
108+ this.queues.set(serviceId, {
109+ serviceId,
110+ jobs: [],
111+ // Service concurrency from database or default to 1
112+ limit: pLimit(serviceConcurrency),
113+ });
114+
115+ console.log(
116+ `Created queue for service ${serviceId} with concurrency: ${serviceConcurrency}`,
117+ );
118+ }
119+ return this.queues.get(serviceId)!;
120+ }
121+
122+ // Add a job to a service queue
123+ async addJob(
124+ serviceId: string,
125+ jobData: DeploymentJob,
126+ userId?: string,
127+ ): Promise<string> {
128+ if (this.isShuttingDown) {
129+ throw new Error("Queue manager is shutting down");
130+ }
131+
132+ // Update global concurrency based on user settings if provided
133+ // This controls the TOTAL number of deployments across ALL services for this user
134+ if (userId) {
135+ try {
136+ const userData = await db.query.users_temp.findFirst({
137+ where: eq(users_temp.id, userId),
138+ });
139+
140+ if (userData?.serverConcurrency) {
141+ // This is GLOBAL concurrency - total deployments across all services
142+ this.globalLimit = pLimit(userData.serverConcurrency);
143+ console.log(
144+ `Set GLOBAL concurrency to ${userData.serverConcurrency} deployments total for user ${userId}`,
145+ );
146+ }
147+ } catch (error) {
148+ console.warn(
149+ `Could not get user concurrency settings for ${userId}:`,
150+ error,
151+ );
152+ }
153+ }
154+
155+ const queue = await this.getOrCreateQueue(serviceId, jobData);
156+ const jobId = `${serviceId}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
157+
158+ const job: QueueJob = {
159+ id: jobId,
160+ data: jobData,
161+ createdAt: new Date(),
162+ status: "waiting",
163+ abortController: new AbortController(),
164+ };
165+
166+ queue.jobs.push(job);
167+ console.log(
168+ `Added job ${jobId} to service ${serviceId} queue. Queue length: ${queue.jobs.length}`,
169+ );
170+
171+ // Start processing the job using p-limit
172+ this.processJob(queue, job);
173+
174+ return jobId;
175+ }
176+
177+ // Process a job using both global and service-level p-limit
178+ private processJob(queue: ServiceQueue, job: QueueJob) {
179+ // Use global limit to control cross-service concurrency
180+ job.promise = this.globalLimit(() =>
181+ // Use service limit to ensure ordered processing within service
182+ queue.limit(async () => {
183+ if (job.status === "cancelled" || this.isShuttingDown) {
184+ return;
185+ }
186+
187+ job.status = "processing";
188+ console.log(`Processing job ${job.id} for service ${queue.serviceId}`);
189+
190+ try {
191+ await this.executeJob(job);
192+ job.status = "completed";
193+ console.log(`Completed job ${job.id} for service ${queue.serviceId}`);
194+ } catch (error) {
195+ if (job.abortController.signal.aborted) {
196+ job.status = "cancelled";
197+ console.log(
198+ `Job ${job.id} was cancelled for service ${queue.serviceId}`,
199+ );
200+ } else {
201+ job.status = "failed";
202+ console.error(
203+ `Job ${job.id} failed for service ${queue.serviceId}:`,
204+ error,
205+ );
206+ }
207+ } finally {
208+ // Clean up completed/failed jobs after a delay
209+ setTimeout(() => {
210+ queue.jobs = queue.jobs.filter((j) => j.id !== job.id);
211+ }, 5000);
212+ }
213+ }),
214+ );
215+ }
216+
217+ // Remove/cancel jobs for a specific service
218+ cancelJobsByService(
219+ serviceId: string,
220+ applicationId?: string,
221+ composeId?: string,
222+ ): number {
223+ const queue = this.queues.get(serviceId);
224+ if (!queue) return 0;
225+
226+ let cancelledCount = 0;
227+
228+ // Cancel waiting and processing jobs
229+ for (const job of queue.jobs) {
230+ if (job.status === "waiting" || job.status === "processing") {
231+ // Check if this job matches the filter criteria
232+ const matchesApplication = applicationId
233+ ? (job.data.applicationType === "application" ||
234+ job.data.applicationType === "application-preview") &&
235+ job.data.applicationId === applicationId
236+ : true;
237+ const matchesCompose = composeId
238+ ? job.data.applicationType === "compose" &&
239+ job.data.composeId === composeId
240+ : true;
241+
242+ if (matchesApplication && matchesCompose) {
243+ job.status = "cancelled";
244+ job.abortController.abort();
245+ cancelledCount++;
246+ console.log(`Cancelled job ${job.id} for service ${serviceId}`);
247+ }
248+ }
249+ }
250+
251+ // Remove cancelled jobs from queue immediately
252+ queue.jobs = queue.jobs.filter((job) => job.status !== "cancelled");
253+
254+ return cancelledCount;
255+ }
256+
257+ // Get queue status for a service
258+ getQueueStatus(serviceId: string) {
259+ const queue = this.queues.get(serviceId);
260+ if (!queue) return null;
261+
262+ return {
263+ serviceId,
264+ totalJobs: queue.jobs.length,
265+ waitingJobs: queue.jobs.filter((j) => j.status === "waiting").length,
266+ processingJobs: queue.jobs.filter((j) => j.status === "processing")
267+ .length,
268+ completedJobs: queue.jobs.filter((j) => j.status === "completed").length,
269+ failedJobs: queue.jobs.filter((j) => j.status === "failed").length,
270+ // p-limit queue status
271+ activeCount: queue.limit.activeCount,
272+ pendingCount: queue.limit.pendingCount,
273+ };
274+ }
275+
276+ // Get all queues status
277+ getAllQueuesStatus() {
278+ const status: Record<string, any> = {};
279+ for (const [serviceId] of this.queues) {
280+ status[serviceId] = this.getQueueStatus(serviceId);
281+ }
282+ status.global = {
283+ activeCount: this.globalLimit.activeCount,
284+ pendingCount: this.globalLimit.pendingCount,
285+ concurrency: this.globalLimit.concurrency,
286+ };
287+ return status;
288+ }
289+
290+ // Clear pending jobs from a service queue using p-limit's clearQueue
291+ clearServiceQueue(serviceId: string) {
292+ const queue = this.queues.get(serviceId);
293+ if (queue) {
294+ // Cancel all waiting jobs
295+ for (const job of queue.jobs) {
296+ if (job.status === "waiting") {
297+ job.status = "cancelled";
298+ job.abortController.abort();
299+ }
300+ }
301+
302+ // Clear p-limit's internal queue
303+ queue.limit.clearQueue();
304+
305+ // Remove cancelled jobs
306+ queue.jobs = queue.jobs.filter((job) => job.status !== "cancelled");
307+
308+ console.log(`Cleared service queue for ${serviceId}`);
309+ }
310+ }
311+
312+ private async executeJob(job: QueueJob): Promise<void> {
313+ const { data } = job;
314+
315+ // Check if job was cancelled before execution
316+ if (job.abortController.signal.aborted) {
317+ throw new Error("Job was cancelled");
318+ }
319+
320+ try {
321+ if (data.applicationType === "application") {
322+ await updateApplicationStatus(data.applicationId, "running");
323+
324+ if (data.server) {
325+ if (data.type === "redeploy") {
326+ await rebuildRemoteApplication({
327+ applicationId: data.applicationId,
328+ titleLog: data.titleLog,
329+ descriptionLog: data.descriptionLog,
330+ });
331+ } else if (data.type === "deploy") {
332+ await deployRemoteApplication({
333+ applicationId: data.applicationId,
334+ titleLog: data.titleLog,
335+ descriptionLog: data.descriptionLog,
336+ });
337+ }
338+ } else {
339+ if (data.type === "redeploy") {
340+ await rebuildApplication({
341+ applicationId: data.applicationId,
342+ titleLog: data.titleLog,
343+ descriptionLog: data.descriptionLog,
344+ });
345+ } else if (data.type === "deploy") {
346+ await deployApplication({
347+ applicationId: data.applicationId,
348+ titleLog: data.titleLog,
349+ descriptionLog: data.descriptionLog,
350+ });
351+ }
352+ }
353+ } else if (data.applicationType === "compose") {
354+ await updateCompose(data.composeId, {
355+ composeStatus: "running",
356+ });
357+
358+ if (data.server) {
359+ if (data.type === "redeploy") {
360+ await rebuildRemoteCompose({
361+ composeId: data.composeId,
362+ titleLog: data.titleLog,
363+ descriptionLog: data.descriptionLog,
364+ });
365+ } else if (data.type === "deploy") {
366+ await deployRemoteCompose({
367+ composeId: data.composeId,
368+ titleLog: data.titleLog,
369+ descriptionLog: data.descriptionLog,
370+ });
371+ }
372+ } else {
373+ if (data.type === "deploy") {
374+ await deployCompose({
375+ composeId: data.composeId,
376+ titleLog: data.titleLog,
377+ descriptionLog: data.descriptionLog,
378+ });
379+ } else if (data.type === "redeploy") {
380+ await rebuildCompose({
381+ composeId: data.composeId,
382+ titleLog: data.titleLog,
383+ descriptionLog: data.descriptionLog,
384+ });
385+ }
386+ }
387+ } else if (data.applicationType === "application-preview") {
388+ await updatePreviewDeployment(data.previewDeploymentId, {
389+ previewStatus: "running",
390+ });
391+ if (data.server) {
392+ if (data.type === "deploy") {
393+ await deployRemotePreviewApplication({
394+ applicationId: data.applicationId,
395+ titleLog: data.titleLog,
396+ descriptionLog: data.descriptionLog,
397+ previewDeploymentId: data.previewDeploymentId,
398+ });
399+ }
400+ } else {
401+ if (data.type === "deploy") {
402+ await deployPreviewApplication({
403+ applicationId: data.applicationId,
404+ titleLog: data.titleLog,
405+ descriptionLog: data.descriptionLog,
406+ previewDeploymentId: data.previewDeploymentId,
407+ });
408+ }
409+ }
410+ }
411+ } catch (error) {
412+ console.log("Deployment Error", error);
413+ throw error;
414+ }
415+ }
416+
417+ private setupShutdownHandlers() {
418+ const gracefulShutdown = async () => {
419+ console.log("Shutting down service queue manager...");
420+ this.isShuttingDown = true;
421+
422+ // Cancel all jobs
423+ for (const queue of this.queues.values()) {
424+ for (const job of queue.jobs) {
425+ job.abortController.abort();
426+ }
427+ // Clear p-limit queues
428+ queue.limit.clearQueue();
429+ }
430+
431+ // Clear global queue
432+ this.globalLimit.clearQueue();
433+
434+ // Wait a bit for jobs to finish cancelling
435+ await new Promise((resolve) => setTimeout(resolve, 2000));
436+ process.exit(0);
437+ };
438+
439+ process.on("SIGTERM", gracefulShutdown);
440+ process.on("SIGINT", gracefulShutdown);
441+ }
442+
443+ // Remove a specific service queue entirely
444+ removeServiceQueue(serviceId: string) {
445+ const queue = this.queues.get(serviceId);
446+ if (queue) {
447+ // Cancel all jobs in the queue
448+ for (const job of queue.jobs) {
449+ job.abortController.abort();
450+ }
451+ // Clear p-limit queue
452+ queue.limit.clearQueue();
453+ this.queues.delete(serviceId);
454+ console.log(`Removed service queue for ${serviceId}`);
455+ }
456+ }
457+}
458+
459+// Global instance
460+export const serviceQueueManager = new ServiceQueueManager();
461+
462+// Helper functions to maintain compatibility with existing code
463+export const addDeploymentJob = async (
464+ serviceId: string,
465+ jobData: DeploymentJob,
466+ userId?: string,
467+): Promise<string> => {
468+ return await serviceQueueManager.addJob(serviceId, jobData, userId);
469+};
470+
471+export const cancelDeploymentJobs = (
472+ serviceId: string,
473+ applicationId?: string,
474+ composeId?: string,
475+): number => {
476+ return serviceQueueManager.cancelJobsByService(
477+ serviceId,
478+ applicationId,
479+ composeId,
480+ );
481+};
482+
483+export const getDeploymentQueueStatus = (serviceId?: string) => {
484+ if (serviceId) {
485+ return serviceQueueManager.getQueueStatus(serviceId);
486+ }
487+ return serviceQueueManager.getAllQueuesStatus();
488+};
489+
490+export const setGlobalConcurrency = (concurrency: number) => {
491+ serviceQueueManager.setGlobalConcurrency(concurrency);
492+};
493+
494+export const removeServiceQueue = (serviceId: string) => {
495+ serviceQueueManager.removeServiceQueue(serviceId);
496+};
497+
498+export const clearServiceQueue = (serviceId: string) => {
499+ serviceQueueManager.clearServiceQueue(serviceId);
500+};
packages/server/src/db/schema/server.ts+1−0
@@ -48,6 +48,7 @@ export const server = pgTable("server", { · 47 unmodified lines
4848 sshKeyId: text("sshKeyId").references(() => sshKeys.sshKeyId, {
4949 onDelete: "set null",
5050 }),
51+ concurrency: integer("concurrency").notNull().default(1),
5152 metricsConfig: jsonb("metricsConfig")
5253 .$type<{
5354 server: {
packages/server/src/db/schema/user.ts+1−0
@@ -62,6 +62,7 @@ export const users_temp = pgTable("user_temp", { · 61 unmodified lines
6262 // Metrics
6363 enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
6464 allowImpersonation: boolean("allowImpersonation").notNull().default(false),
65+ serverConcurrency: integer("serverConcurrency").notNull().default(1),
6566 metricsConfig: jsonb("metricsConfig")
6667 .$type<{
6768 server: {
pnpm-lock.yaml+11−3
@@ -280,9 +280,6 @@ importers: · 279 unmodified lines
280280 boxen:
281281 specifier: ^7.1.1
282282 version: 7.1.1
283− bullmq:
284− specifier: 5.4.2
285− version: 5.4.2
286283 class-variance-authority:
287284 specifier: ^0.7.1
288285 version: 0.7.1
@@ -367,6 +364,9 @@ importers: · 78 unmodified lines
367364 otpauth:
368365 specifier: ^9.4.0
369366 version: 9.4.0
367+ p-limit:
368+ specifier: ^7.1.1
369+ version: 7.1.1
370370 pino:
371371 specifier: 9.4.0
372372 version: 9.4.0
@@ -6412,6 +6412,10 @@ packages: · 6039 unmodified lines
64126412 resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==}
64136413 engines: {node: '>=18'}
64146414
6415+ p-limit@7.1.1:
6416+ resolution: {integrity: sha512-i8PyM2JnsNChVSYWLr2BAjNoLi0BAYC+wecOnZnVV+YSNJkzP7cWmvI34dk0WArWfH9KwBHNoZI3P3MppImlIA==}
6417+ engines: {node: '>=20'}
6418+
64156419 p-locate@4.1.0:
64166420 resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
64176421 engines: {node: '>=8'}
@@ -13869,6 +13873,10 @@ snapshots: · 7451 unmodified lines
1386913873 dependencies:
1387013874 yocto-queue: 1.2.1
1387113875
13876+ p-limit@7.1.1:
13877+ dependencies:
13878+ yocto-queue: 1.2.1
13879+
1387213880 p-locate@4.1.0:
1387313881 dependencies:
1387413882 p-limit: 2.3.0

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t