diff --git a/Dockerfile b/Dockerfile
index 11310b18e2..ae8c997f89 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -46,7 +46,7 @@ COPY --from=build /prod/dokploy/node_modules ./node_modules
# Install docker
-RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && rm get-docker.sh && curl https://rclone.org/install.sh | bash
+RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh --version 28.5.2 && rm get-docker.sh && curl https://rclone.org/install.sh | bash
# Install Nixpacks and tsx
# | VERBOSE=1 VERSION=1.21.0 bash
diff --git a/apps/dokploy/.env.example b/apps/dokploy/.env.example
index ba57ec7bed..8f801196e7 100644
--- a/apps/dokploy/.env.example
+++ b/apps/dokploy/.env.example
@@ -1,3 +1,3 @@
DATABASE_URL="postgres://dokploy:amukds4wi9001583845717ad2@localhost:5432/dokploy"
PORT=3000
-NODE_ENV=development
\ No newline at end of file
+NODE_ENV=development
diff --git a/apps/dokploy/components/dashboard/project/add-application.tsx b/apps/dokploy/components/dashboard/project/add-application.tsx
index 079701eb8b..b0db46681f 100644
--- a/apps/dokploy/components/dashboard/project/add-application.tsx
+++ b/apps/dokploy/components/dashboard/project/add-application.tsx
@@ -150,8 +150,8 @@ export const AddApplication = ({ environmentId, projectName }: Props) => {
placeholder="Frontend"
{...field}
onChange={(e) => {
- const val = e.target.value?.trim() || "";
- const serviceName = slugify(val);
+ const val = e.target.value || "";
+ const serviceName = slugify(val.trim());
form.setValue("appName", `${slug}-${serviceName}`);
field.onChange(val);
}}
diff --git a/apps/dokploy/components/dashboard/project/add-compose.tsx b/apps/dokploy/components/dashboard/project/add-compose.tsx
index a187104ecb..bb911373fe 100644
--- a/apps/dokploy/components/dashboard/project/add-compose.tsx
+++ b/apps/dokploy/components/dashboard/project/add-compose.tsx
@@ -161,8 +161,8 @@ export const AddCompose = ({ environmentId, projectName }: Props) => {
placeholder="Frontend"
{...field}
onChange={(e) => {
- const val = e.target.value?.trim() || "";
- const serviceName = slugify(val);
+ const val = e.target.value || "";
+ const serviceName = slugify(val.trim());
form.setValue("appName", `${slug}-${serviceName}`);
field.onChange(val);
}}
diff --git a/apps/dokploy/components/dashboard/project/add-database.tsx b/apps/dokploy/components/dashboard/project/add-database.tsx
index c0600a2d99..3176b95894 100644
--- a/apps/dokploy/components/dashboard/project/add-database.tsx
+++ b/apps/dokploy/components/dashboard/project/add-database.tsx
@@ -395,8 +395,8 @@ export const AddDatabase = ({ environmentId, projectName }: Props) => {
placeholder="Name"
{...field}
onChange={(e) => {
- const val = e.target.value?.trim() || "";
- const serviceName = slugify(val);
+ const val = e.target.value || "";
+ const serviceName = slugify(val.trim());
form.setValue("appName", `${slug}-${serviceName}`);
field.onChange(val);
}}
diff --git a/apps/dokploy/components/dashboard/settings/notifications/handle-notifications.tsx b/apps/dokploy/components/dashboard/settings/notifications/handle-notifications.tsx
index e5fee3a9d3..337cdfd2ba 100644
--- a/apps/dokploy/components/dashboard/settings/notifications/handle-notifications.tsx
+++ b/apps/dokploy/components/dashboard/settings/notifications/handle-notifications.tsx
@@ -1261,8 +1261,10 @@ export const HandleNotifications = ({ notificationId }: Props) => {
});
}
toast.success("Connection Success");
- } catch {
- toast.error("Error testing the provider");
+ } catch (error) {
+ toast.error(
+ `Error testing the provider ${error instanceof Error ? error.message : "Unknown error"}`,
+ );
}
}}
>
diff --git a/apps/dokploy/components/dashboard/settings/users/show-users.tsx b/apps/dokploy/components/dashboard/settings/users/show-users.tsx
index 51d8704a38..06c94416b0 100644
--- a/apps/dokploy/components/dashboard/settings/users/show-users.tsx
+++ b/apps/dokploy/components/dashboard/settings/users/show-users.tsx
@@ -21,7 +21,6 @@ import {
import {
Table,
TableBody,
- TableCaption,
TableCell,
TableHead,
TableHeader,
@@ -68,7 +67,6 @@ export const ShowUsers = () => {
) : (
- See all users
Email
@@ -111,35 +109,75 @@ export const ShowUsers = () => {
-
-
-
-
-
-
- Actions
-
+ {member.role !== "owner" && (
+
+
+
+
+
+
+ Actions
+
- {member.role !== "owner" && (
- )}
- {member.role !== "owner" && (
- <>
- {!isCloud && (
- {
+ {!isCloud && (
+ {
+ await mutateAsync({
+ userId: member.user.id,
+ })
+ .then(() => {
+ toast.success(
+ "User deleted successfully",
+ );
+ refetch();
+ })
+ .catch(() => {
+ toast.error(
+ "Error deleting destination",
+ );
+ });
+ }}
+ >
+ e.preventDefault()}
+ >
+ Delete User
+
+
+ )}
+
+ {
+ if (!isCloud) {
+ const orgCount =
+ await utils.user.checkUserOrganizations.fetch(
+ {
+ userId: member.user.id,
+ },
+ );
+
+ console.log(orgCount);
+
+ if (orgCount === 1) {
await mutateAsync({
userId: member.user.id,
})
@@ -151,86 +189,40 @@ export const ShowUsers = () => {
})
.catch(() => {
toast.error(
- "Error deleting destination",
+ "Error deleting user",
);
});
- }}
- >
-
- e.preventDefault()
- }
- >
- Delete User
-
-
- )}
-
- {
- if (!isCloud) {
- const orgCount =
- await utils.user.checkUserOrganizations.fetch(
- {
- userId: member.user.id,
- },
- );
-
- console.log(orgCount);
-
- if (orgCount === 1) {
- await mutateAsync({
- userId: member.user.id,
- })
- .then(() => {
- toast.success(
- "User deleted successfully",
- );
- refetch();
- })
- .catch(() => {
- toast.error(
- "Error deleting user",
- );
- });
- return;
- }
+ return;
}
+ }
- const { error } =
- await authClient.organization.removeMember(
- {
- memberIdOrEmail: member.id,
- },
- );
+ const { error } =
+ await authClient.organization.removeMember(
+ {
+ memberIdOrEmail: member.id,
+ },
+ );
- if (!error) {
- toast.success(
- "User unlinked successfully",
- );
- refetch();
- } else {
- toast.error(
- "Error unlinking user",
- );
- }
- }}
+ if (!error) {
+ toast.success(
+ "User unlinked successfully",
+ );
+ refetch();
+ } else {
+ toast.error("Error unlinking user");
+ }
+ }}
+ >
+ e.preventDefault()}
>
- e.preventDefault()}
- >
- Unlink User
-
-
- >
- )}
-
-
+ Unlink User
+
+
+
+
+ )}
);
diff --git a/apps/dokploy/components/ui/time-badge.tsx b/apps/dokploy/components/ui/time-badge.tsx
index ea7f1f84e4..4cf778f252 100644
--- a/apps/dokploy/components/ui/time-badge.tsx
+++ b/apps/dokploy/components/ui/time-badge.tsx
@@ -44,14 +44,20 @@ export function TimeBadge() {
.padStart(2, "0")}`;
};
+ const formattedTime = new Intl.DateTimeFormat("en-US", {
+ timeZone: serverTime.timezone,
+ timeStyle: "medium",
+ hour12: false,
+ }).format(time);
+
return (
-
-
Server Time:
-
- {time.toLocaleTimeString()}
-
-
- ({serverTime.timezone} | {getUtcOffset(serverTime.timezone)})
+
+
+ Server Time:
+ {formattedTime}
+
+
+ {serverTime.timezone} | {getUtcOffset(serverTime.timezone)}
);
diff --git a/apps/dokploy/drizzle/0121_rainy_cargill.sql b/apps/dokploy/drizzle/0121_rainy_cargill.sql
new file mode 100644
index 0000000000..85cfa8ceb9
--- /dev/null
+++ b/apps/dokploy/drizzle/0121_rainy_cargill.sql
@@ -0,0 +1,9 @@
+-- Fix inconsistent date formats in environment.createdAt field
+-- Convert PostgreSQL timestamp format to ISO 8601 format
+-- This addresses issue #2992 where old environments have PostgreSQL timestamp format
+-- while new ones have ISO 8601 format
+
+UPDATE "environment"
+SET "createdAt" = to_char("createdAt"::timestamptz, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
+WHERE "createdAt" NOT LIKE '%T%';
+
diff --git a/apps/dokploy/drizzle/meta/0121_snapshot.json b/apps/dokploy/drizzle/meta/0121_snapshot.json
new file mode 100644
index 0000000000..52516ec291
--- /dev/null
+++ b/apps/dokploy/drizzle/meta/0121_snapshot.json
@@ -0,0 +1,6722 @@
+{
+ "id": "6d1361fc-3a46-4016-b6db-42351c20393c",
+ "prevId": "bbe005b3-d5e0-4e93-8305-ba3b9a2e3f3d",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is2FAEnabled": {
+ "name": "is2FAEnabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resetPasswordToken": {
+ "name": "resetPasswordToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resetPasswordExpiresAt": {
+ "name": "resetPasswordExpiresAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "confirmationToken": {
+ "name": "confirmationToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "confirmationExpiresAt": {
+ "name": "confirmationExpiresAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_user_id_user_id_fk": {
+ "name": "account_user_id_user_id_fk",
+ "tableFrom": "account",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.apikey": {
+ "name": "apikey",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "start": {
+ "name": "start",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refill_interval": {
+ "name": "refill_interval",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refill_amount": {
+ "name": "refill_amount",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_refill_at": {
+ "name": "last_refill_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rate_limit_enabled": {
+ "name": "rate_limit_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rate_limit_time_window": {
+ "name": "rate_limit_time_window",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rate_limit_max": {
+ "name": "rate_limit_max",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_count": {
+ "name": "request_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "remaining": {
+ "name": "remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_request": {
+ "name": "last_request",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permissions": {
+ "name": "permissions",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "apikey_user_id_user_id_fk": {
+ "name": "apikey_user_id_user_id_fk",
+ "tableFrom": "apikey",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.invitation": {
+ "name": "invitation",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inviter_id": {
+ "name": "inviter_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "invitation_organization_id_organization_id_fk": {
+ "name": "invitation_organization_id_organization_id_fk",
+ "tableFrom": "invitation",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "invitation_inviter_id_user_id_fk": {
+ "name": "invitation_inviter_id_user_id_fk",
+ "tableFrom": "invitation",
+ "columnsFrom": [
+ "inviter_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.member": {
+ "name": "member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canCreateProjects": {
+ "name": "canCreateProjects",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canAccessToSSHKeys": {
+ "name": "canAccessToSSHKeys",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canCreateServices": {
+ "name": "canCreateServices",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canDeleteProjects": {
+ "name": "canDeleteProjects",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canDeleteServices": {
+ "name": "canDeleteServices",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canAccessToDocker": {
+ "name": "canAccessToDocker",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canAccessToAPI": {
+ "name": "canAccessToAPI",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canAccessToGitProviders": {
+ "name": "canAccessToGitProviders",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canAccessToTraefikFiles": {
+ "name": "canAccessToTraefikFiles",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canDeleteEnvironments": {
+ "name": "canDeleteEnvironments",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "canCreateEnvironments": {
+ "name": "canCreateEnvironments",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "accesedProjects": {
+ "name": "accesedProjects",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY[]::text[]"
+ },
+ "accessedEnvironments": {
+ "name": "accessedEnvironments",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY[]::text[]"
+ },
+ "accesedServices": {
+ "name": "accesedServices",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY[]::text[]"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "member_organization_id_organization_id_fk": {
+ "name": "member_organization_id_organization_id_fk",
+ "tableFrom": "member",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "member_user_id_user_id_fk": {
+ "name": "member_user_id_user_id_fk",
+ "tableFrom": "member",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organization": {
+ "name": "organization",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "logo": {
+ "name": "logo",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_id": {
+ "name": "owner_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "organization_owner_id_user_id_fk": {
+ "name": "organization_owner_id_user_id_fk",
+ "tableFrom": "organization",
+ "columnsFrom": [
+ "owner_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "organization_slug_unique": {
+ "name": "organization_slug_unique",
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.two_factor": {
+ "name": "two_factor",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "secret": {
+ "name": "secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "backup_codes": {
+ "name": "backup_codes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "two_factor_user_id_user_id_fk": {
+ "name": "two_factor_user_id_user_id_fk",
+ "tableFrom": "two_factor",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verification": {
+ "name": "verification",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ai": {
+ "name": "ai",
+ "schema": "",
+ "columns": {
+ "aiId": {
+ "name": "aiId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "apiUrl": {
+ "name": "apiUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "apiKey": {
+ "name": "apiKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "isEnabled": {
+ "name": "isEnabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ai_organizationId_organization_id_fk": {
+ "name": "ai_organizationId_organization_id_fk",
+ "tableFrom": "ai",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.application": {
+ "name": "application",
+ "schema": "",
+ "columns": {
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewEnv": {
+ "name": "previewEnv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "watchPaths": {
+ "name": "watchPaths",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewBuildArgs": {
+ "name": "previewBuildArgs",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewBuildSecrets": {
+ "name": "previewBuildSecrets",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewLabels": {
+ "name": "previewLabels",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewWildcard": {
+ "name": "previewWildcard",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewPort": {
+ "name": "previewPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 3000
+ },
+ "previewHttps": {
+ "name": "previewHttps",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "previewPath": {
+ "name": "previewPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "certificateType": {
+ "name": "certificateType",
+ "type": "certificateType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "previewCustomCertResolver": {
+ "name": "previewCustomCertResolver",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewLimit": {
+ "name": "previewLimit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 3
+ },
+ "isPreviewDeploymentsActive": {
+ "name": "isPreviewDeploymentsActive",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "previewRequireCollaboratorPermissions": {
+ "name": "previewRequireCollaboratorPermissions",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": true
+ },
+ "rollbackActive": {
+ "name": "rollbackActive",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "buildArgs": {
+ "name": "buildArgs",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "buildSecrets": {
+ "name": "buildSecrets",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryReservation": {
+ "name": "memoryReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryLimit": {
+ "name": "memoryLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuReservation": {
+ "name": "cpuReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuLimit": {
+ "name": "cpuLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subtitle": {
+ "name": "subtitle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refreshToken": {
+ "name": "refreshToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sourceType": {
+ "name": "sourceType",
+ "type": "sourceType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'github'"
+ },
+ "cleanCache": {
+ "name": "cleanCache",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "repository": {
+ "name": "repository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner": {
+ "name": "owner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "branch": {
+ "name": "branch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "buildPath": {
+ "name": "buildPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "triggerType": {
+ "name": "triggerType",
+ "type": "triggerType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'push'"
+ },
+ "autoDeploy": {
+ "name": "autoDeploy",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabProjectId": {
+ "name": "gitlabProjectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabRepository": {
+ "name": "gitlabRepository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabOwner": {
+ "name": "gitlabOwner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabBranch": {
+ "name": "gitlabBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabBuildPath": {
+ "name": "gitlabBuildPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "gitlabPathNamespace": {
+ "name": "gitlabPathNamespace",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaRepository": {
+ "name": "giteaRepository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaOwner": {
+ "name": "giteaOwner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaBranch": {
+ "name": "giteaBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaBuildPath": {
+ "name": "giteaBuildPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "bitbucketRepository": {
+ "name": "bitbucketRepository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketOwner": {
+ "name": "bitbucketOwner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketBranch": {
+ "name": "bitbucketBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketBuildPath": {
+ "name": "bitbucketBuildPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dockerImage": {
+ "name": "dockerImage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "registryUrl": {
+ "name": "registryUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitUrl": {
+ "name": "customGitUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitBranch": {
+ "name": "customGitBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitBuildPath": {
+ "name": "customGitBuildPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitSSHKeyId": {
+ "name": "customGitSSHKeyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enableSubmodules": {
+ "name": "enableSubmodules",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "dockerfile": {
+ "name": "dockerfile",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dockerContextPath": {
+ "name": "dockerContextPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dockerBuildStage": {
+ "name": "dockerBuildStage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dropBuildPath": {
+ "name": "dropBuildPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "healthCheckSwarm": {
+ "name": "healthCheckSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restartPolicySwarm": {
+ "name": "restartPolicySwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "placementSwarm": {
+ "name": "placementSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updateConfigSwarm": {
+ "name": "updateConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackConfigSwarm": {
+ "name": "rollbackConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modeSwarm": {
+ "name": "modeSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labelsSwarm": {
+ "name": "labelsSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "networkSwarm": {
+ "name": "networkSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopGracePeriodSwarm": {
+ "name": "stopGracePeriodSwarm",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpointSpecSwarm": {
+ "name": "endpointSpecSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicas": {
+ "name": "replicas",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "applicationStatus": {
+ "name": "applicationStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "buildType": {
+ "name": "buildType",
+ "type": "buildType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'nixpacks'"
+ },
+ "railpackVersion": {
+ "name": "railpackVersion",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'0.2.2'"
+ },
+ "herokuVersion": {
+ "name": "herokuVersion",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'24'"
+ },
+ "publishDirectory": {
+ "name": "publishDirectory",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "isStaticSpa": {
+ "name": "isStaticSpa",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "registryId": {
+ "name": "registryId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "githubId": {
+ "name": "githubId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabId": {
+ "name": "gitlabId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaId": {
+ "name": "giteaId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketId": {
+ "name": "bitbucketId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "application_customGitSSHKeyId_ssh-key_sshKeyId_fk": {
+ "name": "application_customGitSSHKeyId_ssh-key_sshKeyId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "customGitSSHKeyId"
+ ],
+ "tableTo": "ssh-key",
+ "columnsTo": [
+ "sshKeyId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "application_registryId_registry_registryId_fk": {
+ "name": "application_registryId_registry_registryId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "registryId"
+ ],
+ "tableTo": "registry",
+ "columnsTo": [
+ "registryId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "application_environmentId_environment_environmentId_fk": {
+ "name": "application_environmentId_environment_environmentId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "application_githubId_github_githubId_fk": {
+ "name": "application_githubId_github_githubId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "githubId"
+ ],
+ "tableTo": "github",
+ "columnsTo": [
+ "githubId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "application_gitlabId_gitlab_gitlabId_fk": {
+ "name": "application_gitlabId_gitlab_gitlabId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "gitlabId"
+ ],
+ "tableTo": "gitlab",
+ "columnsTo": [
+ "gitlabId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "application_giteaId_gitea_giteaId_fk": {
+ "name": "application_giteaId_gitea_giteaId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "giteaId"
+ ],
+ "tableTo": "gitea",
+ "columnsTo": [
+ "giteaId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "application_bitbucketId_bitbucket_bitbucketId_fk": {
+ "name": "application_bitbucketId_bitbucket_bitbucketId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "bitbucketId"
+ ],
+ "tableTo": "bitbucket",
+ "columnsTo": [
+ "bitbucketId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "application_serverId_server_serverId_fk": {
+ "name": "application_serverId_server_serverId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "application_appName_unique": {
+ "name": "application_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.backup": {
+ "name": "backup",
+ "schema": "",
+ "columns": {
+ "backupId": {
+ "name": "backupId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schedule": {
+ "name": "schedule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "database": {
+ "name": "database",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serviceName": {
+ "name": "serviceName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "destinationId": {
+ "name": "destinationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keepLatestCount": {
+ "name": "keepLatestCount",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "backupType": {
+ "name": "backupType",
+ "type": "backupType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'database'"
+ },
+ "databaseType": {
+ "name": "databaseType",
+ "type": "databaseType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "postgresId": {
+ "name": "postgresId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mariadbId": {
+ "name": "mariadbId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mysqlId": {
+ "name": "mysqlId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mongoId": {
+ "name": "mongoId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "backup_destinationId_destination_destinationId_fk": {
+ "name": "backup_destinationId_destination_destinationId_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "destinationId"
+ ],
+ "tableTo": "destination",
+ "columnsTo": [
+ "destinationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "backup_composeId_compose_composeId_fk": {
+ "name": "backup_composeId_compose_composeId_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "composeId"
+ ],
+ "tableTo": "compose",
+ "columnsTo": [
+ "composeId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "backup_postgresId_postgres_postgresId_fk": {
+ "name": "backup_postgresId_postgres_postgresId_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "postgresId"
+ ],
+ "tableTo": "postgres",
+ "columnsTo": [
+ "postgresId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "backup_mariadbId_mariadb_mariadbId_fk": {
+ "name": "backup_mariadbId_mariadb_mariadbId_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "mariadbId"
+ ],
+ "tableTo": "mariadb",
+ "columnsTo": [
+ "mariadbId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "backup_mysqlId_mysql_mysqlId_fk": {
+ "name": "backup_mysqlId_mysql_mysqlId_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "mysqlId"
+ ],
+ "tableTo": "mysql",
+ "columnsTo": [
+ "mysqlId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "backup_mongoId_mongo_mongoId_fk": {
+ "name": "backup_mongoId_mongo_mongoId_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "mongoId"
+ ],
+ "tableTo": "mongo",
+ "columnsTo": [
+ "mongoId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "backup_userId_user_id_fk": {
+ "name": "backup_userId_user_id_fk",
+ "tableFrom": "backup",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "backup_appName_unique": {
+ "name": "backup_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.bitbucket": {
+ "name": "bitbucket",
+ "schema": "",
+ "columns": {
+ "bitbucketId": {
+ "name": "bitbucketId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "bitbucketUsername": {
+ "name": "bitbucketUsername",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketEmail": {
+ "name": "bitbucketEmail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "appPassword": {
+ "name": "appPassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "apiToken": {
+ "name": "apiToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketWorkspaceName": {
+ "name": "bitbucketWorkspaceName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitProviderId": {
+ "name": "gitProviderId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "bitbucket_gitProviderId_git_provider_gitProviderId_fk": {
+ "name": "bitbucket_gitProviderId_git_provider_gitProviderId_fk",
+ "tableFrom": "bitbucket",
+ "columnsFrom": [
+ "gitProviderId"
+ ],
+ "tableTo": "git_provider",
+ "columnsTo": [
+ "gitProviderId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.certificate": {
+ "name": "certificate",
+ "schema": "",
+ "columns": {
+ "certificateId": {
+ "name": "certificateId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "certificateData": {
+ "name": "certificateData",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "privateKey": {
+ "name": "privateKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "certificatePath": {
+ "name": "certificatePath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "autoRenew": {
+ "name": "autoRenew",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "certificate_organizationId_organization_id_fk": {
+ "name": "certificate_organizationId_organization_id_fk",
+ "tableFrom": "certificate",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "certificate_serverId_server_serverId_fk": {
+ "name": "certificate_serverId_server_serverId_fk",
+ "tableFrom": "certificate",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "certificate_certificatePath_unique": {
+ "name": "certificate_certificatePath_unique",
+ "columns": [
+ "certificatePath"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.compose": {
+ "name": "compose",
+ "schema": "",
+ "columns": {
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "composeFile": {
+ "name": "composeFile",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "refreshToken": {
+ "name": "refreshToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sourceType": {
+ "name": "sourceType",
+ "type": "sourceTypeCompose",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'github'"
+ },
+ "composeType": {
+ "name": "composeType",
+ "type": "composeType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'docker-compose'"
+ },
+ "repository": {
+ "name": "repository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner": {
+ "name": "owner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "branch": {
+ "name": "branch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "autoDeploy": {
+ "name": "autoDeploy",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabProjectId": {
+ "name": "gitlabProjectId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabRepository": {
+ "name": "gitlabRepository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabOwner": {
+ "name": "gitlabOwner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabBranch": {
+ "name": "gitlabBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabPathNamespace": {
+ "name": "gitlabPathNamespace",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketRepository": {
+ "name": "bitbucketRepository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketOwner": {
+ "name": "bitbucketOwner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketBranch": {
+ "name": "bitbucketBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaRepository": {
+ "name": "giteaRepository",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaOwner": {
+ "name": "giteaOwner",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaBranch": {
+ "name": "giteaBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitUrl": {
+ "name": "customGitUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitBranch": {
+ "name": "customGitBranch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customGitSSHKeyId": {
+ "name": "customGitSSHKeyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "enableSubmodules": {
+ "name": "enableSubmodules",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "composePath": {
+ "name": "composePath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'./docker-compose.yml'"
+ },
+ "suffix": {
+ "name": "suffix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "randomize": {
+ "name": "randomize",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "isolatedDeployment": {
+ "name": "isolatedDeployment",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "isolatedDeploymentsVolume": {
+ "name": "isolatedDeploymentsVolume",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "triggerType": {
+ "name": "triggerType",
+ "type": "triggerType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'push'"
+ },
+ "composeStatus": {
+ "name": "composeStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "watchPaths": {
+ "name": "watchPaths",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubId": {
+ "name": "githubId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitlabId": {
+ "name": "gitlabId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bitbucketId": {
+ "name": "bitbucketId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "giteaId": {
+ "name": "giteaId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk": {
+ "name": "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "customGitSSHKeyId"
+ ],
+ "tableTo": "ssh-key",
+ "columnsTo": [
+ "sshKeyId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "compose_environmentId_environment_environmentId_fk": {
+ "name": "compose_environmentId_environment_environmentId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "compose_githubId_github_githubId_fk": {
+ "name": "compose_githubId_github_githubId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "githubId"
+ ],
+ "tableTo": "github",
+ "columnsTo": [
+ "githubId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "compose_gitlabId_gitlab_gitlabId_fk": {
+ "name": "compose_gitlabId_gitlab_gitlabId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "gitlabId"
+ ],
+ "tableTo": "gitlab",
+ "columnsTo": [
+ "gitlabId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "compose_bitbucketId_bitbucket_bitbucketId_fk": {
+ "name": "compose_bitbucketId_bitbucket_bitbucketId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "bitbucketId"
+ ],
+ "tableTo": "bitbucket",
+ "columnsTo": [
+ "bitbucketId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "compose_giteaId_gitea_giteaId_fk": {
+ "name": "compose_giteaId_gitea_giteaId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "giteaId"
+ ],
+ "tableTo": "gitea",
+ "columnsTo": [
+ "giteaId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "compose_serverId_server_serverId_fk": {
+ "name": "compose_serverId_server_serverId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.deployment": {
+ "name": "deployment",
+ "schema": "",
+ "columns": {
+ "deploymentId": {
+ "name": "deploymentId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "deploymentStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'running'"
+ },
+ "logPath": {
+ "name": "logPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pid": {
+ "name": "pid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "isPreviewDeployment": {
+ "name": "isPreviewDeployment",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "previewDeploymentId": {
+ "name": "previewDeploymentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "startedAt": {
+ "name": "startedAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "finishedAt": {
+ "name": "finishedAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "errorMessage": {
+ "name": "errorMessage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scheduleId": {
+ "name": "scheduleId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "backupId": {
+ "name": "backupId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackId": {
+ "name": "rollbackId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "volumeBackupId": {
+ "name": "volumeBackupId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "deployment_applicationId_application_applicationId_fk": {
+ "name": "deployment_applicationId_application_applicationId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_composeId_compose_composeId_fk": {
+ "name": "deployment_composeId_compose_composeId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "composeId"
+ ],
+ "tableTo": "compose",
+ "columnsTo": [
+ "composeId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_serverId_server_serverId_fk": {
+ "name": "deployment_serverId_server_serverId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
+ "name": "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "previewDeploymentId"
+ ],
+ "tableTo": "preview_deployments",
+ "columnsTo": [
+ "previewDeploymentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_scheduleId_schedule_scheduleId_fk": {
+ "name": "deployment_scheduleId_schedule_scheduleId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "scheduleId"
+ ],
+ "tableTo": "schedule",
+ "columnsTo": [
+ "scheduleId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_backupId_backup_backupId_fk": {
+ "name": "deployment_backupId_backup_backupId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "backupId"
+ ],
+ "tableTo": "backup",
+ "columnsTo": [
+ "backupId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_rollbackId_rollback_rollbackId_fk": {
+ "name": "deployment_rollbackId_rollback_rollbackId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "rollbackId"
+ ],
+ "tableTo": "rollback",
+ "columnsTo": [
+ "rollbackId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "deployment_volumeBackupId_volume_backup_volumeBackupId_fk": {
+ "name": "deployment_volumeBackupId_volume_backup_volumeBackupId_fk",
+ "tableFrom": "deployment",
+ "columnsFrom": [
+ "volumeBackupId"
+ ],
+ "tableTo": "volume_backup",
+ "columnsTo": [
+ "volumeBackupId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.destination": {
+ "name": "destination",
+ "schema": "",
+ "columns": {
+ "destinationId": {
+ "name": "destinationId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accessKey": {
+ "name": "accessKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secretAccessKey": {
+ "name": "secretAccessKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bucket": {
+ "name": "bucket",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "region": {
+ "name": "region",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "endpoint": {
+ "name": "endpoint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "destination_organizationId_organization_id_fk": {
+ "name": "destination_organizationId_organization_id_fk",
+ "tableFrom": "destination",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.domain": {
+ "name": "domain",
+ "schema": "",
+ "columns": {
+ "domainId": {
+ "name": "domainId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "host": {
+ "name": "host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "https": {
+ "name": "https",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "port": {
+ "name": "port",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 3000
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "serviceName": {
+ "name": "serviceName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "domainType": {
+ "name": "domainType",
+ "type": "domainType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'application'"
+ },
+ "uniqueConfigKey": {
+ "name": "uniqueConfigKey",
+ "type": "serial",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customCertResolver": {
+ "name": "customCertResolver",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "previewDeploymentId": {
+ "name": "previewDeploymentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "certificateType": {
+ "name": "certificateType",
+ "type": "certificateType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "internalPath": {
+ "name": "internalPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'/'"
+ },
+ "stripPath": {
+ "name": "stripPath",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "domain_composeId_compose_composeId_fk": {
+ "name": "domain_composeId_compose_composeId_fk",
+ "tableFrom": "domain",
+ "columnsFrom": [
+ "composeId"
+ ],
+ "tableTo": "compose",
+ "columnsTo": [
+ "composeId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "domain_applicationId_application_applicationId_fk": {
+ "name": "domain_applicationId_application_applicationId_fk",
+ "tableFrom": "domain",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
+ "name": "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
+ "tableFrom": "domain",
+ "columnsFrom": [
+ "previewDeploymentId"
+ ],
+ "tableTo": "preview_deployments",
+ "columnsTo": [
+ "previewDeploymentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.environment": {
+ "name": "environment",
+ "schema": "",
+ "columns": {
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "environment_projectId_project_projectId_fk": {
+ "name": "environment_projectId_project_projectId_fk",
+ "tableFrom": "environment",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.git_provider": {
+ "name": "git_provider",
+ "schema": "",
+ "columns": {
+ "gitProviderId": {
+ "name": "gitProviderId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "providerType": {
+ "name": "providerType",
+ "type": "gitProviderType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'github'"
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "git_provider_organizationId_organization_id_fk": {
+ "name": "git_provider_organizationId_organization_id_fk",
+ "tableFrom": "git_provider",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "git_provider_userId_user_id_fk": {
+ "name": "git_provider_userId_user_id_fk",
+ "tableFrom": "git_provider",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.gitea": {
+ "name": "gitea",
+ "schema": "",
+ "columns": {
+ "giteaId": {
+ "name": "giteaId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "giteaUrl": {
+ "name": "giteaUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'https://gitea.com'"
+ },
+ "redirect_uri": {
+ "name": "redirect_uri",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_secret": {
+ "name": "client_secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitProviderId": {
+ "name": "gitProviderId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'repo,repo:status,read:user,read:org'"
+ },
+ "last_authenticated_at": {
+ "name": "last_authenticated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "gitea_gitProviderId_git_provider_gitProviderId_fk": {
+ "name": "gitea_gitProviderId_git_provider_gitProviderId_fk",
+ "tableFrom": "gitea",
+ "columnsFrom": [
+ "gitProviderId"
+ ],
+ "tableTo": "git_provider",
+ "columnsTo": [
+ "gitProviderId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.github": {
+ "name": "github",
+ "schema": "",
+ "columns": {
+ "githubId": {
+ "name": "githubId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "githubAppName": {
+ "name": "githubAppName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubAppId": {
+ "name": "githubAppId",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubClientId": {
+ "name": "githubClientId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubClientSecret": {
+ "name": "githubClientSecret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubInstallationId": {
+ "name": "githubInstallationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubPrivateKey": {
+ "name": "githubPrivateKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "githubWebhookSecret": {
+ "name": "githubWebhookSecret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitProviderId": {
+ "name": "gitProviderId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "github_gitProviderId_git_provider_gitProviderId_fk": {
+ "name": "github_gitProviderId_git_provider_gitProviderId_fk",
+ "tableFrom": "github",
+ "columnsFrom": [
+ "gitProviderId"
+ ],
+ "tableTo": "git_provider",
+ "columnsTo": [
+ "gitProviderId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.gitlab": {
+ "name": "gitlab",
+ "schema": "",
+ "columns": {
+ "gitlabId": {
+ "name": "gitlabId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "gitlabUrl": {
+ "name": "gitlabUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'https://gitlab.com'"
+ },
+ "application_id": {
+ "name": "application_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redirect_uri": {
+ "name": "redirect_uri",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret": {
+ "name": "secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "group_name": {
+ "name": "group_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gitProviderId": {
+ "name": "gitProviderId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "gitlab_gitProviderId_git_provider_gitProviderId_fk": {
+ "name": "gitlab_gitProviderId_git_provider_gitProviderId_fk",
+ "tableFrom": "gitlab",
+ "columnsFrom": [
+ "gitProviderId"
+ ],
+ "tableTo": "git_provider",
+ "columnsTo": [
+ "gitProviderId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mariadb": {
+ "name": "mariadb",
+ "schema": "",
+ "columns": {
+ "mariadbId": {
+ "name": "mariadbId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "databaseName": {
+ "name": "databaseName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databaseUser": {
+ "name": "databaseUser",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databasePassword": {
+ "name": "databasePassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rootPassword": {
+ "name": "rootPassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dockerImage": {
+ "name": "dockerImage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryReservation": {
+ "name": "memoryReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryLimit": {
+ "name": "memoryLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuReservation": {
+ "name": "cpuReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuLimit": {
+ "name": "cpuLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "externalPort": {
+ "name": "externalPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationStatus": {
+ "name": "applicationStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "healthCheckSwarm": {
+ "name": "healthCheckSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restartPolicySwarm": {
+ "name": "restartPolicySwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "placementSwarm": {
+ "name": "placementSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updateConfigSwarm": {
+ "name": "updateConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackConfigSwarm": {
+ "name": "rollbackConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modeSwarm": {
+ "name": "modeSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labelsSwarm": {
+ "name": "labelsSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "networkSwarm": {
+ "name": "networkSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopGracePeriodSwarm": {
+ "name": "stopGracePeriodSwarm",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpointSpecSwarm": {
+ "name": "endpointSpecSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicas": {
+ "name": "replicas",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mariadb_environmentId_environment_environmentId_fk": {
+ "name": "mariadb_environmentId_environment_environmentId_fk",
+ "tableFrom": "mariadb",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mariadb_serverId_server_serverId_fk": {
+ "name": "mariadb_serverId_server_serverId_fk",
+ "tableFrom": "mariadb",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "mariadb_appName_unique": {
+ "name": "mariadb_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mongo": {
+ "name": "mongo",
+ "schema": "",
+ "columns": {
+ "mongoId": {
+ "name": "mongoId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "databaseUser": {
+ "name": "databaseUser",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databasePassword": {
+ "name": "databasePassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dockerImage": {
+ "name": "dockerImage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryReservation": {
+ "name": "memoryReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryLimit": {
+ "name": "memoryLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuReservation": {
+ "name": "cpuReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuLimit": {
+ "name": "cpuLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "externalPort": {
+ "name": "externalPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationStatus": {
+ "name": "applicationStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "healthCheckSwarm": {
+ "name": "healthCheckSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restartPolicySwarm": {
+ "name": "restartPolicySwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "placementSwarm": {
+ "name": "placementSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updateConfigSwarm": {
+ "name": "updateConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackConfigSwarm": {
+ "name": "rollbackConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modeSwarm": {
+ "name": "modeSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labelsSwarm": {
+ "name": "labelsSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "networkSwarm": {
+ "name": "networkSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopGracePeriodSwarm": {
+ "name": "stopGracePeriodSwarm",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpointSpecSwarm": {
+ "name": "endpointSpecSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicas": {
+ "name": "replicas",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicaSets": {
+ "name": "replicaSets",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mongo_environmentId_environment_environmentId_fk": {
+ "name": "mongo_environmentId_environment_environmentId_fk",
+ "tableFrom": "mongo",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mongo_serverId_server_serverId_fk": {
+ "name": "mongo_serverId_server_serverId_fk",
+ "tableFrom": "mongo",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "mongo_appName_unique": {
+ "name": "mongo_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mount": {
+ "name": "mount",
+ "schema": "",
+ "columns": {
+ "mountId": {
+ "name": "mountId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "mountType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hostPath": {
+ "name": "hostPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "volumeName": {
+ "name": "volumeName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "filePath": {
+ "name": "filePath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serviceType": {
+ "name": "serviceType",
+ "type": "serviceType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'application'"
+ },
+ "mountPath": {
+ "name": "mountPath",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "postgresId": {
+ "name": "postgresId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mariadbId": {
+ "name": "mariadbId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mongoId": {
+ "name": "mongoId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mysqlId": {
+ "name": "mysqlId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redisId": {
+ "name": "redisId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mount_applicationId_application_applicationId_fk": {
+ "name": "mount_applicationId_application_applicationId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mount_postgresId_postgres_postgresId_fk": {
+ "name": "mount_postgresId_postgres_postgresId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "postgresId"
+ ],
+ "tableTo": "postgres",
+ "columnsTo": [
+ "postgresId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mount_mariadbId_mariadb_mariadbId_fk": {
+ "name": "mount_mariadbId_mariadb_mariadbId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "mariadbId"
+ ],
+ "tableTo": "mariadb",
+ "columnsTo": [
+ "mariadbId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mount_mongoId_mongo_mongoId_fk": {
+ "name": "mount_mongoId_mongo_mongoId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "mongoId"
+ ],
+ "tableTo": "mongo",
+ "columnsTo": [
+ "mongoId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mount_mysqlId_mysql_mysqlId_fk": {
+ "name": "mount_mysqlId_mysql_mysqlId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "mysqlId"
+ ],
+ "tableTo": "mysql",
+ "columnsTo": [
+ "mysqlId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mount_redisId_redis_redisId_fk": {
+ "name": "mount_redisId_redis_redisId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "redisId"
+ ],
+ "tableTo": "redis",
+ "columnsTo": [
+ "redisId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mount_composeId_compose_composeId_fk": {
+ "name": "mount_composeId_compose_composeId_fk",
+ "tableFrom": "mount",
+ "columnsFrom": [
+ "composeId"
+ ],
+ "tableTo": "compose",
+ "columnsTo": [
+ "composeId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mysql": {
+ "name": "mysql",
+ "schema": "",
+ "columns": {
+ "mysqlId": {
+ "name": "mysqlId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "databaseName": {
+ "name": "databaseName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databaseUser": {
+ "name": "databaseUser",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databasePassword": {
+ "name": "databasePassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rootPassword": {
+ "name": "rootPassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dockerImage": {
+ "name": "dockerImage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryReservation": {
+ "name": "memoryReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryLimit": {
+ "name": "memoryLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuReservation": {
+ "name": "cpuReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuLimit": {
+ "name": "cpuLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "externalPort": {
+ "name": "externalPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationStatus": {
+ "name": "applicationStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "healthCheckSwarm": {
+ "name": "healthCheckSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restartPolicySwarm": {
+ "name": "restartPolicySwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "placementSwarm": {
+ "name": "placementSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updateConfigSwarm": {
+ "name": "updateConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackConfigSwarm": {
+ "name": "rollbackConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modeSwarm": {
+ "name": "modeSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labelsSwarm": {
+ "name": "labelsSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "networkSwarm": {
+ "name": "networkSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopGracePeriodSwarm": {
+ "name": "stopGracePeriodSwarm",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpointSpecSwarm": {
+ "name": "endpointSpecSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicas": {
+ "name": "replicas",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mysql_environmentId_environment_environmentId_fk": {
+ "name": "mysql_environmentId_environment_environmentId_fk",
+ "tableFrom": "mysql",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "mysql_serverId_server_serverId_fk": {
+ "name": "mysql_serverId_server_serverId_fk",
+ "tableFrom": "mysql",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "mysql_appName_unique": {
+ "name": "mysql_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.discord": {
+ "name": "discord",
+ "schema": "",
+ "columns": {
+ "discordId": {
+ "name": "discordId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "webhookUrl": {
+ "name": "webhookUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "decoration": {
+ "name": "decoration",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.email": {
+ "name": "email",
+ "schema": "",
+ "columns": {
+ "emailId": {
+ "name": "emailId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "smtpServer": {
+ "name": "smtpServer",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "smtpPort": {
+ "name": "smtpPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fromAddress": {
+ "name": "fromAddress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "toAddress": {
+ "name": "toAddress",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.gotify": {
+ "name": "gotify",
+ "schema": "",
+ "columns": {
+ "gotifyId": {
+ "name": "gotifyId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "serverUrl": {
+ "name": "serverUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appToken": {
+ "name": "appToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 5
+ },
+ "decoration": {
+ "name": "decoration",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.lark": {
+ "name": "lark",
+ "schema": "",
+ "columns": {
+ "larkId": {
+ "name": "larkId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "webhookUrl": {
+ "name": "webhookUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.notification": {
+ "name": "notification",
+ "schema": "",
+ "columns": {
+ "notificationId": {
+ "name": "notificationId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appDeploy": {
+ "name": "appDeploy",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "appBuildError": {
+ "name": "appBuildError",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "databaseBackup": {
+ "name": "databaseBackup",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "dokployRestart": {
+ "name": "dokployRestart",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "dockerCleanup": {
+ "name": "dockerCleanup",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "serverThreshold": {
+ "name": "serverThreshold",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "notificationType": {
+ "name": "notificationType",
+ "type": "notificationType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slackId": {
+ "name": "slackId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "telegramId": {
+ "name": "telegramId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "discordId": {
+ "name": "discordId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "emailId": {
+ "name": "emailId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gotifyId": {
+ "name": "gotifyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ntfyId": {
+ "name": "ntfyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "larkId": {
+ "name": "larkId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "notification_slackId_slack_slackId_fk": {
+ "name": "notification_slackId_slack_slackId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "slackId"
+ ],
+ "tableTo": "slack",
+ "columnsTo": [
+ "slackId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_telegramId_telegram_telegramId_fk": {
+ "name": "notification_telegramId_telegram_telegramId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "telegramId"
+ ],
+ "tableTo": "telegram",
+ "columnsTo": [
+ "telegramId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_discordId_discord_discordId_fk": {
+ "name": "notification_discordId_discord_discordId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "discordId"
+ ],
+ "tableTo": "discord",
+ "columnsTo": [
+ "discordId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_emailId_email_emailId_fk": {
+ "name": "notification_emailId_email_emailId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "emailId"
+ ],
+ "tableTo": "email",
+ "columnsTo": [
+ "emailId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_gotifyId_gotify_gotifyId_fk": {
+ "name": "notification_gotifyId_gotify_gotifyId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "gotifyId"
+ ],
+ "tableTo": "gotify",
+ "columnsTo": [
+ "gotifyId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_ntfyId_ntfy_ntfyId_fk": {
+ "name": "notification_ntfyId_ntfy_ntfyId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "ntfyId"
+ ],
+ "tableTo": "ntfy",
+ "columnsTo": [
+ "ntfyId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_larkId_lark_larkId_fk": {
+ "name": "notification_larkId_lark_larkId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "larkId"
+ ],
+ "tableTo": "lark",
+ "columnsTo": [
+ "larkId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "notification_organizationId_organization_id_fk": {
+ "name": "notification_organizationId_organization_id_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ntfy": {
+ "name": "ntfy",
+ "schema": "",
+ "columns": {
+ "ntfyId": {
+ "name": "ntfyId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "serverUrl": {
+ "name": "serverUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "topic": {
+ "name": "topic",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "accessToken": {
+ "name": "accessToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 3
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.slack": {
+ "name": "slack",
+ "schema": "",
+ "columns": {
+ "slackId": {
+ "name": "slackId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "webhookUrl": {
+ "name": "webhookUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "channel": {
+ "name": "channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.telegram": {
+ "name": "telegram",
+ "schema": "",
+ "columns": {
+ "telegramId": {
+ "name": "telegramId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "botToken": {
+ "name": "botToken",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chatId": {
+ "name": "chatId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "messageThreadId": {
+ "name": "messageThreadId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.port": {
+ "name": "port",
+ "schema": "",
+ "columns": {
+ "portId": {
+ "name": "portId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "publishedPort": {
+ "name": "publishedPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "publishMode": {
+ "name": "publishMode",
+ "type": "publishModeType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'host'"
+ },
+ "targetPort": {
+ "name": "targetPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "protocol": {
+ "name": "protocol",
+ "type": "protocolType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "port_applicationId_application_applicationId_fk": {
+ "name": "port_applicationId_application_applicationId_fk",
+ "tableFrom": "port",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.postgres": {
+ "name": "postgres",
+ "schema": "",
+ "columns": {
+ "postgresId": {
+ "name": "postgresId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databaseName": {
+ "name": "databaseName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databaseUser": {
+ "name": "databaseUser",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databasePassword": {
+ "name": "databasePassword",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dockerImage": {
+ "name": "dockerImage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryReservation": {
+ "name": "memoryReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "externalPort": {
+ "name": "externalPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryLimit": {
+ "name": "memoryLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuReservation": {
+ "name": "cpuReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuLimit": {
+ "name": "cpuLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationStatus": {
+ "name": "applicationStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "healthCheckSwarm": {
+ "name": "healthCheckSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restartPolicySwarm": {
+ "name": "restartPolicySwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "placementSwarm": {
+ "name": "placementSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updateConfigSwarm": {
+ "name": "updateConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackConfigSwarm": {
+ "name": "rollbackConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modeSwarm": {
+ "name": "modeSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labelsSwarm": {
+ "name": "labelsSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "networkSwarm": {
+ "name": "networkSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopGracePeriodSwarm": {
+ "name": "stopGracePeriodSwarm",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpointSpecSwarm": {
+ "name": "endpointSpecSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicas": {
+ "name": "replicas",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "postgres_environmentId_environment_environmentId_fk": {
+ "name": "postgres_environmentId_environment_environmentId_fk",
+ "tableFrom": "postgres",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "postgres_serverId_server_serverId_fk": {
+ "name": "postgres_serverId_server_serverId_fk",
+ "tableFrom": "postgres",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "postgres_appName_unique": {
+ "name": "postgres_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.preview_deployments": {
+ "name": "preview_deployments",
+ "schema": "",
+ "columns": {
+ "previewDeploymentId": {
+ "name": "previewDeploymentId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "branch": {
+ "name": "branch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pullRequestId": {
+ "name": "pullRequestId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pullRequestNumber": {
+ "name": "pullRequestNumber",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pullRequestURL": {
+ "name": "pullRequestURL",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pullRequestTitle": {
+ "name": "pullRequestTitle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pullRequestCommentId": {
+ "name": "pullRequestCommentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previewStatus": {
+ "name": "previewStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "domainId": {
+ "name": "domainId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiresAt": {
+ "name": "expiresAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "preview_deployments_applicationId_application_applicationId_fk": {
+ "name": "preview_deployments_applicationId_application_applicationId_fk",
+ "tableFrom": "preview_deployments",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "preview_deployments_domainId_domain_domainId_fk": {
+ "name": "preview_deployments_domainId_domain_domainId_fk",
+ "tableFrom": "preview_deployments",
+ "columnsFrom": [
+ "domainId"
+ ],
+ "tableTo": "domain",
+ "columnsTo": [
+ "domainId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "preview_deployments_appName_unique": {
+ "name": "preview_deployments_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.project": {
+ "name": "project",
+ "schema": "",
+ "columns": {
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "project_organizationId_organization_id_fk": {
+ "name": "project_organizationId_organization_id_fk",
+ "tableFrom": "project",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.redirect": {
+ "name": "redirect",
+ "schema": "",
+ "columns": {
+ "redirectId": {
+ "name": "redirectId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "regex": {
+ "name": "regex",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "replacement": {
+ "name": "replacement",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permanent": {
+ "name": "permanent",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "uniqueConfigKey": {
+ "name": "uniqueConfigKey",
+ "type": "serial",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "redirect_applicationId_application_applicationId_fk": {
+ "name": "redirect_applicationId_application_applicationId_fk",
+ "tableFrom": "redirect",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.redis": {
+ "name": "redis",
+ "schema": "",
+ "columns": {
+ "redisId": {
+ "name": "redisId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dockerImage": {
+ "name": "dockerImage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryReservation": {
+ "name": "memoryReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "memoryLimit": {
+ "name": "memoryLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuReservation": {
+ "name": "cpuReservation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cpuLimit": {
+ "name": "cpuLimit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "externalPort": {
+ "name": "externalPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "applicationStatus": {
+ "name": "applicationStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "healthCheckSwarm": {
+ "name": "healthCheckSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "restartPolicySwarm": {
+ "name": "restartPolicySwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "placementSwarm": {
+ "name": "placementSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updateConfigSwarm": {
+ "name": "updateConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rollbackConfigSwarm": {
+ "name": "rollbackConfigSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "modeSwarm": {
+ "name": "modeSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labelsSwarm": {
+ "name": "labelsSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "networkSwarm": {
+ "name": "networkSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stopGracePeriodSwarm": {
+ "name": "stopGracePeriodSwarm",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpointSpecSwarm": {
+ "name": "endpointSpecSwarm",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "replicas": {
+ "name": "replicas",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "environmentId": {
+ "name": "environmentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "redis_environmentId_environment_environmentId_fk": {
+ "name": "redis_environmentId_environment_environmentId_fk",
+ "tableFrom": "redis",
+ "columnsFrom": [
+ "environmentId"
+ ],
+ "tableTo": "environment",
+ "columnsTo": [
+ "environmentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "redis_serverId_server_serverId_fk": {
+ "name": "redis_serverId_server_serverId_fk",
+ "tableFrom": "redis",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "redis_appName_unique": {
+ "name": "redis_appName_unique",
+ "columns": [
+ "appName"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.registry": {
+ "name": "registry",
+ "schema": "",
+ "columns": {
+ "registryId": {
+ "name": "registryId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "registryName": {
+ "name": "registryName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "imagePrefix": {
+ "name": "imagePrefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "registryUrl": {
+ "name": "registryUrl",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "selfHosted": {
+ "name": "selfHosted",
+ "type": "RegistryType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'cloud'"
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "registry_organizationId_organization_id_fk": {
+ "name": "registry_organizationId_organization_id_fk",
+ "tableFrom": "registry",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.rollback": {
+ "name": "rollback",
+ "schema": "",
+ "columns": {
+ "rollbackId": {
+ "name": "rollbackId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "deploymentId": {
+ "name": "deploymentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "serial",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fullContext": {
+ "name": "fullContext",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "rollback_deploymentId_deployment_deploymentId_fk": {
+ "name": "rollback_deploymentId_deployment_deploymentId_fk",
+ "tableFrom": "rollback",
+ "columnsFrom": [
+ "deploymentId"
+ ],
+ "tableTo": "deployment",
+ "columnsTo": [
+ "deploymentId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.schedule": {
+ "name": "schedule",
+ "schema": "",
+ "columns": {
+ "scheduleId": {
+ "name": "scheduleId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cronExpression": {
+ "name": "cronExpression",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serviceName": {
+ "name": "serviceName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "shellType": {
+ "name": "shellType",
+ "type": "shellType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'bash'"
+ },
+ "scheduleType": {
+ "name": "scheduleType",
+ "type": "scheduleType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'application'"
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "script": {
+ "name": "script",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "schedule_applicationId_application_applicationId_fk": {
+ "name": "schedule_applicationId_application_applicationId_fk",
+ "tableFrom": "schedule",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "schedule_composeId_compose_composeId_fk": {
+ "name": "schedule_composeId_compose_composeId_fk",
+ "tableFrom": "schedule",
+ "columnsFrom": [
+ "composeId"
+ ],
+ "tableTo": "compose",
+ "columnsTo": [
+ "composeId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "schedule_serverId_server_serverId_fk": {
+ "name": "schedule_serverId_server_serverId_fk",
+ "tableFrom": "schedule",
+ "columnsFrom": [
+ "serverId"
+ ],
+ "tableTo": "server",
+ "columnsTo": [
+ "serverId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "schedule_userId_user_id_fk": {
+ "name": "schedule_userId_user_id_fk",
+ "tableFrom": "schedule",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.security": {
+ "name": "security",
+ "schema": "",
+ "columns": {
+ "securityId": {
+ "name": "securityId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "security_applicationId_application_applicationId_fk": {
+ "name": "security_applicationId_application_applicationId_fk",
+ "tableFrom": "security",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "security_username_applicationId_unique": {
+ "name": "security_username_applicationId_unique",
+ "columns": [
+ "username",
+ "applicationId"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.server": {
+ "name": "server",
+ "schema": "",
+ "columns": {
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ipAddress": {
+ "name": "ipAddress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "port": {
+ "name": "port",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'root'"
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enableDockerCleanup": {
+ "name": "enableDockerCleanup",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverStatus": {
+ "name": "serverStatus",
+ "type": "serverStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "sshKeyId": {
+ "name": "sshKeyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metricsConfig": {
+ "name": "metricsConfig",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"server\":{\"type\":\"Remote\",\"refreshRate\":60,\"port\":4500,\"token\":\"\",\"urlCallback\":\"\",\"cronJob\":\"\",\"retentionDays\":2,\"thresholds\":{\"cpu\":0,\"memory\":0}},\"containers\":{\"refreshRate\":60,\"services\":{\"include\":[],\"exclude\":[]}}}'::jsonb"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "server_organizationId_organization_id_fk": {
+ "name": "server_organizationId_organization_id_fk",
+ "tableFrom": "server",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "server_sshKeyId_ssh-key_sshKeyId_fk": {
+ "name": "server_sshKeyId_ssh-key_sshKeyId_fk",
+ "tableFrom": "server",
+ "columnsFrom": [
+ "sshKeyId"
+ ],
+ "tableTo": "ssh-key",
+ "columnsTo": [
+ "sshKeyId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session_temp": {
+ "name": "session_temp",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "impersonated_by": {
+ "name": "impersonated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "active_organization_id": {
+ "name": "active_organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_temp_user_id_user_id_fk": {
+ "name": "session_temp_user_id_user_id_fk",
+ "tableFrom": "session_temp",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "session_temp_token_unique": {
+ "name": "session_temp_token_unique",
+ "columns": [
+ "token"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ssh-key": {
+ "name": "ssh-key",
+ "schema": "",
+ "columns": {
+ "sshKeyId": {
+ "name": "sshKeyId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "privateKey": {
+ "name": "privateKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "publicKey": {
+ "name": "publicKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lastUsedAt": {
+ "name": "lastUsedAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizationId": {
+ "name": "organizationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ssh-key_organizationId_organization_id_fk": {
+ "name": "ssh-key_organizationId_organization_id_fk",
+ "tableFrom": "ssh-key",
+ "columnsFrom": [
+ "organizationId"
+ ],
+ "tableTo": "organization",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "isRegistered": {
+ "name": "isRegistered",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "expirationDate": {
+ "name": "expirationDate",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "two_factor_enabled": {
+ "name": "two_factor_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "banned": {
+ "name": "banned",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ban_reason": {
+ "name": "ban_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ban_expires": {
+ "name": "ban_expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverIp": {
+ "name": "serverIp",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "certificateType": {
+ "name": "certificateType",
+ "type": "certificateType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "https": {
+ "name": "https",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "host": {
+ "name": "host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "letsEncryptEmail": {
+ "name": "letsEncryptEmail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sshPrivateKey": {
+ "name": "sshPrivateKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enableDockerCleanup": {
+ "name": "enableDockerCleanup",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "logCleanupCron": {
+ "name": "logCleanupCron",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'0 0 * * *'"
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'user'"
+ },
+ "enablePaidFeatures": {
+ "name": "enablePaidFeatures",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "allowImpersonation": {
+ "name": "allowImpersonation",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "metricsConfig": {
+ "name": "metricsConfig",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"server\":{\"type\":\"Dokploy\",\"refreshRate\":60,\"port\":4500,\"token\":\"\",\"retentionDays\":2,\"cronJob\":\"\",\"urlCallback\":\"\",\"thresholds\":{\"cpu\":0,\"memory\":0}},\"containers\":{\"refreshRate\":60,\"services\":{\"include\":[],\"exclude\":[]}}}'::jsonb"
+ },
+ "cleanupCacheApplications": {
+ "name": "cleanupCacheApplications",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cleanupCacheOnPreviews": {
+ "name": "cleanupCacheOnPreviews",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cleanupCacheOnCompose": {
+ "name": "cleanupCacheOnCompose",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "stripeCustomerId": {
+ "name": "stripeCustomerId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripeSubscriptionId": {
+ "name": "stripeSubscriptionId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serversQuantity": {
+ "name": "serversQuantity",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.volume_backup": {
+ "name": "volume_backup",
+ "schema": "",
+ "columns": {
+ "volumeBackupId": {
+ "name": "volumeBackupId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "volumeName": {
+ "name": "volumeName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serviceType": {
+ "name": "serviceType",
+ "type": "serviceType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'application'"
+ },
+ "appName": {
+ "name": "appName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serviceName": {
+ "name": "serviceName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "turnOff": {
+ "name": "turnOff",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cronExpression": {
+ "name": "cronExpression",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keepLatestCount": {
+ "name": "keepLatestCount",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "applicationId": {
+ "name": "applicationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "postgresId": {
+ "name": "postgresId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mariadbId": {
+ "name": "mariadbId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mongoId": {
+ "name": "mongoId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mysqlId": {
+ "name": "mysqlId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redisId": {
+ "name": "redisId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "composeId": {
+ "name": "composeId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "destinationId": {
+ "name": "destinationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "volume_backup_applicationId_application_applicationId_fk": {
+ "name": "volume_backup_applicationId_application_applicationId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "applicationId"
+ ],
+ "tableTo": "application",
+ "columnsTo": [
+ "applicationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_postgresId_postgres_postgresId_fk": {
+ "name": "volume_backup_postgresId_postgres_postgresId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "postgresId"
+ ],
+ "tableTo": "postgres",
+ "columnsTo": [
+ "postgresId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_mariadbId_mariadb_mariadbId_fk": {
+ "name": "volume_backup_mariadbId_mariadb_mariadbId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "mariadbId"
+ ],
+ "tableTo": "mariadb",
+ "columnsTo": [
+ "mariadbId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_mongoId_mongo_mongoId_fk": {
+ "name": "volume_backup_mongoId_mongo_mongoId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "mongoId"
+ ],
+ "tableTo": "mongo",
+ "columnsTo": [
+ "mongoId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_mysqlId_mysql_mysqlId_fk": {
+ "name": "volume_backup_mysqlId_mysql_mysqlId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "mysqlId"
+ ],
+ "tableTo": "mysql",
+ "columnsTo": [
+ "mysqlId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_redisId_redis_redisId_fk": {
+ "name": "volume_backup_redisId_redis_redisId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "redisId"
+ ],
+ "tableTo": "redis",
+ "columnsTo": [
+ "redisId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_composeId_compose_composeId_fk": {
+ "name": "volume_backup_composeId_compose_composeId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "composeId"
+ ],
+ "tableTo": "compose",
+ "columnsTo": [
+ "composeId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "volume_backup_destinationId_destination_destinationId_fk": {
+ "name": "volume_backup_destinationId_destination_destinationId_fk",
+ "tableFrom": "volume_backup",
+ "columnsFrom": [
+ "destinationId"
+ ],
+ "tableTo": "destination",
+ "columnsTo": [
+ "destinationId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.buildType": {
+ "name": "buildType",
+ "schema": "public",
+ "values": [
+ "dockerfile",
+ "heroku_buildpacks",
+ "paketo_buildpacks",
+ "nixpacks",
+ "static",
+ "railpack"
+ ]
+ },
+ "public.sourceType": {
+ "name": "sourceType",
+ "schema": "public",
+ "values": [
+ "docker",
+ "git",
+ "github",
+ "gitlab",
+ "bitbucket",
+ "gitea",
+ "drop"
+ ]
+ },
+ "public.backupType": {
+ "name": "backupType",
+ "schema": "public",
+ "values": [
+ "database",
+ "compose"
+ ]
+ },
+ "public.databaseType": {
+ "name": "databaseType",
+ "schema": "public",
+ "values": [
+ "postgres",
+ "mariadb",
+ "mysql",
+ "mongo",
+ "web-server"
+ ]
+ },
+ "public.composeType": {
+ "name": "composeType",
+ "schema": "public",
+ "values": [
+ "docker-compose",
+ "stack"
+ ]
+ },
+ "public.sourceTypeCompose": {
+ "name": "sourceTypeCompose",
+ "schema": "public",
+ "values": [
+ "git",
+ "github",
+ "gitlab",
+ "bitbucket",
+ "gitea",
+ "raw"
+ ]
+ },
+ "public.deploymentStatus": {
+ "name": "deploymentStatus",
+ "schema": "public",
+ "values": [
+ "running",
+ "done",
+ "error",
+ "cancelled"
+ ]
+ },
+ "public.domainType": {
+ "name": "domainType",
+ "schema": "public",
+ "values": [
+ "compose",
+ "application",
+ "preview"
+ ]
+ },
+ "public.gitProviderType": {
+ "name": "gitProviderType",
+ "schema": "public",
+ "values": [
+ "github",
+ "gitlab",
+ "bitbucket",
+ "gitea"
+ ]
+ },
+ "public.mountType": {
+ "name": "mountType",
+ "schema": "public",
+ "values": [
+ "bind",
+ "volume",
+ "file"
+ ]
+ },
+ "public.serviceType": {
+ "name": "serviceType",
+ "schema": "public",
+ "values": [
+ "application",
+ "postgres",
+ "mysql",
+ "mariadb",
+ "mongo",
+ "redis",
+ "compose"
+ ]
+ },
+ "public.notificationType": {
+ "name": "notificationType",
+ "schema": "public",
+ "values": [
+ "slack",
+ "telegram",
+ "discord",
+ "email",
+ "gotify",
+ "ntfy",
+ "lark"
+ ]
+ },
+ "public.protocolType": {
+ "name": "protocolType",
+ "schema": "public",
+ "values": [
+ "tcp",
+ "udp"
+ ]
+ },
+ "public.publishModeType": {
+ "name": "publishModeType",
+ "schema": "public",
+ "values": [
+ "ingress",
+ "host"
+ ]
+ },
+ "public.RegistryType": {
+ "name": "RegistryType",
+ "schema": "public",
+ "values": [
+ "selfHosted",
+ "cloud"
+ ]
+ },
+ "public.scheduleType": {
+ "name": "scheduleType",
+ "schema": "public",
+ "values": [
+ "application",
+ "compose",
+ "server",
+ "dokploy-server"
+ ]
+ },
+ "public.shellType": {
+ "name": "shellType",
+ "schema": "public",
+ "values": [
+ "bash",
+ "sh"
+ ]
+ },
+ "public.serverStatus": {
+ "name": "serverStatus",
+ "schema": "public",
+ "values": [
+ "active",
+ "inactive"
+ ]
+ },
+ "public.applicationStatus": {
+ "name": "applicationStatus",
+ "schema": "public",
+ "values": [
+ "idle",
+ "running",
+ "done",
+ "error"
+ ]
+ },
+ "public.certificateType": {
+ "name": "certificateType",
+ "schema": "public",
+ "values": [
+ "letsencrypt",
+ "none",
+ "custom"
+ ]
+ },
+ "public.triggerType": {
+ "name": "triggerType",
+ "schema": "public",
+ "values": [
+ "push",
+ "tag"
+ ]
+ }
+ },
+ "schemas": {},
+ "views": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/apps/dokploy/drizzle/meta/_journal.json b/apps/dokploy/drizzle/meta/_journal.json
index c51c288160..323562fd1c 100644
--- a/apps/dokploy/drizzle/meta/_journal.json
+++ b/apps/dokploy/drizzle/meta/_journal.json
@@ -848,6 +848,13 @@
"when": 1762632540024,
"tag": "0120_lame_captain_midlands",
"breakpoints": true
+ },
+ {
+ "idx": 121,
+ "version": "7",
+ "when": 1763755037033,
+ "tag": "0121_rainy_cargill",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json
index e52968b158..1301fe91bf 100644
--- a/apps/dokploy/package.json
+++ b/apps/dokploy/package.json
@@ -1,6 +1,6 @@
{
"name": "dokploy",
- "version": "v0.25.10",
+ "version": "v0.25.11",
"private": true,
"license": "Apache-2.0",
"type": "module",
diff --git a/apps/dokploy/server/api/routers/destination.ts b/apps/dokploy/server/api/routers/destination.ts
index dc5892c857..d7cbf53d55 100644
--- a/apps/dokploy/server/api/routers/destination.ts
+++ b/apps/dokploy/server/api/routers/destination.ts
@@ -47,15 +47,19 @@ export const destinationRouter = createTRPCRouter({
input;
try {
const rcloneFlags = [
- `--s3-access-key-id=${accessKey}`,
- `--s3-secret-access-key=${secretAccessKey}`,
- `--s3-region=${region}`,
- `--s3-endpoint=${endpoint}`,
+ `--s3-access-key-id="${accessKey}"`,
+ `--s3-secret-access-key="${secretAccessKey}"`,
+ `--s3-region="${region}"`,
+ `--s3-endpoint="${endpoint}"`,
"--s3-no-check-bucket",
"--s3-force-path-style",
+ "--retries 1",
+ "--low-level-retries 1",
+ "--timeout 10s",
+ "--contimeout 5s",
];
if (provider) {
- rcloneFlags.unshift(`--s3-provider=${provider}`);
+ rcloneFlags.unshift(`--s3-provider="${provider}"`);
}
const rcloneDestination = `:s3:${bucket}`;
const rcloneCommand = `rclone ls ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
diff --git a/apps/dokploy/server/api/routers/notification.ts b/apps/dokploy/server/api/routers/notification.ts
index 56748dc982..c483b813e7 100644
--- a/apps/dokploy/server/api/routers/notification.ts
+++ b/apps/dokploy/server/api/routers/notification.ts
@@ -111,7 +111,7 @@ export const notificationRouter = createTRPCRouter({
} catch (error) {
throw new TRPCError({
code: "BAD_REQUEST",
- message: "Error testing the notification",
+ message: `${error instanceof Error ? error.message : "Unknown error"}`,
cause: error,
});
}
@@ -228,7 +228,7 @@ export const notificationRouter = createTRPCRouter({
} catch (error) {
throw new TRPCError({
code: "BAD_REQUEST",
- message: "Error testing the notification",
+ message: `${error instanceof Error ? error.message : "Unknown error"}`,
cause: error,
});
}
@@ -285,7 +285,7 @@ export const notificationRouter = createTRPCRouter({
} catch (error) {
throw new TRPCError({
code: "BAD_REQUEST",
- message: "Error testing the notification",
+ message: `${error instanceof Error ? error.message : "Unknown error"}`,
cause: error,
});
}
diff --git a/apps/dokploy/server/api/routers/postgres.ts b/apps/dokploy/server/api/routers/postgres.ts
index a05072ab75..3112beb66a 100644
--- a/apps/dokploy/server/api/routers/postgres.ts
+++ b/apps/dokploy/server/api/routers/postgres.ts
@@ -8,6 +8,7 @@ import {
findEnvironmentById,
findPostgresById,
findProjectById,
+ getMountPath,
IS_CLOUD,
rebuildDatabase,
removePostgresById,
@@ -37,6 +38,7 @@ import {
postgres as postgresTable,
} from "@/server/db/schema";
import { cancelJobs } from "@/server/utils/backup";
+
export const postgresRouter = createTRPCRouter({
create: protectedProcedure
.input(apiCreatePostgres)
@@ -79,11 +81,13 @@ export const postgresRouter = createTRPCRouter({
);
}
+ const mountPath = getMountPath(input.dockerImage);
+
await createMount({
serviceId: newPostgres.postgresId,
serviceType: "postgres",
volumeName: `${newPostgres.appName}-data`,
- mountPath: "/var/lib/postgresql/data",
+ mountPath: mountPath,
type: "volume",
});
@@ -282,12 +286,16 @@ export const postgresRouter = createTRPCRouter({
const backups = await findBackupsByDbId(input.postgresId, "postgres");
const cleanupOperations = [
- removeService(postgres.appName, postgres.serverId),
- cancelJobs(backups),
- removePostgresById(input.postgresId),
+ async () => await removeService(postgres?.appName, postgres.serverId),
+ async () => await cancelJobs(backups),
+ async () => await removePostgresById(input.postgresId),
];
- await Promise.allSettled(cleanupOperations);
+ for (const operation of cleanupOperations) {
+ try {
+ await operation();
+ } catch (_) {}
+ }
return postgres;
}),
@@ -363,6 +371,7 @@ export const postgresRouter = createTRPCRouter({
message: "You are not authorized to update this Postgres",
});
}
+
const service = await updatePostgresById(postgresId, {
...rest,
});
diff --git a/apps/dokploy/server/api/routers/settings.ts b/apps/dokploy/server/api/routers/settings.ts
index b4968c260f..e0a74f5cf2 100644
--- a/apps/dokploy/server/api/routers/settings.ts
+++ b/apps/dokploy/server/api/routers/settings.ts
@@ -587,7 +587,7 @@ export const settingsRouter = createTRPCRouter({
return ports.some((port) => port.targetPort === 8080);
}),
- readStatsLogs: adminProcedure
+ readStatsLogs: protectedProcedure
.meta({
openapi: {
path: "/read-stats-logs",
@@ -650,7 +650,7 @@ export const settingsRouter = createTRPCRouter({
const processedLogs = processLogs(rawConfig as string, input?.dateRange);
return processedLogs || [];
}),
- haveActivateRequests: adminProcedure.query(async () => {
+ haveActivateRequests: protectedProcedure.query(async () => {
if (IS_CLOUD) {
return true;
}
@@ -665,7 +665,7 @@ export const settingsRouter = createTRPCRouter({
return !!parsedConfig?.accessLog?.filePath;
}),
- toggleRequests: adminProcedure
+ toggleRequests: protectedProcedure
.input(
z.object({
enable: z.boolean(),
@@ -835,7 +835,7 @@ export const settingsRouter = createTRPCRouter({
const ports = await readPorts("dokploy-traefik", input?.serverId);
return ports;
}),
- updateLogCleanup: adminProcedure
+ updateLogCleanup: protectedProcedure
.input(
z.object({
cronExpression: z.string().nullable(),
@@ -851,7 +851,7 @@ export const settingsRouter = createTRPCRouter({
return stopLogCleanup();
}),
- getLogCleanupStatus: adminProcedure.query(async () => {
+ getLogCleanupStatus: protectedProcedure.query(async () => {
return getLogCleanupStatus();
}),
diff --git a/packages/server/src/services/application.ts b/packages/server/src/services/application.ts
index 31f015c0c2..6ad90a93bd 100644
--- a/packages/server/src/services/application.ts
+++ b/packages/server/src/services/application.ts
@@ -13,6 +13,7 @@ import {
import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error";
import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success";
import {
+ ExecError,
execAsync,
execAsyncRemote,
} from "@dokploy/server/utils/process/execAsync";
@@ -28,6 +29,7 @@ import { cloneGitlabRepository } from "@dokploy/server/utils/providers/gitlab";
import { createTraefikConfig } from "@dokploy/server/utils/traefik/application";
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
+import { encodeBase64 } from "../utils/docker/utils";
import { getDokployUrl } from "./admin";
import {
createDeployment,
@@ -228,7 +230,16 @@ export const deployApplication = async ({
environmentName: application.environment.name,
});
} catch (error) {
- const command = `echo "Error occurred ❌, check the logs for details." >> ${deployment.logPath};`;
+ let command = "";
+
+ // Only log details for non-ExecError errors
+ if (!(error instanceof ExecError)) {
+ const message = error instanceof Error ? error.message : String(error);
+ const encodedMessage = encodeBase64(message);
+ command += `echo "${encodedMessage}" | base64 -d >> "${deployment.logPath}";`;
+ }
+
+ command += `echo "\nError occurred ❌, check the logs for details." >> ${deployment.logPath};`;
if (application.serverId) {
await execAsyncRemote(application.serverId, command);
} else {
@@ -317,6 +328,21 @@ export const rebuildApplication = async ({
environmentName: application.environment.name,
});
} catch (error) {
+ let command = "";
+
+ // Only log details for non-ExecError errors
+ if (!(error instanceof ExecError)) {
+ const message = error instanceof Error ? error.message : String(error);
+ const encodedMessage = encodeBase64(message);
+ command += `echo "${encodedMessage}" | base64 -d >> "${deployment.logPath}";`;
+ }
+
+ command += `echo "\nError occurred ❌, check the logs for details." >> ${deployment.logPath};`;
+ if (application.serverId) {
+ await execAsyncRemote(application.serverId, command);
+ } else {
+ await execAsync(command);
+ }
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateApplicationStatus(applicationId, "error");
throw error;
diff --git a/packages/server/src/services/compose.ts b/packages/server/src/services/compose.ts
index 1d4a7e5c9c..89a12a1564 100644
--- a/packages/server/src/services/compose.ts
+++ b/packages/server/src/services/compose.ts
@@ -18,6 +18,7 @@ import type { ComposeSpecification } from "@dokploy/server/utils/docker/types";
import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error";
import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success";
import {
+ ExecError,
execAsync,
execAsyncRemote,
} from "@dokploy/server/utils/process/execAsync";
@@ -32,6 +33,7 @@ import { cloneGitlabRepository } from "@dokploy/server/utils/providers/gitlab";
import { getCreateComposeFileCommand } from "@dokploy/server/utils/providers/raw";
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
+import { encodeBase64 } from "../utils/docker/utils";
import { getDokployUrl } from "./admin";
import {
createDeploymentCompose,
@@ -270,6 +272,21 @@ export const deployCompose = async ({
environmentName: compose.environment.name,
});
} catch (error) {
+ let command = "";
+
+ // Only log details for non-ExecError errors
+ if (!(error instanceof ExecError)) {
+ const message = error instanceof Error ? error.message : String(error);
+ const encodedMessage = encodeBase64(message);
+ command += `echo "${encodedMessage}" | base64 -d >> "${deployment.logPath}";`;
+ }
+
+ command += `echo "\nError occurred ❌, check the logs for details." >> ${deployment.logPath};`;
+ if (compose.serverId) {
+ await execAsyncRemote(compose.serverId, command);
+ } else {
+ await execAsync(command);
+ }
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, {
composeStatus: "error",
@@ -342,6 +359,21 @@ export const rebuildCompose = async ({
composeStatus: "done",
});
} catch (error) {
+ let command = "";
+
+ // Only log details for non-ExecError errors
+ if (!(error instanceof ExecError)) {
+ const message = error instanceof Error ? error.message : String(error);
+ const encodedMessage = encodeBase64(message);
+ command += `echo "${encodedMessage}" | base64 -d >> "${deployment.logPath}";`;
+ }
+
+ command += `echo "\nError occurred ❌, check the logs for details." >> ${deployment.logPath};`;
+ if (compose.serverId) {
+ await execAsyncRemote(compose.serverId, command);
+ } else {
+ await execAsync(command);
+ }
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, {
composeStatus: "error",
diff --git a/packages/server/src/services/postgres.ts b/packages/server/src/services/postgres.ts
index 0d900443ea..d7016038a9 100644
--- a/packages/server/src/services/postgres.ts
+++ b/packages/server/src/services/postgres.ts
@@ -13,6 +13,18 @@ import { TRPCError } from "@trpc/server";
import { eq, getTableColumns } from "drizzle-orm";
import { validUniqueServerAppName } from "./project";
+export function getMountPath(dockerImage: string): string {
+ const versionMatch = dockerImage.match(/postgres:(\d+)/);
+
+ if (versionMatch?.[1]) {
+ const version = Number.parseInt(versionMatch[1], 10);
+ if (version >= 18) {
+ return `/var/lib/postgresql/${version}/data`;
+ }
+ }
+ return "/var/lib/postgresql/data";
+}
+
export type Postgres = typeof postgres.$inferSelect;
export const createPostgres = async (input: typeof apiCreatePostgres._type) => {
diff --git a/packages/server/src/services/settings.ts b/packages/server/src/services/settings.ts
index 996aec3524..23d11b09bd 100644
--- a/packages/server/src/services/settings.ts
+++ b/packages/server/src/services/settings.ts
@@ -60,10 +60,7 @@ export const getUpdateData = async (): Promise => {
try {
currentDigest = await getServiceImageDigest();
} catch (error) {
- console.error(error);
- // Docker service might not exist locally
- // You can run the # Installation command for docker service create mentioned in the below docs to test it locally:
- // https://docs.dokploy.com/docs/core/manual-installation
+ // TODO: Docker versions 29.0.0 change the way to get the service image digest, so we need to update this in the future we upgrade to that version.
return DEFAULT_UPDATE_DATA;
}
diff --git a/packages/server/src/setup/postgres-setup.ts b/packages/server/src/setup/postgres-setup.ts
index cf162f1ed2..377a849528 100644
--- a/packages/server/src/setup/postgres-setup.ts
+++ b/packages/server/src/setup/postgres-setup.ts
@@ -17,7 +17,7 @@ export const initializePostgres = async () => {
Mounts: [
{
Type: "volume",
- Source: "dokploy-postgres-database",
+ Source: "dokploy-postgres",
Target: "/var/lib/postgresql/data",
},
],
diff --git a/packages/server/src/setup/redis-setup.ts b/packages/server/src/setup/redis-setup.ts
index 7366546da9..894b3427de 100644
--- a/packages/server/src/setup/redis-setup.ts
+++ b/packages/server/src/setup/redis-setup.ts
@@ -14,7 +14,7 @@ export const initializeRedis = async () => {
Mounts: [
{
Type: "volume",
- Source: "redis-data-volume",
+ Source: "dokploy-redis",
Target: "/data",
},
],
diff --git a/packages/server/src/utils/builders/railpack.ts b/packages/server/src/utils/builders/railpack.ts
index 03d490cdf8..62fa9f9756 100644
--- a/packages/server/src/utils/builders/railpack.ts
+++ b/packages/server/src/utils/builders/railpack.ts
@@ -85,6 +85,9 @@ export const getRailpackCommand = (application: ApplicationNested) => {
const bashCommand = `
# Ensure we have a builder with containerd
+
+export RAILPACK_VERSION=${application.railpackVersion}
+bash -c "$(curl -fsSL https://railpack.com/install.sh)"
docker buildx create --use --name builder-containerd --driver docker-container || true
docker buildx use builder-containerd
diff --git a/packages/server/src/utils/notifications/build-error.ts b/packages/server/src/utils/notifications/build-error.ts
index 67c568b729..3ee9830315 100644
--- a/packages/server/src/utils/notifications/build-error.ts
+++ b/packages/server/src/utils/notifications/build-error.ts
@@ -7,8 +7,8 @@ import { and, eq } from "drizzle-orm";
import {
sendDiscordNotification,
sendEmailNotification,
- sendLarkNotification,
sendGotifyNotification,
+ sendLarkNotification,
sendNtfyNotification,
sendSlackNotification,
sendTelegramNotification,
@@ -52,279 +52,287 @@ export const sendBuildErrorNotifications = async ({
for (const notification of notificationList) {
const { email, discord, telegram, slack, gotify, ntfy, lark } =
notification;
- if (email) {
- const template = await renderAsync(
- BuildFailedEmail({
- projectName,
- applicationName,
- applicationType,
- errorMessage: errorMessage,
- buildLink,
- date: date.toLocaleString(),
- }),
- ).catch();
- await sendEmailNotification(email, "Build failed for dokploy", template);
- }
+ try {
+ if (email) {
+ const template = await renderAsync(
+ BuildFailedEmail({
+ projectName,
+ applicationName,
+ applicationType,
+ errorMessage: errorMessage,
+ buildLink,
+ date: date.toLocaleString(),
+ }),
+ ).catch();
+ await sendEmailNotification(
+ email,
+ "Build failed for dokploy",
+ template,
+ );
+ }
- if (discord) {
- const decorate = (decoration: string, text: string) =>
- `${discord.decoration ? decoration : ""} ${text}`.trim();
+ if (discord) {
+ const decorate = (decoration: string, text: string) =>
+ `${discord.decoration ? decoration : ""} ${text}`.trim();
- const limitCharacter = 800;
- const truncatedErrorMessage = errorMessage.substring(0, limitCharacter);
- await sendDiscordNotification(discord, {
- title: decorate(">", "`⚠️` Build Failed"),
- color: 0xed4245,
- fields: [
- {
- name: decorate("`🛠️`", "Project"),
- value: projectName,
- inline: true,
- },
- {
- name: decorate("`⚙️`", "Application"),
- value: applicationName,
- inline: true,
- },
- {
- name: decorate("`❔`", "Type"),
- value: applicationType,
- inline: true,
- },
- {
- name: decorate("`📅`", "Date"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`⌚`", "Time"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`❓`", "Type"),
- value: "Failed",
- inline: true,
- },
- {
- name: decorate("`⚠️`", "Error Message"),
- value: `\`\`\`${truncatedErrorMessage}\`\`\``,
- },
- {
- name: decorate("`🧷`", "Build Link"),
- value: `[Click here to access build link](${buildLink})`,
+ const limitCharacter = 800;
+ const truncatedErrorMessage = errorMessage.substring(0, limitCharacter);
+ await sendDiscordNotification(discord, {
+ title: decorate(">", "`⚠️` Build Failed"),
+ color: 0xed4245,
+ fields: [
+ {
+ name: decorate("`🛠️`", "Project"),
+ value: projectName,
+ inline: true,
+ },
+ {
+ name: decorate("`⚙️`", "Application"),
+ value: applicationName,
+ inline: true,
+ },
+ {
+ name: decorate("`❔`", "Type"),
+ value: applicationType,
+ inline: true,
+ },
+ {
+ name: decorate("`📅`", "Date"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`⌚`", "Time"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`❓`", "Type"),
+ value: "Failed",
+ inline: true,
+ },
+ {
+ name: decorate("`⚠️`", "Error Message"),
+ value: `\`\`\`${truncatedErrorMessage}\`\`\``,
+ },
+ {
+ name: decorate("`🧷`", "Build Link"),
+ value: `[Click here to access build link](${buildLink})`,
+ },
+ ],
+ timestamp: date.toISOString(),
+ footer: {
+ text: "Dokploy Build Notification",
},
- ],
- timestamp: date.toISOString(),
- footer: {
- text: "Dokploy Build Notification",
- },
- });
- }
+ });
+ }
- if (gotify) {
- const decorate = (decoration: string, text: string) =>
- `${gotify.decoration ? decoration : ""} ${text}\n`;
- await sendGotifyNotification(
- gotify,
- decorate("⚠️", "Build Failed"),
- `${decorate("🛠️", `Project: ${projectName}`)}` +
- `${decorate("⚙️", `Application: ${applicationName}`)}` +
- `${decorate("❔", `Type: ${applicationType}`)}` +
- `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
- `${decorate("⚠️", `Error:\n${errorMessage}`)}` +
- `${decorate("🔗", `Build details:\n${buildLink}`)}`,
- );
- }
+ if (gotify) {
+ const decorate = (decoration: string, text: string) =>
+ `${gotify.decoration ? decoration : ""} ${text}\n`;
+ await sendGotifyNotification(
+ gotify,
+ decorate("⚠️", "Build Failed"),
+ `${decorate("🛠️", `Project: ${projectName}`)}` +
+ `${decorate("⚙️", `Application: ${applicationName}`)}` +
+ `${decorate("❔", `Type: ${applicationType}`)}` +
+ `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
+ `${decorate("⚠️", `Error:\n${errorMessage}`)}` +
+ `${decorate("🔗", `Build details:\n${buildLink}`)}`,
+ );
+ }
- if (ntfy) {
- await sendNtfyNotification(
- ntfy,
- "Build Failed",
- "warning",
- `view, Build details, ${buildLink}, clear=true;`,
- `🛠️Project: ${projectName}\n` +
- `⚙️Application: ${applicationName}\n` +
- `❔Type: ${applicationType}\n` +
- `🕒Date: ${date.toLocaleString()}\n` +
- `⚠️Error:\n${errorMessage}`,
- );
- }
+ if (ntfy) {
+ await sendNtfyNotification(
+ ntfy,
+ "Build Failed",
+ "warning",
+ `view, Build details, ${buildLink}, clear=true;`,
+ `🛠️Project: ${projectName}\n` +
+ `⚙️Application: ${applicationName}\n` +
+ `❔Type: ${applicationType}\n` +
+ `🕒Date: ${date.toLocaleString()}\n` +
+ `⚠️Error:\n${errorMessage}`,
+ );
+ }
- if (telegram) {
- const inlineButton = [
- [
- {
- text: "Deployment Logs",
- url: buildLink,
- },
- ],
- ];
+ if (telegram) {
+ const inlineButton = [
+ [
+ {
+ text: "Deployment Logs",
+ url: buildLink,
+ },
+ ],
+ ];
- await sendTelegramNotification(
- telegram,
- `⚠️ Build Failed\n\nProject: ${projectName}\nApplication: ${applicationName}\nType: ${applicationType}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}\n\nError:\n${errorMessage}`,
- inlineButton,
- );
- }
+ await sendTelegramNotification(
+ telegram,
+ `⚠️ Build Failed\n\nProject: ${projectName}\nApplication: ${applicationName}\nType: ${applicationType}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}\n\nError:\n${errorMessage}`,
+ inlineButton,
+ );
+ }
- if (slack) {
- const { channel } = slack;
- await sendSlackNotification(slack, {
- channel: channel,
- attachments: [
- {
- color: "#FF0000",
- pretext: ":warning: *Build Failed*",
- fields: [
- {
- title: "Project",
- value: projectName,
- short: true,
- },
- {
- title: "Application",
- value: applicationName,
- short: true,
- },
- {
- title: "Type",
- value: applicationType,
- short: true,
- },
- {
- title: "Time",
- value: date.toLocaleString(),
- short: true,
- },
- {
- title: "Error",
- value: `\`\`\`${errorMessage}\`\`\``,
- short: false,
- },
- ],
- actions: [
- {
- type: "button",
- text: "View Build Details",
- url: buildLink,
- },
- ],
- },
- ],
- });
- }
+ if (slack) {
+ const { channel } = slack;
+ await sendSlackNotification(slack, {
+ channel: channel,
+ attachments: [
+ {
+ color: "#FF0000",
+ pretext: ":warning: *Build Failed*",
+ fields: [
+ {
+ title: "Project",
+ value: projectName,
+ short: true,
+ },
+ {
+ title: "Application",
+ value: applicationName,
+ short: true,
+ },
+ {
+ title: "Type",
+ value: applicationType,
+ short: true,
+ },
+ {
+ title: "Time",
+ value: date.toLocaleString(),
+ short: true,
+ },
+ {
+ title: "Error",
+ value: `\`\`\`${errorMessage}\`\`\``,
+ short: false,
+ },
+ ],
+ actions: [
+ {
+ type: "button",
+ text: "View Build Details",
+ url: buildLink,
+ },
+ ],
+ },
+ ],
+ });
+ }
- if (lark) {
- const limitCharacter = 800;
- const truncatedErrorMessage = errorMessage.substring(0, limitCharacter);
- await sendLarkNotification(lark, {
- msg_type: "interactive",
- card: {
- schema: "2.0",
- config: {
- update_multi: true,
- style: {
- text_size: {
- normal_v2: {
- default: "normal",
- pc: "normal",
- mobile: "heading",
+ if (lark) {
+ const limitCharacter = 800;
+ const truncatedErrorMessage = errorMessage.substring(0, limitCharacter);
+ await sendLarkNotification(lark, {
+ msg_type: "interactive",
+ card: {
+ schema: "2.0",
+ config: {
+ update_multi: true,
+ style: {
+ text_size: {
+ normal_v2: {
+ default: "normal",
+ pc: "normal",
+ mobile: "heading",
+ },
},
},
},
- },
- header: {
- title: {
- tag: "plain_text",
- content: "⚠️ Build Failed",
- },
- subtitle: {
- tag: "plain_text",
- content: "",
- },
- template: "red",
- padding: "12px 12px 12px 12px",
- },
- body: {
- direction: "vertical",
- padding: "12px 12px 12px 12px",
- elements: [
- {
- tag: "column_set",
- columns: [
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Project:**\n${projectName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Type:**\n${applicationType}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Error Message:**\n\`\`\`\n${truncatedErrorMessage}\n\`\`\``,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
- },
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Application:**\n${applicationName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Date:**\n${format(date, "PP pp")}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
- },
- ],
+ header: {
+ title: {
+ tag: "plain_text",
+ content: "⚠️ Build Failed",
+ },
+ subtitle: {
+ tag: "plain_text",
+ content: "",
},
- {
- tag: "button",
- text: {
- tag: "plain_text",
- content: "View Build Details",
+ template: "red",
+ padding: "12px 12px 12px 12px",
+ },
+ body: {
+ direction: "vertical",
+ padding: "12px 12px 12px 12px",
+ elements: [
+ {
+ tag: "column_set",
+ columns: [
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Project:**\n${projectName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Type:**\n${applicationType}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Error Message:**\n\`\`\`\n${truncatedErrorMessage}\n\`\`\``,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Application:**\n${applicationName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Date:**\n${format(date, "PP pp")}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ ],
},
- type: "danger",
- width: "default",
- size: "medium",
- behaviors: [
- {
- type: "open_url",
- default_url: buildLink,
- pc_url: "",
- ios_url: "",
- android_url: "",
+ {
+ tag: "button",
+ text: {
+ tag: "plain_text",
+ content: "View Build Details",
},
- ],
- margin: "0px 0px 0px 0px",
- },
- ],
+ type: "danger",
+ width: "default",
+ size: "medium",
+ behaviors: [
+ {
+ type: "open_url",
+ default_url: buildLink,
+ pc_url: "",
+ ios_url: "",
+ android_url: "",
+ },
+ ],
+ margin: "0px 0px 0px 0px",
+ },
+ ],
+ },
},
- },
- });
+ });
+ }
+ } catch (error) {
+ console.log(error);
}
}
};
diff --git a/packages/server/src/utils/notifications/build-success.ts b/packages/server/src/utils/notifications/build-success.ts
index 5b5d6f518a..232eb76c2a 100644
--- a/packages/server/src/utils/notifications/build-success.ts
+++ b/packages/server/src/utils/notifications/build-success.ts
@@ -8,8 +8,8 @@ import { and, eq } from "drizzle-orm";
import {
sendDiscordNotification,
sendEmailNotification,
- sendLarkNotification,
sendGotifyNotification,
+ sendLarkNotification,
sendNtfyNotification,
sendSlackNotification,
sendTelegramNotification,
@@ -55,288 +55,295 @@ export const sendBuildSuccessNotifications = async ({
for (const notification of notificationList) {
const { email, discord, telegram, slack, gotify, ntfy, lark } =
notification;
+ try {
+ if (email) {
+ const template = await renderAsync(
+ BuildSuccessEmail({
+ projectName,
+ applicationName,
+ applicationType,
+ buildLink,
+ date: date.toLocaleString(),
+ environmentName,
+ }),
+ ).catch();
+ await sendEmailNotification(
+ email,
+ "Build success for dokploy",
+ template,
+ );
+ }
- if (email) {
- const template = await renderAsync(
- BuildSuccessEmail({
- projectName,
- applicationName,
- applicationType,
- buildLink,
- date: date.toLocaleString(),
- environmentName,
- }),
- ).catch();
- await sendEmailNotification(email, "Build success for dokploy", template);
- }
-
- if (discord) {
- const decorate = (decoration: string, text: string) =>
- `${discord.decoration ? decoration : ""} ${text}`.trim();
+ if (discord) {
+ const decorate = (decoration: string, text: string) =>
+ `${discord.decoration ? decoration : ""} ${text}`.trim();
- await sendDiscordNotification(discord, {
- title: decorate(">", "`✅` Build Successes"),
- color: 0x57f287,
- fields: [
- {
- name: decorate("`🛠️`", "Project"),
- value: projectName,
- inline: true,
- },
- {
- name: decorate("`⚙️`", "Application"),
- value: applicationName,
- inline: true,
- },
- {
- name: decorate("`🌍`", "Environment"),
- value: environmentName,
- inline: true,
- },
- {
- name: decorate("`❔`", "Type"),
- value: applicationType,
- inline: true,
- },
- {
- name: decorate("`📅`", "Date"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`⌚`", "Time"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`❓`", "Type"),
- value: "Successful",
- inline: true,
- },
- {
- name: decorate("`🧷`", "Build Link"),
- value: `[Click here to access build link](${buildLink})`,
+ await sendDiscordNotification(discord, {
+ title: decorate(">", "`✅` Build Successes"),
+ color: 0x57f287,
+ fields: [
+ {
+ name: decorate("`🛠️`", "Project"),
+ value: projectName,
+ inline: true,
+ },
+ {
+ name: decorate("`⚙️`", "Application"),
+ value: applicationName,
+ inline: true,
+ },
+ {
+ name: decorate("`🌍`", "Environment"),
+ value: environmentName,
+ inline: true,
+ },
+ {
+ name: decorate("`❔`", "Type"),
+ value: applicationType,
+ inline: true,
+ },
+ {
+ name: decorate("`📅`", "Date"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`⌚`", "Time"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`❓`", "Type"),
+ value: "Successful",
+ inline: true,
+ },
+ {
+ name: decorate("`🧷`", "Build Link"),
+ value: `[Click here to access build link](${buildLink})`,
+ },
+ ],
+ timestamp: date.toISOString(),
+ footer: {
+ text: "Dokploy Build Notification",
},
- ],
- timestamp: date.toISOString(),
- footer: {
- text: "Dokploy Build Notification",
- },
- });
- }
-
- if (gotify) {
- const decorate = (decoration: string, text: string) =>
- `${gotify.decoration ? decoration : ""} ${text}\n`;
- await sendGotifyNotification(
- gotify,
- decorate("✅", "Build Success"),
- `${decorate("🛠️", `Project: ${projectName}`)}` +
- `${decorate("⚙️", `Application: ${applicationName}`)}` +
- `${decorate("🌍", `Environment: ${environmentName}`)}` +
- `${decorate("❔", `Type: ${applicationType}`)}` +
- `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
- `${decorate("🔗", `Build details:\n${buildLink}`)}`,
- );
- }
+ });
+ }
- if (ntfy) {
- await sendNtfyNotification(
- ntfy,
- "Build Success",
- "white_check_mark",
- `view, Build details, ${buildLink}, clear=true;`,
- `🛠Project: ${projectName}\n` +
- `⚙️Application: ${applicationName}\n` +
- `🌍Environment: ${environmentName}\n` +
- `❔Type: ${applicationType}\n` +
- `🕒Date: ${date.toLocaleString()}`,
- );
- }
+ if (gotify) {
+ const decorate = (decoration: string, text: string) =>
+ `${gotify.decoration ? decoration : ""} ${text}\n`;
+ await sendGotifyNotification(
+ gotify,
+ decorate("✅", "Build Success"),
+ `${decorate("🛠️", `Project: ${projectName}`)}` +
+ `${decorate("⚙️", `Application: ${applicationName}`)}` +
+ `${decorate("🌍", `Environment: ${environmentName}`)}` +
+ `${decorate("❔", `Type: ${applicationType}`)}` +
+ `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
+ `${decorate("🔗", `Build details:\n${buildLink}`)}`,
+ );
+ }
- if (telegram) {
- const chunkArray = (array: T[], chunkSize: number): T[][] =>
- Array.from({ length: Math.ceil(array.length / chunkSize) }, (_, i) =>
- array.slice(i * chunkSize, i * chunkSize + chunkSize),
+ if (ntfy) {
+ await sendNtfyNotification(
+ ntfy,
+ "Build Success",
+ "white_check_mark",
+ `view, Build details, ${buildLink}, clear=true;`,
+ `🛠Project: ${projectName}\n` +
+ `⚙️Application: ${applicationName}\n` +
+ `🌍Environment: ${environmentName}\n` +
+ `❔Type: ${applicationType}\n` +
+ `🕒Date: ${date.toLocaleString()}`,
);
+ }
- const inlineButton = [
- [
- {
- text: "Deployment Logs",
- url: buildLink,
- },
- ],
- ...chunkArray(domains, 2).map((chunk) =>
- chunk.map((data) => ({
- text: data.host,
- url: `${data.https ? "https" : "http"}://${data.host}`,
- })),
- ),
- ];
+ if (telegram) {
+ const chunkArray = (array: T[], chunkSize: number): T[][] =>
+ Array.from({ length: Math.ceil(array.length / chunkSize) }, (_, i) =>
+ array.slice(i * chunkSize, i * chunkSize + chunkSize),
+ );
- await sendTelegramNotification(
- telegram,
- `✅ Build Success\n\nProject: ${projectName}\nApplication: ${applicationName}\nEnvironment: ${environmentName}\nType: ${applicationType}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}`,
- inlineButton,
- );
- }
+ const inlineButton = [
+ [
+ {
+ text: "Deployment Logs",
+ url: buildLink,
+ },
+ ],
+ ...chunkArray(domains, 2).map((chunk) =>
+ chunk.map((data) => ({
+ text: data.host,
+ url: `${data.https ? "https" : "http"}://${data.host}`,
+ })),
+ ),
+ ];
- if (slack) {
- const { channel } = slack;
- await sendSlackNotification(slack, {
- channel: channel,
- attachments: [
- {
- color: "#00FF00",
- pretext: ":white_check_mark: *Build Success*",
- fields: [
- {
- title: "Project",
- value: projectName,
- short: true,
- },
- {
- title: "Application",
- value: applicationName,
- short: true,
- },
- {
- title: "Environment",
- value: environmentName,
- short: true,
- },
- {
- title: "Type",
- value: applicationType,
- short: true,
- },
- {
- title: "Time",
- value: date.toLocaleString(),
- short: true,
- },
- ],
- actions: [
- {
- type: "button",
- text: "View Build Details",
- url: buildLink,
- },
- ],
- },
- ],
- });
- }
+ await sendTelegramNotification(
+ telegram,
+ `✅ Build Success\n\nProject: ${projectName}\nApplication: ${applicationName}\nEnvironment: ${environmentName}\nType: ${applicationType}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}`,
+ inlineButton,
+ );
+ }
- if (lark) {
- await sendLarkNotification(lark, {
- msg_type: "interactive",
- card: {
- schema: "2.0",
- config: {
- update_multi: true,
- style: {
- text_size: {
- normal_v2: {
- default: "normal",
- pc: "normal",
- mobile: "heading",
+ if (slack) {
+ const { channel } = slack;
+ await sendSlackNotification(slack, {
+ channel: channel,
+ attachments: [
+ {
+ color: "#00FF00",
+ pretext: ":white_check_mark: *Build Success*",
+ fields: [
+ {
+ title: "Project",
+ value: projectName,
+ short: true,
},
- },
- },
- },
- header: {
- title: {
- tag: "plain_text",
- content: "✅ Build Success",
- },
- subtitle: {
- tag: "plain_text",
- content: "",
+ {
+ title: "Application",
+ value: applicationName,
+ short: true,
+ },
+ {
+ title: "Environment",
+ value: environmentName,
+ short: true,
+ },
+ {
+ title: "Type",
+ value: applicationType,
+ short: true,
+ },
+ {
+ title: "Time",
+ value: date.toLocaleString(),
+ short: true,
+ },
+ ],
+ actions: [
+ {
+ type: "button",
+ text: "View Build Details",
+ url: buildLink,
+ },
+ ],
},
- template: "green",
- padding: "12px 12px 12px 12px",
- },
- body: {
- direction: "vertical",
- padding: "12px 12px 12px 12px",
- elements: [
- {
- tag: "column_set",
- columns: [
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Project:**\n${projectName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Environment:**\n${environmentName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Type:**\n${applicationType}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
- },
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Application:**\n${applicationName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Date:**\n${format(date, "PP pp")}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
+ ],
+ });
+ }
+
+ if (lark) {
+ await sendLarkNotification(lark, {
+ msg_type: "interactive",
+ card: {
+ schema: "2.0",
+ config: {
+ update_multi: true,
+ style: {
+ text_size: {
+ normal_v2: {
+ default: "normal",
+ pc: "normal",
+ mobile: "heading",
},
- ],
+ },
},
- {
- tag: "button",
- text: {
- tag: "plain_text",
- content: "View Build Details",
+ },
+ header: {
+ title: {
+ tag: "plain_text",
+ content: "✅ Build Success",
+ },
+ subtitle: {
+ tag: "plain_text",
+ content: "",
+ },
+ template: "green",
+ padding: "12px 12px 12px 12px",
+ },
+ body: {
+ direction: "vertical",
+ padding: "12px 12px 12px 12px",
+ elements: [
+ {
+ tag: "column_set",
+ columns: [
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Project:**\n${projectName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Environment:**\n${environmentName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Type:**\n${applicationType}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Application:**\n${applicationName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Date:**\n${format(date, "PP pp")}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ ],
},
- type: "primary",
- width: "default",
- size: "medium",
- behaviors: [
- {
- type: "open_url",
- default_url: buildLink,
- pc_url: "",
- ios_url: "",
- android_url: "",
+ {
+ tag: "button",
+ text: {
+ tag: "plain_text",
+ content: "View Build Details",
},
- ],
- margin: "0px 0px 0px 0px",
- },
- ],
+ type: "primary",
+ width: "default",
+ size: "medium",
+ behaviors: [
+ {
+ type: "open_url",
+ default_url: buildLink,
+ pc_url: "",
+ ios_url: "",
+ android_url: "",
+ },
+ ],
+ margin: "0px 0px 0px 0px",
+ },
+ ],
+ },
},
- },
- });
+ });
+ }
+ } catch (error) {
+ console.log(error);
}
}
};
diff --git a/packages/server/src/utils/notifications/database-backup.ts b/packages/server/src/utils/notifications/database-backup.ts
index c5cb68dbc0..02141e3aea 100644
--- a/packages/server/src/utils/notifications/database-backup.ts
+++ b/packages/server/src/utils/notifications/database-backup.ts
@@ -7,8 +7,8 @@ import { and, eq } from "drizzle-orm";
import {
sendDiscordNotification,
sendEmailNotification,
- sendLarkNotification,
sendGotifyNotification,
+ sendLarkNotification,
sendNtfyNotification,
sendSlackNotification,
sendTelegramNotification,
@@ -52,309 +52,312 @@ export const sendDatabaseBackupNotifications = async ({
for (const notification of notificationList) {
const { email, discord, telegram, slack, gotify, ntfy, lark } =
notification;
+ try {
+ if (email) {
+ const template = await renderAsync(
+ DatabaseBackupEmail({
+ projectName,
+ applicationName,
+ databaseType,
+ type,
+ errorMessage,
+ date: date.toLocaleString(),
+ }),
+ ).catch();
+ await sendEmailNotification(
+ email,
+ "Database backup for dokploy",
+ template,
+ );
+ }
- if (email) {
- const template = await renderAsync(
- DatabaseBackupEmail({
- projectName,
- applicationName,
- databaseType,
- type,
- errorMessage,
- date: date.toLocaleString(),
- }),
- ).catch();
- await sendEmailNotification(
- email,
- "Database backup for dokploy",
- template,
- );
- }
-
- if (discord) {
- const decorate = (decoration: string, text: string) =>
- `${discord.decoration ? decoration : ""} ${text}`.trim();
+ if (discord) {
+ const decorate = (decoration: string, text: string) =>
+ `${discord.decoration ? decoration : ""} ${text}`.trim();
- await sendDiscordNotification(discord, {
- title:
- type === "success"
- ? decorate(">", "`✅` Database Backup Successful")
- : decorate(">", "`❌` Database Backup Failed"),
- color: type === "success" ? 0x57f287 : 0xed4245,
- fields: [
- {
- name: decorate("`🛠️`", "Project"),
- value: projectName,
- inline: true,
- },
- {
- name: decorate("`⚙️`", "Application"),
- value: applicationName,
- inline: true,
- },
- {
- name: decorate("`❔`", "Database"),
- value: databaseType,
- inline: true,
- },
- {
- name: decorate("`📂`", "Database Name"),
- value: databaseName,
- inline: true,
- },
- {
- name: decorate("`📅`", "Date"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`⌚`", "Time"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`❓`", "Type"),
- value: type
- .replace("error", "Failed")
- .replace("success", "Successful"),
- inline: true,
+ await sendDiscordNotification(discord, {
+ title:
+ type === "success"
+ ? decorate(">", "`✅` Database Backup Successful")
+ : decorate(">", "`❌` Database Backup Failed"),
+ color: type === "success" ? 0x57f287 : 0xed4245,
+ fields: [
+ {
+ name: decorate("`🛠️`", "Project"),
+ value: projectName,
+ inline: true,
+ },
+ {
+ name: decorate("`⚙️`", "Application"),
+ value: applicationName,
+ inline: true,
+ },
+ {
+ name: decorate("`❔`", "Database"),
+ value: databaseType,
+ inline: true,
+ },
+ {
+ name: decorate("`📂`", "Database Name"),
+ value: databaseName,
+ inline: true,
+ },
+ {
+ name: decorate("`📅`", "Date"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`⌚`", "Time"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`❓`", "Type"),
+ value: type
+ .replace("error", "Failed")
+ .replace("success", "Successful"),
+ inline: true,
+ },
+ ...(type === "error" && errorMessage
+ ? [
+ {
+ name: decorate("`⚠️`", "Error Message"),
+ value: `\`\`\`${errorMessage}\`\`\``,
+ },
+ ]
+ : []),
+ ],
+ timestamp: date.toISOString(),
+ footer: {
+ text: "Dokploy Database Backup Notification",
},
- ...(type === "error" && errorMessage
- ? [
- {
- name: decorate("`⚠️`", "Error Message"),
- value: `\`\`\`${errorMessage}\`\`\``,
- },
- ]
- : []),
- ],
- timestamp: date.toISOString(),
- footer: {
- text: "Dokploy Database Backup Notification",
- },
- });
- }
+ });
+ }
+
+ if (gotify) {
+ const decorate = (decoration: string, text: string) =>
+ `${gotify.decoration ? decoration : ""} ${text}\n`;
- if (gotify) {
- const decorate = (decoration: string, text: string) =>
- `${gotify.decoration ? decoration : ""} ${text}\n`;
+ await sendGotifyNotification(
+ gotify,
+ decorate(
+ type === "success" ? "✅" : "❌",
+ `Database Backup ${type === "success" ? "Successful" : "Failed"}`,
+ ),
+ `${decorate("🛠️", `Project: ${projectName}`)}` +
+ `${decorate("⚙️", `Application: ${applicationName}`)}` +
+ `${decorate("❔", `Type: ${databaseType}`)}` +
+ `${decorate("📂", `Database Name: ${databaseName}`)}` +
+ `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
+ `${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`,
+ );
+ }
- await sendGotifyNotification(
- gotify,
- decorate(
- type === "success" ? "✅" : "❌",
+ if (ntfy) {
+ await sendNtfyNotification(
+ ntfy,
`Database Backup ${type === "success" ? "Successful" : "Failed"}`,
- ),
- `${decorate("🛠️", `Project: ${projectName}`)}` +
- `${decorate("⚙️", `Application: ${applicationName}`)}` +
- `${decorate("❔", `Type: ${databaseType}`)}` +
- `${decorate("📂", `Database Name: ${databaseName}`)}` +
- `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
- `${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`,
- );
- }
+ `${type === "success" ? "white_check_mark" : "x"}`,
+ "",
+ `🛠Project: ${projectName}\n` +
+ `⚙️Application: ${applicationName}\n` +
+ `❔Type: ${databaseType}\n` +
+ `📂Database Name: ${databaseName}` +
+ `🕒Date: ${date.toLocaleString()}\n` +
+ `${type === "error" && errorMessage ? `❌Error:\n${errorMessage}` : ""}`,
+ );
+ }
- if (ntfy) {
- await sendNtfyNotification(
- ntfy,
- `Database Backup ${type === "success" ? "Successful" : "Failed"}`,
- `${type === "success" ? "white_check_mark" : "x"}`,
- "",
- `🛠Project: ${projectName}\n` +
- `⚙️Application: ${applicationName}\n` +
- `❔Type: ${databaseType}\n` +
- `📂Database Name: ${databaseName}` +
- `🕒Date: ${date.toLocaleString()}\n` +
- `${type === "error" && errorMessage ? `❌Error:\n${errorMessage}` : ""}`,
- );
- }
+ if (telegram) {
+ const isError = type === "error" && errorMessage;
- if (telegram) {
- const isError = type === "error" && errorMessage;
+ const statusEmoji = type === "success" ? "✅" : "❌";
+ const typeStatus = type === "success" ? "Successful" : "Failed";
+ const errorMsg = isError
+ ? `\n\nError:\n${errorMessage}`
+ : "";
- const statusEmoji = type === "success" ? "✅" : "❌";
- const typeStatus = type === "success" ? "Successful" : "Failed";
- const errorMsg = isError
- ? `\n\nError:\n${errorMessage}`
- : "";
+ const messageText = `${statusEmoji} Database Backup ${typeStatus}\n\nProject: ${projectName}\nApplication: ${applicationName}\nType: ${databaseType}\nDatabase Name: ${databaseName}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}${isError ? errorMsg : ""}`;
- const messageText = `${statusEmoji} Database Backup ${typeStatus}\n\nProject: ${projectName}\nApplication: ${applicationName}\nType: ${databaseType}\nDatabase Name: ${databaseName}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}${isError ? errorMsg : ""}`;
+ await sendTelegramNotification(telegram, messageText);
+ }
- await sendTelegramNotification(telegram, messageText);
- }
-
- if (slack) {
- const { channel } = slack;
- await sendSlackNotification(slack, {
- channel: channel,
- attachments: [
- {
- color: type === "success" ? "#00FF00" : "#FF0000",
- pretext:
- type === "success"
- ? ":white_check_mark: *Database Backup Successful*"
- : ":x: *Database Backup Failed*",
- fields: [
- ...(type === "error" && errorMessage
- ? [
- {
- title: "Error Message",
- value: errorMessage,
- short: false,
- },
- ]
- : []),
- {
- title: "Project",
- value: projectName,
- short: true,
- },
- {
- title: "Application",
- value: applicationName,
- short: true,
- },
- {
- title: "Type",
- value: databaseType,
- short: true,
- },
- {
- title: "Database Name",
- value: databaseName,
- },
- {
- title: "Time",
- value: date.toLocaleString(),
- short: true,
- },
- {
- title: "Type",
- value: type,
- },
- {
- title: "Status",
- value: type === "success" ? "Successful" : "Failed",
- },
- ],
- },
- ],
- });
- }
+ if (slack) {
+ const { channel } = slack;
+ await sendSlackNotification(slack, {
+ channel: channel,
+ attachments: [
+ {
+ color: type === "success" ? "#00FF00" : "#FF0000",
+ pretext:
+ type === "success"
+ ? ":white_check_mark: *Database Backup Successful*"
+ : ":x: *Database Backup Failed*",
+ fields: [
+ ...(type === "error" && errorMessage
+ ? [
+ {
+ title: "Error Message",
+ value: errorMessage,
+ short: false,
+ },
+ ]
+ : []),
+ {
+ title: "Project",
+ value: projectName,
+ short: true,
+ },
+ {
+ title: "Application",
+ value: applicationName,
+ short: true,
+ },
+ {
+ title: "Type",
+ value: databaseType,
+ short: true,
+ },
+ {
+ title: "Database Name",
+ value: databaseName,
+ },
+ {
+ title: "Time",
+ value: date.toLocaleString(),
+ short: true,
+ },
+ {
+ title: "Type",
+ value: type,
+ },
+ {
+ title: "Status",
+ value: type === "success" ? "Successful" : "Failed",
+ },
+ ],
+ },
+ ],
+ });
+ }
- if (lark) {
- const limitCharacter = 800;
- const truncatedErrorMessage =
- errorMessage && errorMessage.length > limitCharacter
- ? errorMessage.substring(0, limitCharacter)
- : errorMessage;
+ if (lark) {
+ const limitCharacter = 800;
+ const truncatedErrorMessage =
+ errorMessage && errorMessage.length > limitCharacter
+ ? errorMessage.substring(0, limitCharacter)
+ : errorMessage;
- await sendLarkNotification(lark, {
- msg_type: "interactive",
- card: {
- schema: "2.0",
- config: {
- update_multi: true,
- style: {
- text_size: {
- normal_v2: {
- default: "normal",
- pc: "normal",
- mobile: "heading",
+ await sendLarkNotification(lark, {
+ msg_type: "interactive",
+ card: {
+ schema: "2.0",
+ config: {
+ update_multi: true,
+ style: {
+ text_size: {
+ normal_v2: {
+ default: "normal",
+ pc: "normal",
+ mobile: "heading",
+ },
},
},
},
- },
- header: {
- title: {
- tag: "plain_text",
- content:
- type === "success"
- ? "✅ Database Backup Successful"
- : "❌ Database Backup Failed",
- },
- subtitle: {
- tag: "plain_text",
- content: "",
+ header: {
+ title: {
+ tag: "plain_text",
+ content:
+ type === "success"
+ ? "✅ Database Backup Successful"
+ : "❌ Database Backup Failed",
+ },
+ subtitle: {
+ tag: "plain_text",
+ content: "",
+ },
+ template: type === "success" ? "green" : "red",
+ padding: "12px 12px 12px 12px",
},
- template: type === "success" ? "green" : "red",
- padding: "12px 12px 12px 12px",
- },
- body: {
- direction: "vertical",
- padding: "12px 12px 12px 12px",
- elements: [
- {
- tag: "column_set",
- columns: [
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Project:**\n${projectName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Database Type:**\n${databaseType}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Status:**\n${type === "success" ? "Successful" : "Failed"}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
- },
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Application:**\n${applicationName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Database Name:**\n${databaseName}`,
- text_align: "left",
- text_size: "normal_v2",
- },
+ body: {
+ direction: "vertical",
+ padding: "12px 12px 12px 12px",
+ elements: [
+ {
+ tag: "column_set",
+ columns: [
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Project:**\n${projectName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Database Type:**\n${databaseType}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Status:**\n${type === "success" ? "Successful" : "Failed"}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Application:**\n${applicationName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Database Name:**\n${databaseName}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Date:**\n${format(date, "PP pp")}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ ],
+ },
+ ...(type === "error" && truncatedErrorMessage
+ ? [
{
tag: "markdown",
- content: `**Date:**\n${format(date, "PP pp")}`,
+ content: `**Error Message:**\n\`\`\`\n${truncatedErrorMessage}\n\`\`\``,
text_align: "left",
text_size: "normal_v2",
},
- ],
- vertical_align: "top",
- weight: 1,
- },
- ],
- },
- ...(type === "error" && truncatedErrorMessage
- ? [
- {
- tag: "markdown",
- content: `**Error Message:**\n\`\`\`\n${truncatedErrorMessage}\n\`\`\``,
- text_align: "left",
- text_size: "normal_v2",
- },
- ]
- : []),
- ],
+ ]
+ : []),
+ ],
+ },
},
- },
- });
+ });
+ }
+ } catch (error) {
+ console.log(error);
}
}
};
diff --git a/packages/server/src/utils/notifications/docker-cleanup.ts b/packages/server/src/utils/notifications/docker-cleanup.ts
index 062da9d497..f7947c8a01 100644
--- a/packages/server/src/utils/notifications/docker-cleanup.ts
+++ b/packages/server/src/utils/notifications/docker-cleanup.ts
@@ -7,8 +7,8 @@ import { and, eq } from "drizzle-orm";
import {
sendDiscordNotification,
sendEmailNotification,
- sendLarkNotification,
sendGotifyNotification,
+ sendLarkNotification,
sendNtfyNotification,
sendSlackNotification,
sendTelegramNotification,
@@ -39,182 +39,185 @@ export const sendDockerCleanupNotifications = async (
for (const notification of notificationList) {
const { email, discord, telegram, slack, gotify, ntfy, lark } =
notification;
+ try {
+ if (email) {
+ const template = await renderAsync(
+ DockerCleanupEmail({ message, date: date.toLocaleString() }),
+ ).catch();
- if (email) {
- const template = await renderAsync(
- DockerCleanupEmail({ message, date: date.toLocaleString() }),
- ).catch();
-
- await sendEmailNotification(
- email,
- "Docker cleanup for dokploy",
- template,
- );
- }
+ await sendEmailNotification(
+ email,
+ "Docker cleanup for dokploy",
+ template,
+ );
+ }
- if (discord) {
- const decorate = (decoration: string, text: string) =>
- `${discord.decoration ? decoration : ""} ${text}`.trim();
+ if (discord) {
+ const decorate = (decoration: string, text: string) =>
+ `${discord.decoration ? decoration : ""} ${text}`.trim();
- await sendDiscordNotification(discord, {
- title: decorate(">", "`✅` Docker Cleanup"),
- color: 0x57f287,
- fields: [
- {
- name: decorate("`📅`", "Date"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`⌚`", "Time"),
- value: ``,
- inline: true,
- },
- {
- name: decorate("`❓`", "Type"),
- value: "Successful",
- inline: true,
- },
- {
- name: decorate("`📜`", "Message"),
- value: `\`\`\`${message}\`\`\``,
+ await sendDiscordNotification(discord, {
+ title: decorate(">", "`✅` Docker Cleanup"),
+ color: 0x57f287,
+ fields: [
+ {
+ name: decorate("`📅`", "Date"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`⌚`", "Time"),
+ value: ``,
+ inline: true,
+ },
+ {
+ name: decorate("`❓`", "Type"),
+ value: "Successful",
+ inline: true,
+ },
+ {
+ name: decorate("`📜`", "Message"),
+ value: `\`\`\`${message}\`\`\``,
+ },
+ ],
+ timestamp: date.toISOString(),
+ footer: {
+ text: "Dokploy Docker Cleanup Notification",
},
- ],
- timestamp: date.toISOString(),
- footer: {
- text: "Dokploy Docker Cleanup Notification",
- },
- });
- }
+ });
+ }
- if (gotify) {
- const decorate = (decoration: string, text: string) =>
- `${gotify.decoration ? decoration : ""} ${text}\n`;
- await sendGotifyNotification(
- gotify,
- decorate("✅", "Docker Cleanup"),
- `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
- `${decorate("📜", `Message:\n${message}`)}`,
- );
- }
+ if (gotify) {
+ const decorate = (decoration: string, text: string) =>
+ `${gotify.decoration ? decoration : ""} ${text}\n`;
+ await sendGotifyNotification(
+ gotify,
+ decorate("✅", "Docker Cleanup"),
+ `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
+ `${decorate("📜", `Message:\n${message}`)}`,
+ );
+ }
- if (ntfy) {
- await sendNtfyNotification(
- ntfy,
- "Docker Cleanup",
- "white_check_mark",
- "",
- `🕒Date: ${date.toLocaleString()}\n` + `📜Message:\n${message}`,
- );
- }
+ if (ntfy) {
+ await sendNtfyNotification(
+ ntfy,
+ "Docker Cleanup",
+ "white_check_mark",
+ "",
+ `🕒Date: ${date.toLocaleString()}\n` + `📜Message:\n${message}`,
+ );
+ }
- if (telegram) {
- await sendTelegramNotification(
- telegram,
- `✅ Docker Cleanup\n\nMessage: ${message}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}`,
- );
- }
+ if (telegram) {
+ await sendTelegramNotification(
+ telegram,
+ `✅ Docker Cleanup\n\nMessage: ${message}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}`,
+ );
+ }
- if (slack) {
- const { channel } = slack;
- await sendSlackNotification(slack, {
- channel: channel,
- attachments: [
- {
- color: "#00FF00",
- pretext: ":white_check_mark: *Docker Cleanup*",
- fields: [
- {
- title: "Message",
- value: message,
- },
- {
- title: "Time",
- value: date.toLocaleString(),
- short: true,
- },
- ],
- },
- ],
- });
- }
+ if (slack) {
+ const { channel } = slack;
+ await sendSlackNotification(slack, {
+ channel: channel,
+ attachments: [
+ {
+ color: "#00FF00",
+ pretext: ":white_check_mark: *Docker Cleanup*",
+ fields: [
+ {
+ title: "Message",
+ value: message,
+ },
+ {
+ title: "Time",
+ value: date.toLocaleString(),
+ short: true,
+ },
+ ],
+ },
+ ],
+ });
+ }
- if (lark) {
- await sendLarkNotification(lark, {
- msg_type: "interactive",
- card: {
- schema: "2.0",
- config: {
- update_multi: true,
- style: {
- text_size: {
- normal_v2: {
- default: "normal",
- pc: "normal",
- mobile: "heading",
+ if (lark) {
+ await sendLarkNotification(lark, {
+ msg_type: "interactive",
+ card: {
+ schema: "2.0",
+ config: {
+ update_multi: true,
+ style: {
+ text_size: {
+ normal_v2: {
+ default: "normal",
+ pc: "normal",
+ mobile: "heading",
+ },
},
},
},
- },
- header: {
- title: {
- tag: "plain_text",
- content: "✅ Docker Cleanup",
+ header: {
+ title: {
+ tag: "plain_text",
+ content: "✅ Docker Cleanup",
+ },
+ subtitle: {
+ tag: "plain_text",
+ content: "",
+ },
+ template: "green",
+ padding: "12px 12px 12px 12px",
},
- subtitle: {
- tag: "plain_text",
- content: "",
+ body: {
+ direction: "vertical",
+ padding: "12px 12px 12px 12px",
+ elements: [
+ {
+ tag: "column_set",
+ columns: [
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: "**Status:**\nSuccessful",
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ {
+ tag: "markdown",
+ content: `**Cleanup Details:**\n${message}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ {
+ tag: "column",
+ width: "weighted",
+ elements: [
+ {
+ tag: "markdown",
+ content: `**Date:**\n${format(date, "PP pp")}`,
+ text_align: "left",
+ text_size: "normal_v2",
+ },
+ ],
+ vertical_align: "top",
+ weight: 1,
+ },
+ ],
+ },
+ ],
},
- template: "green",
- padding: "12px 12px 12px 12px",
- },
- body: {
- direction: "vertical",
- padding: "12px 12px 12px 12px",
- elements: [
- {
- tag: "column_set",
- columns: [
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Status:**\nSuccessful`,
- text_align: "left",
- text_size: "normal_v2",
- },
- {
- tag: "markdown",
- content: `**Cleanup Details:**\n${message}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
- },
- {
- tag: "column",
- width: "weighted",
- elements: [
- {
- tag: "markdown",
- content: `**Date:**\n${format(date, "PP pp")}`,
- text_align: "left",
- text_size: "normal_v2",
- },
- ],
- vertical_align: "top",
- weight: 1,
- },
- ],
- },
- ],
},
- },
- });
+ });
+ }
+ } catch (error) {
+ console.log(error);
}
}
};
diff --git a/packages/server/src/utils/notifications/dokploy-restart.ts b/packages/server/src/utils/notifications/dokploy-restart.ts
index 2582c92d14..093e14010d 100644
--- a/packages/server/src/utils/notifications/dokploy-restart.ts
+++ b/packages/server/src/utils/notifications/dokploy-restart.ts
@@ -7,8 +7,8 @@ import { eq } from "drizzle-orm";
import {
sendDiscordNotification,
sendEmailNotification,
- sendLarkNotification,
sendGotifyNotification,
+ sendLarkNotification,
sendNtfyNotification,
sendSlackNotification,
sendTelegramNotification,
@@ -34,18 +34,23 @@ export const sendDokployRestartNotifications = async () => {
const { email, discord, telegram, slack, gotify, ntfy, lark } =
notification;
- if (email) {
- const template = await renderAsync(
- DokployRestartEmail({ date: date.toLocaleString() }),
- ).catch();
- await sendEmailNotification(email, "Dokploy Server Restarted", template);
- }
+ try {
+ if (email) {
+ const template = await renderAsync(
+ DokployRestartEmail({ date: date.toLocaleString() }),
+ ).catch();
+
+ await sendEmailNotification(
+ email,
+ "Dokploy Server Restarted",
+ template,
+ );
+ }
- if (discord) {
- const decorate = (decoration: string, text: string) =>
- `${discord.decoration ? decoration : ""} ${text}`.trim();
+ if (discord) {
+ const decorate = (decoration: string, text: string) =>
+ `${discord.decoration ? decoration : ""} ${text}`.trim();
- try {
await sendDiscordNotification(discord, {
title: decorate(">", "`✅` Dokploy Server Restarted"),
color: 0x57f287,
@@ -71,27 +76,19 @@ export const sendDokployRestartNotifications = async () => {
text: "Dokploy Restart Notification",
},
});
- } catch (error) {
- console.log(error);
}
- }
- if (gotify) {
- const decorate = (decoration: string, text: string) =>
- `${gotify.decoration ? decoration : ""} ${text}\n`;
- try {
+ if (gotify) {
+ const decorate = (decoration: string, text: string) =>
+ `${gotify.decoration ? decoration : ""} ${text}\n`;
await sendGotifyNotification(
gotify,
decorate("✅", "Dokploy Server Restarted"),
`${decorate("🕒", `Date: ${date.toLocaleString()}`)}`,
);
- } catch (error) {
- console.log(error);
}
- }
- if (ntfy) {
- try {
+ if (ntfy) {
await sendNtfyNotification(
ntfy,
"Dokploy Server Restarted",
@@ -99,25 +96,17 @@ export const sendDokployRestartNotifications = async () => {
"",
`🕒Date: ${date.toLocaleString()}`,
);
- } catch (error) {
- console.log(error);
}
- }
- if (telegram) {
- try {
+ if (telegram) {
await sendTelegramNotification(
telegram,
`✅ Dokploy Server Restarted\n\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}`,
);
- } catch (error) {
- console.log(error);
}
- }
- if (slack) {
- const { channel } = slack;
- try {
+ if (slack) {
+ const { channel } = slack;
await sendSlackNotification(slack, {
channel: channel,
attachments: [
@@ -134,13 +123,9 @@ export const sendDokployRestartNotifications = async () => {
},
],
});
- } catch (error) {
- console.log(error);
}
- }
- if (lark) {
- try {
+ if (lark) {
await sendLarkNotification(lark, {
msg_type: "interactive",
card: {
@@ -182,7 +167,7 @@ export const sendDokployRestartNotifications = async () => {
elements: [
{
tag: "markdown",
- content: `**Status:**\nSuccessful`,
+ content: "**Status:**\nSuccessful",
text_align: "left",
text_size: "normal_v2",
},
@@ -210,9 +195,9 @@ export const sendDokployRestartNotifications = async () => {
},
},
});
- } catch (error) {
- console.log(error);
}
+ } catch (error) {
+ console.log(error);
}
}
};
diff --git a/packages/server/src/utils/notifications/utils.ts b/packages/server/src/utils/notifications/utils.ts
index a56a709186..539376ac51 100644
--- a/packages/server/src/utils/notifications/utils.ts
+++ b/packages/server/src/utils/notifications/utils.ts
@@ -1,8 +1,8 @@
import type {
discord,
email,
- lark,
gotify,
+ lark,
ntfy,
slack,
telegram,
@@ -38,6 +38,9 @@ export const sendEmailNotification = async (
});
} catch (err) {
console.log(err);
+ throw new Error(
+ `Failed to send email notification ${err instanceof Error ? err.message : "Unknown error"}`,
+ );
}
};
@@ -45,15 +48,23 @@ export const sendDiscordNotification = async (
connection: typeof discord.$inferInsert,
embed: any,
) => {
- // try {
- await fetch(connection.webhookUrl, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ embeds: [embed] }),
- });
- // } catch (err) {
- // console.log(err);
- // }
+ try {
+ const response = await fetch(connection.webhookUrl, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ embeds: [embed] }),
+ });
+ if (!response.ok) {
+ throw new Error(
+ `Failed to send discord notification ${response.statusText}`,
+ );
+ }
+ } catch (err) {
+ console.log("error", err);
+ throw new Error(
+ `Failed to send discord notification ${err instanceof Error ? err.message : "Unknown error"}`,
+ );
+ }
};
export const sendTelegramNotification = async (
@@ -90,13 +101,21 @@ export const sendSlackNotification = async (
message: any,
) => {
try {
- await fetch(connection.webhookUrl, {
+ const response = await fetch(connection.webhookUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(message),
});
+ if (!response.ok) {
+ throw new Error(
+ `Failed to send slack notification ${response.statusText}`,
+ );
+ }
} catch (err) {
- console.log(err);
+ console.log("error", err);
+ throw new Error(
+ `Failed to send slack notification ${err instanceof Error ? err.message : "Unknown error"}`,
+ );
}
};
diff --git a/packages/server/src/utils/process/ExecError.ts b/packages/server/src/utils/process/ExecError.ts
new file mode 100644
index 0000000000..773968b5cf
--- /dev/null
+++ b/packages/server/src/utils/process/ExecError.ts
@@ -0,0 +1,55 @@
+export interface ExecErrorDetails {
+ command: string;
+ stdout?: string;
+ stderr?: string;
+ exitCode?: number;
+ originalError?: Error;
+ serverId?: string | null;
+}
+
+export class ExecError extends Error {
+ public readonly command: string;
+ public readonly stdout?: string;
+ public readonly stderr?: string;
+ public readonly exitCode?: number;
+ public readonly originalError?: Error;
+ public readonly serverId?: string | null;
+
+ constructor(message: string, details: ExecErrorDetails) {
+ super(message);
+ this.name = "ExecError";
+ this.command = details.command;
+ this.stdout = details.stdout;
+ this.stderr = details.stderr;
+ this.exitCode = details.exitCode;
+ this.originalError = details.originalError;
+ this.serverId = details.serverId;
+
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, ExecError);
+ }
+ }
+
+ /**
+ * Get a formatted error message with all details
+ */
+ getDetailedMessage(): string {
+ const parts = [
+ `Command: ${this.command}`,
+ this.exitCode !== undefined ? `Exit Code: ${this.exitCode}` : null,
+ this.serverId ? `Server ID: ${this.serverId}` : "Location: Local",
+ this.stderr ? `Stderr: ${this.stderr}` : null,
+ this.stdout ? `Stdout: ${this.stdout}` : null,
+ ].filter(Boolean);
+
+ return `${this.message}\n${parts.join("\n")}`;
+ }
+
+ /**
+ * Check if this error is from a remote execution
+ */
+ isRemote(): boolean {
+ return !!this.serverId;
+ }
+}
diff --git a/packages/server/src/utils/process/execAsync.ts b/packages/server/src/utils/process/execAsync.ts
index 13b06c6c4a..cd0249000e 100644
--- a/packages/server/src/utils/process/execAsync.ts
+++ b/packages/server/src/utils/process/execAsync.ts
@@ -2,8 +2,43 @@ import { exec, execFile } from "node:child_process";
import util from "node:util";
import { findServerById } from "@dokploy/server/services/server";
import { Client } from "ssh2";
+import { ExecError } from "./ExecError";
-export const execAsync = util.promisify(exec);
+// Re-export ExecError for easier imports
+export { ExecError } from "./ExecError";
+
+const execAsyncBase = util.promisify(exec);
+
+export const execAsync = async (
+ command: string,
+ options?: { cwd?: string; env?: NodeJS.ProcessEnv; shell?: string },
+): Promise<{ stdout: string; stderr: string }> => {
+ try {
+ const result = await execAsyncBase(command, options);
+ return {
+ stdout: result.stdout.toString(),
+ stderr: result.stderr.toString(),
+ };
+ } catch (error) {
+ if (error instanceof Error) {
+ // @ts-ignore - exec error has these properties
+ const exitCode = error.code;
+ // @ts-ignore
+ const stdout = error.stdout?.toString() || "";
+ // @ts-ignore
+ const stderr = error.stderr?.toString() || "";
+
+ throw new ExecError(`Command execution failed: ${error.message}`, {
+ command,
+ stdout,
+ stderr,
+ exitCode,
+ originalError: error,
+ });
+ }
+ throw error;
+ }
+};
interface ExecOptions {
cwd?: string;
@@ -21,7 +56,16 @@ export const execAsyncStream = (
const childProcess = exec(command, options, (error) => {
if (error) {
- reject(error);
+ reject(
+ new ExecError(`Command execution failed: ${error.message}`, {
+ command,
+ stdout: stdoutComplete,
+ stderr: stderrComplete,
+ // @ts-ignore
+ exitCode: error.code,
+ originalError: error,
+ }),
+ );
return;
}
resolve({ stdout: stdoutComplete, stderr: stderrComplete });
@@ -45,7 +89,14 @@ export const execAsyncStream = (
childProcess.on("error", (error) => {
console.log(error);
- reject(error);
+ reject(
+ new ExecError(`Command execution error: ${error.message}`, {
+ command,
+ stdout: stdoutComplete,
+ stderr: stderrComplete,
+ originalError: error,
+ }),
+ );
});
});
};
@@ -108,7 +159,14 @@ export const execAsyncRemote = async (
conn.exec(command, (err, stream) => {
if (err) {
onData?.(err.message);
- throw err;
+ reject(
+ new ExecError(`Remote command execution failed: ${err.message}`, {
+ command,
+ serverId,
+ originalError: err,
+ }),
+ );
+ return;
}
stream
.on("close", (code: number, _signal: string) => {
@@ -116,7 +174,18 @@ export const execAsyncRemote = async (
if (code === 0) {
resolve({ stdout, stderr });
} else {
- reject(new Error(`Error occurred ❌: ${stderr}`));
+ reject(
+ new ExecError(
+ `Remote command failed with exit code ${code}`,
+ {
+ command,
+ stdout,
+ stderr,
+ exitCode: code,
+ serverId,
+ },
+ ),
+ );
}
})
.on("data", (data: string) => {
@@ -132,17 +201,25 @@ export const execAsyncRemote = async (
.on("error", (err) => {
conn.end();
if (err.level === "client-authentication") {
- onData?.(
- `Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`,
- );
+ const errorMsg = `Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`;
+ onData?.(errorMsg);
reject(
- new Error(
- `Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`,
- ),
+ new ExecError(errorMsg, {
+ command,
+ serverId,
+ originalError: err,
+ }),
);
} else {
- onData?.(`SSH connection error: ${err.message}`);
- reject(new Error(`SSH connection error: ${err.message}`));
+ const errorMsg = `SSH connection error: ${err.message}`;
+ onData?.(errorMsg);
+ reject(
+ new ExecError(errorMsg, {
+ command,
+ serverId,
+ originalError: err,
+ }),
+ );
}
})
.connect({
diff --git a/packages/server/src/utils/providers/github.ts b/packages/server/src/utils/providers/github.ts
index c0f1b651a6..5b7763df72 100644
--- a/packages/server/src/utils/providers/github.ts
+++ b/packages/server/src/utils/providers/github.ts
@@ -159,7 +159,6 @@ export const cloneGithubRepository = async ({
const octokit = authGithub(githubProvider);
const token = await getGithubToken(octokit);
const repoclone = `github.com/${owner}/${repository}.git`;
- // await recreateDirectory(outputPath);
command += `rm -rf ${outputPath};`;
command += `mkdir -p ${outputPath};`;
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
diff --git a/packages/server/src/utils/providers/gitlab.ts b/packages/server/src/utils/providers/gitlab.ts
index a3106b8c02..3343c9bb66 100644
--- a/packages/server/src/utils/providers/gitlab.ts
+++ b/packages/server/src/utils/providers/gitlab.ts
@@ -290,7 +290,7 @@ export const validateGitlabProvider = async (gitlabProvider: Gitlab) => {
while (true) {
const response = await fetch(
- `${gitlabProvider.gitlabUrl}/api/v4/projects?membership=true&owned=true&page=${page}&per_page=${perPage}`,
+ `${gitlabProvider.gitlabUrl}/api/v4/projects?membership=true&page=${page}&per_page=${perPage}`,
{
headers: {
Authorization: `Bearer ${gitlabProvider.accessToken}`,