diff --git a/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx b/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx
index bcf0ccbd..227bca55 100644
--- a/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx
+++ b/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx
@@ -144,38 +144,6 @@ export const ShowResources = ({ id, type }: Props) => {
className="grid w-full gap-8 "
>
-
(
-
-
-
Memory Reservation
-
-
-
-
-
-
-
- Memory soft limit in bytes. Example: 256MB =
- 268435456 bytes
-
-
-
-
-
-
-
-
-
-
- )}
- />
-
{
);
}}
/>
+ (
+
+
+
Memory Reservation
+
+
+
+
+
+
+
+ Memory soft limit in bytes. Example: 256MB =
+ 268435456 bytes
+
+
+
+
+
+
+
+
+
+
+ )}
+ />
{
Volumes
- If you want to persist data in this postgres database use the
- following config to setup the volumes
+ If you want to persist data in this service use the following config
+ to setup the volumes
diff --git a/apps/dokploy/components/dashboard/application/domains/show-domains.tsx b/apps/dokploy/components/dashboard/application/domains/show-domains.tsx
index 0b775c22..21b7a9f5 100644
--- a/apps/dokploy/components/dashboard/application/domains/show-domains.tsx
+++ b/apps/dokploy/components/dashboard/application/domains/show-domains.tsx
@@ -98,8 +98,12 @@ export const ShowDomains = ({ applicationId }: Props) => {
applicationId={applicationId}
domainId={item.domainId}
>
-
-
+
+
{
{repositories?.map((repo) => (
{
form.setValue("repository", {
@@ -245,7 +245,12 @@ export const SaveBitbucketProvider = ({ applicationId }: Props) => {
form.setValue("branch", "");
}}
>
- {repo.name}
+
+ {repo.name}
+
+ {repo.owner.username}
+
+
{
{repositories?.map((repo) => (
{
form.setValue("repository", {
@@ -236,7 +236,12 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
form.setValue("branch", "");
}}
>
- {repo.name}
+
+ {repo.name}
+
+ {repo.owner.login}
+
+
{
{repositories?.map((repo) => {
return (
{
form.setValue("repository", {
@@ -260,7 +260,12 @@ export const SaveGitlabProvider = ({ applicationId }: Props) => {
form.setValue("branch", "");
}}
>
- {repo.name}
+
+ {repo.name}
+
+ {repo.owner.username}
+
+
;
interface Props {
- composeId: string;
+ id: string;
+ type: ServiceType | "application";
}
-export const DeleteCompose = ({ composeId }: Props) => {
+export const DeleteService = ({ id, type }: Props) => {
const [isOpen, setIsOpen] = useState(false);
- const { mutateAsync, isLoading } = api.compose.delete.useMutation();
- const { data } = api.compose.one.useQuery(
- { composeId },
- { enabled: !!composeId },
- );
+
+ const queryMap = {
+ postgres: () =>
+ api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }),
+ redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }),
+ mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }),
+ mariadb: () =>
+ api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }),
+ application: () =>
+ api.application.one.useQuery({ applicationId: id }, { enabled: !!id }),
+ mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }),
+ compose: () =>
+ api.compose.one.useQuery({ composeId: id }, { enabled: !!id }),
+ };
+ const { data, refetch } = queryMap[type]
+ ? queryMap[type]()
+ : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id });
+
+ const mutationMap = {
+ postgres: () => api.postgres.remove.useMutation(),
+ redis: () => api.redis.remove.useMutation(),
+ mysql: () => api.mysql.remove.useMutation(),
+ mariadb: () => api.mariadb.remove.useMutation(),
+ application: () => api.application.delete.useMutation(),
+ mongo: () => api.mongo.remove.useMutation(),
+ compose: () => api.compose.delete.useMutation(),
+ };
+ const { mutateAsync, isLoading } = mutationMap[type]
+ ? mutationMap[type]()
+ : api.mongo.remove.useMutation();
const { push } = useRouter();
const form = useForm({
defaultValues: {
@@ -62,14 +89,23 @@ export const DeleteCompose = ({ composeId }: Props) => {
const expectedName = `${data?.name}/${data?.appName}`;
if (formData.projectName === expectedName) {
const { deleteVolumes } = formData;
- await mutateAsync({ composeId, deleteVolumes })
+ await mutateAsync({
+ mongoId: id || "",
+ postgresId: id || "",
+ redisId: id || "",
+ mysqlId: id || "",
+ mariadbId: id || "",
+ applicationId: id || "",
+ composeId: id || "",
+ deleteVolumes,
+ })
.then((result) => {
push(`/dashboard/project/${result?.projectId}`);
- toast.success("Compose deleted successfully");
+ toast.success("deleted successfully");
setIsOpen(false);
})
.catch(() => {
- toast.error("Error deleting the compose");
+ toast.error("Error deleting the service");
});
} else {
form.setError("projectName", {
@@ -95,8 +131,8 @@ export const DeleteCompose = ({ composeId }: Props) => {
Are you absolutely sure?
This action cannot be undone. This will permanently delete the
- compose. If you are sure please enter the compose name to delete
- this compose.
+ service. If you are sure please enter the service name to delete
+ this service.
@@ -119,9 +155,7 @@ export const DeleteCompose = ({ composeId }: Props) => {
variant="outline"
onClick={() => {
if (data?.name && data?.appName) {
- navigator.clipboard.writeText(
- `${data.name}/${data.appName}`,
- );
+ copy(`${data.name}/${data.appName}`);
toast.success("Copied to clipboard. Be careful!");
}
}}
@@ -142,27 +176,29 @@ export const DeleteCompose = ({ composeId }: Props) => {
)}
/>
-
(
-
-
-
-
-
+ {type === "compose" && (
+
(
+
+
+
+
+
-
- Delete volumes associated with this compose
-
-
-
-
- )}
- />
+
+ Delete volumes associated with this compose
+
+
+
+
+ )}
+ />
+ )}
diff --git a/apps/dokploy/components/dashboard/compose/domains/show-domains.tsx b/apps/dokploy/components/dashboard/compose/domains/show-domains.tsx
index e9527067..c524d443 100644
--- a/apps/dokploy/components/dashboard/compose/domains/show-domains.tsx
+++ b/apps/dokploy/components/dashboard/compose/domains/show-domains.tsx
@@ -97,8 +97,12 @@ export const ShowDomainsCompose = ({ composeId }: Props) => {
composeId={composeId}
domainId={item.domainId}
>
-
-
+
+
{
{repositories?.map((repo) => (
{
form.setValue("repository", {
@@ -247,7 +247,12 @@ export const SaveBitbucketProviderCompose = ({ composeId }: Props) => {
form.setValue("branch", "");
}}
>
- {repo.name}
+
+ {repo.name}
+
+ {repo.owner.username}
+
+
{
{repositories?.map((repo) => (
{
form.setValue("repository", {
@@ -238,7 +238,12 @@ export const SaveGithubProviderCompose = ({ composeId }: Props) => {
form.setValue("branch", "");
}}
>
- {repo.name}
+
+ {repo.name}
+
+ {repo.owner.login}
+
+
{
{repositories?.map((repo) => {
return (
{
form.setValue("repository", {
@@ -262,7 +262,12 @@ export const SaveGitlabProviderCompose = ({ composeId }: Props) => {
form.setValue("branch", "");
}}
>
- {repo.name}
+
+ {repo.name}
+
+ {repo.owner.username}
+
+
{
const utils = api.useUtils();
-
+ const { data: isCloud } = api.settings.isCloud.useQuery();
const [visible, setVisible] = useState(false);
const slug = slugify(projectName);
const { data: servers } = api.server.withSSHKey.useQuery();
@@ -166,7 +166,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
- Select a Server (Optional)
+ Select a Server {!isCloud ? "(Optional)" : ""}
@@ -197,7 +197,12 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
key={server.serverId}
value={server.serverId}
>
- {server.name}
+
+ {server.name}
+
+ {server.ipAddress}
+
+
))}
Servers ({servers?.length})
diff --git a/apps/dokploy/components/dashboard/project/add-compose.tsx b/apps/dokploy/components/dashboard/project/add-compose.tsx
index dc753e94..ea8690a8 100644
--- a/apps/dokploy/components/dashboard/project/add-compose.tsx
+++ b/apps/dokploy/components/dashboard/project/add-compose.tsx
@@ -73,6 +73,7 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
const utils = api.useUtils();
const [visible, setVisible] = useState(false);
const slug = slugify(projectName);
+ const { data: isCloud } = api.settings.isCloud.useQuery();
const { data: servers } = api.server.withSSHKey.useQuery();
const { mutateAsync, isLoading, error, isError } =
api.compose.create.useMutation();
@@ -173,7 +174,7 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
- Select a Server (Optional)
+ Select a Server {!isCloud ? "(Optional)" : ""}
@@ -204,7 +205,12 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
key={server.serverId}
value={server.serverId}
>
- {server.name}
+
+ {server.name}
+
+ {server.ipAddress}
+
+
))}
Servers ({servers?.length})
diff --git a/apps/dokploy/components/dashboard/project/add-database.tsx b/apps/dokploy/components/dashboard/project/add-database.tsx
index fc86d253..1ca0d6a5 100644
--- a/apps/dokploy/components/dashboard/project/add-database.tsx
+++ b/apps/dokploy/components/dashboard/project/add-database.tsx
@@ -89,7 +89,7 @@ const mySchema = z.discriminatedUnion("type", [
z
.object({
type: z.literal("postgres"),
- databaseName: z.string().min(1, "Database name required"),
+ databaseName: z.string().default("postgres"),
databaseUser: z.string().default("postgres"),
})
.merge(baseDatabaseSchema),
@@ -110,7 +110,7 @@ const mySchema = z.discriminatedUnion("type", [
type: z.literal("mysql"),
databaseRootPassword: z.string().default(""),
databaseUser: z.string().default("mysql"),
- databaseName: z.string().min(1, "Database name required"),
+ databaseName: z.string().default("mysql"),
})
.merge(baseDatabaseSchema),
z
@@ -119,7 +119,7 @@ const mySchema = z.discriminatedUnion("type", [
dockerImage: z.string().default("mariadb:4"),
databaseRootPassword: z.string().default(""),
databaseUser: z.string().default("mariadb"),
- databaseName: z.string().min(1, "Database name required"),
+ databaseName: z.string().default("mariadb"),
})
.merge(baseDatabaseSchema),
]);
@@ -206,7 +206,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
promise = postgresMutation.mutateAsync({
...commonParams,
databasePassword: data.databasePassword,
- databaseName: data.databaseName,
+ databaseName: data.databaseName || "postgres",
databaseUser:
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
@@ -233,7 +233,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
...commonParams,
databasePassword: data.databasePassword,
databaseRootPassword: data.databaseRootPassword,
- databaseName: data.databaseName,
+ databaseName: data.databaseName || "mariadb",
databaseUser:
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
serverId: data.serverId,
@@ -242,7 +242,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
promise = mysqlMutation.mutateAsync({
...commonParams,
databasePassword: data.databasePassword,
- databaseName: data.databaseName,
+ databaseName: data.databaseName || "mysql",
databaseUser:
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
databaseRootPassword: data.databaseRootPassword,
diff --git a/apps/dokploy/components/dashboard/project/add-template.tsx b/apps/dokploy/components/dashboard/project/add-template.tsx
index faee27ef..cc6962aa 100644
--- a/apps/dokploy/components/dashboard/project/add-template.tsx
+++ b/apps/dokploy/components/dashboard/project/add-template.tsx
@@ -80,6 +80,7 @@ export const AddTemplate = ({ projectId }: Props) => {
const [viewMode, setViewMode] = useState<"detailed" | "icon">("detailed");
const [selectedTags, setSelectedTags] = useState([]);
const { data } = api.compose.templates.useQuery();
+ const { data: isCloud } = api.settings.isCloud.useQuery();
const { data: servers } = api.server.withSSHKey.useQuery();
const { data: tags, isLoading: isLoadingTags } =
api.compose.getTags.useQuery();
@@ -308,7 +309,7 @@ export const AddTemplate = ({ projectId }: Props) => {
{/* Create Button */}
{
- Select a Server (Optional)
+ Select a Server{" "}
+ {!isCloud ? "(Optional)" : ""}
@@ -405,7 +407,12 @@ export const AddTemplate = ({ projectId }: Props) => {
key={server.serverId}
value={server.serverId}
>
- {server.name}
+
+ {server.name}
+
+ {server.ipAddress}
+
+
))}
diff --git a/apps/dokploy/components/dashboard/projects/show.tsx b/apps/dokploy/components/dashboard/projects/show.tsx
index afeabf30..ca83b588 100644
--- a/apps/dokploy/components/dashboard/projects/show.tsx
+++ b/apps/dokploy/components/dashboard/projects/show.tsx
@@ -23,8 +23,10 @@ import {
import {
DropdownMenu,
DropdownMenuContent,
+ DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
+ DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
@@ -149,14 +151,91 @@ export const ShowProjects = () => {
href={`/dashboard/project/${project.projectId}`}
>
-
-
-
-
+ {project.applications.length > 0 ||
+ project.compose.length > 0 ? (
+
+
+
+
+
+
+ e.stopPropagation()}
+ >
+ {project.applications.length > 0 && (
+
+
+ Applications
+
+ {project.applications.map((app) => (
+
+
+
+
+ {app.name}
+
+
+ {app.domains.map((domain) => (
+
+
+ {domain.host}
+
+
+
+ ))}
+
+
+ ))}
+
+ )}
+ {project.compose.length > 0 && (
+
+
+ Compose
+
+ {project.compose.map((comp) => (
+
+
+
+
+ {comp.name}
+
+
+ {comp.domains.map((domain) => (
+
+
+ {domain.host}
+
+
+
+ ))}
+
+
+ ))}
+
+ )}
+
+
+ ) : null}
@@ -182,7 +261,10 @@ export const ShowProjects = () => {
-
+ e.stopPropagation()}
+ >
Actions
diff --git a/apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx b/apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx
index 3d03d7c6..c6546f2d 100644
--- a/apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx
+++ b/apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx
@@ -61,6 +61,7 @@ export const AddCertificate = () => {
const [open, setOpen] = useState(false);
const utils = api.useUtils();
+ const { data: isCloud } = api.settings.isCloud.useQuery();
const { mutateAsync, isError, error, isLoading } =
api.certificates.create.useMutation();
const { data: servers } = api.server.withSSHKey.useQuery();
@@ -181,7 +182,7 @@ export const AddCertificate = () => {
- Select a Server (Optional)
+ Select a Server {!isCloud && "(Optional)"}
@@ -202,7 +203,12 @@ export const AddCertificate = () => {
key={server.serverId}
value={server.serverId}
>
- {server.name}
+
+ {server.name}
+
+ {server.ipAddress}
+
+
))}
Servers ({servers?.length})
diff --git a/apps/dokploy/components/dashboard/settings/ssh-keys/handle-ssh-keys.tsx b/apps/dokploy/components/dashboard/settings/ssh-keys/handle-ssh-keys.tsx
index f100979e..fc48134a 100644
--- a/apps/dokploy/components/dashboard/settings/ssh-keys/handle-ssh-keys.tsx
+++ b/apps/dokploy/components/dashboard/settings/ssh-keys/handle-ssh-keys.tsx
@@ -22,7 +22,7 @@ import { Textarea } from "@/components/ui/textarea";
import { sshKeyCreate, type sshKeyType } from "@/server/db/validations";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
-import { PenBoxIcon, PlusIcon } from "lucide-react";
+import { DownloadIcon, PenBoxIcon, PlusIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
@@ -111,6 +111,26 @@ export const HandleSSHKeys = ({ sshKeyId }: Props) => {
toast.error("Error generating the SSH Key");
});
+ const downloadKey = (
+ content: string,
+ defaultFilename: string,
+ keyType: "private" | "public",
+ ) => {
+ const keyName = form.watch("name");
+ const filename = keyName
+ ? `${keyName}${sshKeyId ? `_${sshKeyId}` : ""}_${keyType}_${defaultFilename}`
+ : `${keyType}_${defaultFilename}`;
+ const blob = new Blob([content], { type: "text/plain" });
+ const url = window.URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = filename;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ window.URL.revokeObjectURL(url);
+ };
+
return (
@@ -245,7 +265,41 @@ export const HandleSSHKeys = ({ sshKeyId }: Props) => {
)}
/>
-
+
+
+ {form.watch("privateKey") && (
+
+ downloadKey(form.watch("privateKey"), "id_rsa", "private")
+ }
+ className="flex items-center gap-2"
+ >
+
+ Private Key
+
+ )}
+ {form.watch("publicKey") && (
+
+ downloadKey(
+ form.watch("publicKey"),
+ "id_rsa.pub",
+ "public",
+ )
+ }
+ className="flex items-center gap-2"
+ >
+
+ Public Key
+
+ )}
+
{sshKeyId ? "Update" : "Create"}
diff --git a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx
index e45b73d2..dccdec00 100644
--- a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx
+++ b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx
@@ -4,6 +4,7 @@ import { useEffect, useRef } from "react";
import { FitAddon } from "xterm-addon-fit";
import "@xterm/xterm/css/xterm.css";
import { AttachAddon } from "@xterm/addon-attach";
+import { ClipboardAddon } from "@xterm/addon-clipboard";
import { useTheme } from "next-themes";
import { getLocalServerData } from "./local-server-config";
@@ -37,6 +38,7 @@ export const Terminal: React.FC = ({ id, serverId }) => {
foreground: "currentColor",
},
});
+
const addonFit = new FitAddon();
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
@@ -54,6 +56,8 @@ export const Terminal: React.FC = ({ id, serverId }) => {
const ws = new WebSocket(wsUrl);
const addonAttach = new AttachAddon(ws);
+ const clipboardAddon = new ClipboardAddon();
+ term.loadAddon(clipboardAddon);
// @ts-ignore
term.open(termRef.current);
@@ -68,7 +72,7 @@ export const Terminal: React.FC = ({ id, serverId }) => {
return (
-
diff --git a/apps/dokploy/components/layouts/side.tsx b/apps/dokploy/components/layouts/side.tsx
index c711b862..44a4b0ed 100644
--- a/apps/dokploy/components/layouts/side.tsx
+++ b/apps/dokploy/components/layouts/side.tsx
@@ -247,7 +247,7 @@ const MENU: Menu = {
settings: [
{
isSingle: true,
- title: "Server",
+ title: "Web Server",
url: "/dashboard/settings/server",
icon: Activity,
// Only enabled for admins in non-cloud environments
@@ -262,7 +262,7 @@ const MENU: Menu = {
},
{
isSingle: true,
- title: "Servers",
+ title: "Remote Servers",
url: "/dashboard/settings/servers",
icon: Server,
// Only enabled for admins
@@ -783,7 +783,7 @@ export default function Page({ children }: Props) {
))}
- {!isCloud && (
+ {!isCloud && auth?.rol === "admin" && (
diff --git a/apps/dokploy/drizzle/0060_disable-aggressive-cache.sql b/apps/dokploy/drizzle/0060_disable-aggressive-cache.sql
new file mode 100644
index 00000000..33828cec
--- /dev/null
+++ b/apps/dokploy/drizzle/0060_disable-aggressive-cache.sql
@@ -0,0 +1,3 @@
+-- Custom SQL migration file, put you code below!
+
+UPDATE "admin" SET "cleanupCacheApplications" = false;
diff --git a/apps/dokploy/drizzle/meta/0060_snapshot.json b/apps/dokploy/drizzle/meta/0060_snapshot.json
new file mode 100644
index 00000000..5e5719f7
--- /dev/null
+++ b/apps/dokploy/drizzle/meta/0060_snapshot.json
@@ -0,0 +1,4341 @@
+{
+ "id": "1f4eada1-a120-490d-a152-2fc7a81eee7a",
+ "prevId": "8492fecb-69a3-4efb-86b1-7bbc62e1eba8",
+ "version": "6",
+ "dialect": "postgresql",
+ "tables": {
+ "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
+ },
+ "previewBuildArgs": {
+ "name": "previewBuildArgs",
+ "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'"
+ },
+ "previewLimit": {
+ "name": "previewLimit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 3
+ },
+ "isPreviewDeploymentsActive": {
+ "name": "isPreviewDeploymentsActive",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "buildArgs": {
+ "name": "buildArgs",
+ "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'"
+ },
+ "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": "'/'"
+ },
+ "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
+ },
+ "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
+ },
+ "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
+ },
+ "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'"
+ },
+ "herokuVersion": {
+ "name": "herokuVersion",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'24'"
+ },
+ "publishDirectory": {
+ "name": "publishDirectory",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "registryId": {
+ "name": "registryId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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
+ },
+ "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_projectId_project_projectId_fk": {
+ "name": "application_projectId_project_projectId_fk",
+ "tableFrom": "application",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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_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
+ }
+ }
+ },
+ "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'"
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "postgres_projectId_project_projectId_fk": {
+ "name": "postgres_projectId_project_projectId_fk",
+ "tableFrom": "postgres",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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
+ }
+ }
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "isRegistered": {
+ "name": "isRegistered",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "expirationDate": {
+ "name": "expirationDate",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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
+ },
+ "accesedProjects": {
+ "name": "accesedProjects",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY[]::text[]"
+ },
+ "accesedServices": {
+ "name": "accesedServices",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY[]::text[]"
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "authId": {
+ "name": "authId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "user_adminId_admin_adminId_fk": {
+ "name": "user_adminId_admin_adminId_fk",
+ "tableFrom": "user",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_authId_auth_id_fk": {
+ "name": "user_authId_auth_id_fk",
+ "tableFrom": "user",
+ "columnsFrom": [
+ "authId"
+ ],
+ "tableTo": "auth",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.admin": {
+ "name": "admin",
+ "schema": "",
+ "columns": {
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "serverIp": {
+ "name": "serverIp",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "certificateType": {
+ "name": "certificateType",
+ "type": "certificateType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "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
+ },
+ "enableLogRotation": {
+ "name": "enableLogRotation",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "authId": {
+ "name": "authId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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
+ },
+ "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
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "admin_authId_auth_id_fk": {
+ "name": "admin_authId_auth_id_fk",
+ "tableFrom": "admin",
+ "columnsFrom": [
+ "authId"
+ ],
+ "tableTo": "auth",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.auth": {
+ "name": "auth",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rol": {
+ "name": "rol",
+ "type": "Roles",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret": {
+ "name": "secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is2FAEnabled": {
+ "name": "is2FAEnabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "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": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "auth_email_unique": {
+ "name": "auth_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": 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
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "env": {
+ "name": "env",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "project_adminId_admin_adminId_fk": {
+ "name": "project_adminId_admin_adminId_fk",
+ "tableFrom": "project",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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
+ },
+ "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'"
+ }
+ },
+ "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": {}
+ },
+ "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'"
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mariadb_projectId_project_projectId_fk": {
+ "name": "mariadb_projectId_project_projectId_fk",
+ "tableFrom": "mariadb",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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
+ }
+ }
+ },
+ "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'"
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "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_projectId_project_projectId_fk": {
+ "name": "mongo_projectId_project_projectId_fk",
+ "tableFrom": "mongo",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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
+ }
+ }
+ },
+ "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'"
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mysql_projectId_project_projectId_fk": {
+ "name": "mysql_projectId_project_projectId_fk",
+ "tableFrom": "mysql",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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
+ }
+ }
+ },
+ "public.backup": {
+ "name": "backup",
+ "schema": "",
+ "columns": {
+ "backupId": {
+ "name": "backupId",
+ "type": "text",
+ "primaryKey": true,
+ "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
+ },
+ "destinationId": {
+ "name": "destinationId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "databaseType": {
+ "name": "databaseType",
+ "type": "databaseType",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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
+ }
+ },
+ "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_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"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "destination_adminId_admin_adminId_fk": {
+ "name": "destination_adminId_admin_adminId_fk",
+ "tableFrom": "destination",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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
+ },
+ "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
+ },
+ "errorMessage": {
+ "name": "errorMessage",
+ "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"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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": {}
+ },
+ "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
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "certificate_adminId_admin_adminId_fk": {
+ "name": "certificate_adminId_admin_adminId_fk",
+ "tableFrom": "certificate",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "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
+ }
+ }
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_user_id_auth_id_fk": {
+ "name": "session_user_id_auth_id_fk",
+ "tableFrom": "session",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "auth",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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": {}
+ },
+ "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
+ }
+ }
+ },
+ "public.port": {
+ "name": "port",
+ "schema": "",
+ "columns": {
+ "portId": {
+ "name": "portId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "publishedPort": {
+ "name": "publishedPort",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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": {}
+ },
+ "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'"
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "serverId": {
+ "name": "serverId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "redis_projectId_project_projectId_fk": {
+ "name": "redis_projectId_project_projectId_fk",
+ "tableFrom": "redis",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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
+ }
+ }
+ },
+ "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
+ },
+ "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": "''"
+ },
+ "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
+ },
+ "composeStatus": {
+ "name": "composeStatus",
+ "type": "applicationStatus",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "projectId": {
+ "name": "projectId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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
+ },
+ "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_projectId_project_projectId_fk": {
+ "name": "compose_projectId_project_projectId_fk",
+ "tableFrom": "compose",
+ "columnsFrom": [
+ "projectId"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "projectId"
+ ],
+ "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_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": {}
+ },
+ "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'"
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "registry_adminId_admin_adminId_fk": {
+ "name": "registry_adminId_admin_adminId_fk",
+ "tableFrom": "registry",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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": {}
+ },
+ "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": {}
+ },
+ "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": {}
+ },
+ "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
+ },
+ "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
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "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_adminId_admin_adminId_fk": {
+ "name": "notification_adminId_admin_adminId_fk",
+ "tableFrom": "notification",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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": {}
+ },
+ "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
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "ssh-key_adminId_admin_adminId_fk": {
+ "name": "ssh-key_adminId_admin_adminId_fk",
+ "tableFrom": "ssh-key",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "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
+ },
+ "adminId": {
+ "name": "adminId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "git_provider_adminId_admin_adminId_fk": {
+ "name": "git_provider_adminId_admin_adminId_fk",
+ "tableFrom": "git_provider",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.bitbucket": {
+ "name": "bitbucket",
+ "schema": "",
+ "columns": {
+ "bitbucketId": {
+ "name": "bitbucketId",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "bitbucketUsername": {
+ "name": "bitbucketUsername",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "appPassword": {
+ "name": "appPassword",
+ "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": {}
+ },
+ "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": {}
+ },
+ "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": {}
+ },
+ "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
+ },
+ "adminId": {
+ "name": "adminId",
+ "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
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "server_adminId_admin_adminId_fk": {
+ "name": "server_adminId_admin_adminId_fk",
+ "tableFrom": "server",
+ "columnsFrom": [
+ "adminId"
+ ],
+ "tableTo": "admin",
+ "columnsTo": [
+ "adminId"
+ ],
+ "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": {}
+ },
+ "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
+ }
+ }
+ }
+ },
+ "enums": {
+ "public.buildType": {
+ "name": "buildType",
+ "schema": "public",
+ "values": [
+ "dockerfile",
+ "heroku_buildpacks",
+ "paketo_buildpacks",
+ "nixpacks",
+ "static"
+ ]
+ },
+ "public.sourceType": {
+ "name": "sourceType",
+ "schema": "public",
+ "values": [
+ "docker",
+ "git",
+ "github",
+ "gitlab",
+ "bitbucket",
+ "drop"
+ ]
+ },
+ "public.Roles": {
+ "name": "Roles",
+ "schema": "public",
+ "values": [
+ "admin",
+ "user"
+ ]
+ },
+ "public.domainType": {
+ "name": "domainType",
+ "schema": "public",
+ "values": [
+ "compose",
+ "application",
+ "preview"
+ ]
+ },
+ "public.databaseType": {
+ "name": "databaseType",
+ "schema": "public",
+ "values": [
+ "postgres",
+ "mariadb",
+ "mysql",
+ "mongo"
+ ]
+ },
+ "public.deploymentStatus": {
+ "name": "deploymentStatus",
+ "schema": "public",
+ "values": [
+ "running",
+ "done",
+ "error"
+ ]
+ },
+ "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.protocolType": {
+ "name": "protocolType",
+ "schema": "public",
+ "values": [
+ "tcp",
+ "udp"
+ ]
+ },
+ "public.applicationStatus": {
+ "name": "applicationStatus",
+ "schema": "public",
+ "values": [
+ "idle",
+ "running",
+ "done",
+ "error"
+ ]
+ },
+ "public.certificateType": {
+ "name": "certificateType",
+ "schema": "public",
+ "values": [
+ "letsencrypt",
+ "none"
+ ]
+ },
+ "public.composeType": {
+ "name": "composeType",
+ "schema": "public",
+ "values": [
+ "docker-compose",
+ "stack"
+ ]
+ },
+ "public.sourceTypeCompose": {
+ "name": "sourceTypeCompose",
+ "schema": "public",
+ "values": [
+ "git",
+ "github",
+ "gitlab",
+ "bitbucket",
+ "raw"
+ ]
+ },
+ "public.RegistryType": {
+ "name": "RegistryType",
+ "schema": "public",
+ "values": [
+ "selfHosted",
+ "cloud"
+ ]
+ },
+ "public.notificationType": {
+ "name": "notificationType",
+ "schema": "public",
+ "values": [
+ "slack",
+ "telegram",
+ "discord",
+ "email",
+ "gotify"
+ ]
+ },
+ "public.gitProviderType": {
+ "name": "gitProviderType",
+ "schema": "public",
+ "values": [
+ "github",
+ "gitlab",
+ "bitbucket"
+ ]
+ },
+ "public.serverStatus": {
+ "name": "serverStatus",
+ "schema": "public",
+ "values": [
+ "active",
+ "inactive"
+ ]
+ }
+ },
+ "schemas": {},
+ "_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 ccf4a066..25dd0a13 100644
--- a/apps/dokploy/drizzle/meta/_journal.json
+++ b/apps/dokploy/drizzle/meta/_journal.json
@@ -421,6 +421,13 @@
"when": 1737615160768,
"tag": "0059_striped_bill_hollister",
"breakpoints": true
+ },
+ {
+ "idx": 60,
+ "version": "6",
+ "when": 1737929896838,
+ "tag": "0060_disable-aggressive-cache",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json
index 5166c2f9..1839c0b2 100644
--- a/apps/dokploy/package.json
+++ b/apps/dokploy/package.json
@@ -1,6 +1,6 @@
{
"name": "dokploy",
- "version": "v0.17.8",
+ "version": "v0.17.9",
"private": true,
"license": "Apache-2.0",
"type": "module",
@@ -35,6 +35,18 @@
"test": "vitest --config __test__/vitest.config.ts"
},
"dependencies": {
+ "bl": "6.0.11",
+ "rotating-file-stream": "3.2.3",
+ "qrcode": "^1.5.3",
+ "otpauth": "^9.2.3",
+ "hi-base32": "^0.5.1",
+ "boxen": "^7.1.1",
+ "@octokit/auth-app": "^6.0.4",
+ "nodemailer": "6.9.14",
+ "@react-email/components": "^0.0.21",
+ "node-os-utils": "1.3.7",
+ "@lucia-auth/adapter-drizzle": "1.0.7",
+ "dockerode": "4.0.2",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-yaml": "^6.1.1",
"@codemirror/language": "^6.10.1",
@@ -75,6 +87,7 @@
"@uiw/react-codemirror": "^4.22.1",
"@xterm/addon-attach": "0.10.0",
"@xterm/xterm": "^5.4.0",
+ "@xterm/addon-clipboard": "0.1.0",
"adm-zip": "^0.5.14",
"bcrypt": "5.1.1",
"bullmq": "5.4.2",
@@ -127,6 +140,9 @@
"@faker-js/faker": "^8.4.1"
},
"devDependencies": {
+ "@types/qrcode": "^1.5.5",
+ "@types/nodemailer": "^6.4.15",
+ "@types/node-os-utils": "1.3.4",
"@types/adm-zip": "^0.5.5",
"@types/bcrypt": "5.0.2",
"@types/js-cookie": "^3.0.6",
diff --git a/apps/dokploy/pages/api/deploy/github.ts b/apps/dokploy/pages/api/deploy/github.ts
index ff7a9221..761c3866 100644
--- a/apps/dokploy/pages/api/deploy/github.ts
+++ b/apps/dokploy/pages/api/deploy/github.ts
@@ -182,8 +182,9 @@ export default async function handler(
}
} else if (req.headers["x-github-event"] === "pull_request") {
const prId = githubBody?.pull_request?.id;
+ const action = githubBody?.action;
- if (githubBody?.action === "closed") {
+ if (action === "closed") {
const previewDeploymentResult =
await findPreviewDeploymentsByPullRequestId(prId);
@@ -201,79 +202,86 @@ export default async function handler(
res.status(200).json({ message: "Preview Deployment Closed" });
return;
}
+
// opened or synchronize or reopened
- const repository = githubBody?.repository?.name;
- const deploymentHash = githubBody?.pull_request?.head?.sha;
- const branch = githubBody?.pull_request?.base?.ref;
- const owner = githubBody?.repository?.owner?.login;
+ if (
+ action === "opened" ||
+ action === "synchronize" ||
+ action === "reopened"
+ ) {
+ const repository = githubBody?.repository?.name;
+ const deploymentHash = githubBody?.pull_request?.head?.sha;
+ const branch = githubBody?.pull_request?.base?.ref;
+ const owner = githubBody?.repository?.owner?.login;
- const apps = await db.query.applications.findMany({
- where: and(
- eq(applications.sourceType, "github"),
- eq(applications.repository, repository),
- eq(applications.branch, branch),
- eq(applications.isPreviewDeploymentsActive, true),
- eq(applications.owner, owner),
- ),
- with: {
- previewDeployments: true,
- },
- });
-
- const prBranch = githubBody?.pull_request?.head?.ref;
-
- const prNumber = githubBody?.pull_request?.number;
- const prTitle = githubBody?.pull_request?.title;
- const prURL = githubBody?.pull_request?.html_url;
-
- for (const app of apps) {
- const previewLimit = app?.previewLimit || 0;
- if (app?.previewDeployments?.length > previewLimit) {
- continue;
- }
- const previewDeploymentResult =
- await findPreviewDeploymentByApplicationId(app.applicationId, prId);
-
- let previewDeploymentId =
- previewDeploymentResult?.previewDeploymentId || "";
-
- if (!previewDeploymentResult) {
- const previewDeployment = await createPreviewDeployment({
- applicationId: app.applicationId as string,
- branch: prBranch,
- pullRequestId: prId,
- pullRequestNumber: prNumber,
- pullRequestTitle: prTitle,
- pullRequestURL: prURL,
- });
- previewDeploymentId = previewDeployment.previewDeploymentId;
- }
-
- const jobData: DeploymentJob = {
- applicationId: app.applicationId as string,
- titleLog: "Preview Deployment",
- descriptionLog: `Hash: ${deploymentHash}`,
- type: "deploy",
- applicationType: "application-preview",
- server: !!app.serverId,
- previewDeploymentId,
- };
-
- if (IS_CLOUD && app.serverId) {
- jobData.serverId = app.serverId;
- await deploy(jobData);
- return true;
- }
- await myQueue.add(
- "deployments",
- { ...jobData },
- {
- removeOnComplete: true,
- removeOnFail: true,
+ const apps = await db.query.applications.findMany({
+ where: and(
+ eq(applications.sourceType, "github"),
+ eq(applications.repository, repository),
+ eq(applications.branch, branch),
+ eq(applications.isPreviewDeploymentsActive, true),
+ eq(applications.owner, owner),
+ ),
+ with: {
+ previewDeployments: true,
},
- );
+ });
+
+ const prBranch = githubBody?.pull_request?.head?.ref;
+
+ const prNumber = githubBody?.pull_request?.number;
+ const prTitle = githubBody?.pull_request?.title;
+ const prURL = githubBody?.pull_request?.html_url;
+
+ for (const app of apps) {
+ const previewLimit = app?.previewLimit || 0;
+ if (app?.previewDeployments?.length > previewLimit) {
+ continue;
+ }
+ const previewDeploymentResult =
+ await findPreviewDeploymentByApplicationId(app.applicationId, prId);
+
+ let previewDeploymentId =
+ previewDeploymentResult?.previewDeploymentId || "";
+
+ if (!previewDeploymentResult) {
+ const previewDeployment = await createPreviewDeployment({
+ applicationId: app.applicationId as string,
+ branch: prBranch,
+ pullRequestId: prId,
+ pullRequestNumber: prNumber,
+ pullRequestTitle: prTitle,
+ pullRequestURL: prURL,
+ });
+ previewDeploymentId = previewDeployment.previewDeploymentId;
+ }
+
+ const jobData: DeploymentJob = {
+ applicationId: app.applicationId as string,
+ titleLog: "Preview Deployment",
+ descriptionLog: `Hash: ${deploymentHash}`,
+ type: "deploy",
+ applicationType: "application-preview",
+ server: !!app.serverId,
+ previewDeploymentId,
+ };
+
+ if (IS_CLOUD && app.serverId) {
+ jobData.serverId = app.serverId;
+ await deploy(jobData);
+ continue;
+ }
+ await myQueue.add(
+ "deployments",
+ { ...jobData },
+ {
+ removeOnComplete: true,
+ removeOnFail: true,
+ },
+ );
+ }
+ return res.status(200).json({ message: "Apps Deployed" });
}
- return res.status(200).json({ message: "Apps Deployed" });
}
return res.status(400).json({ message: "No Actions matched" });
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx
index bdde2af5..3ef433ed 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx
@@ -13,6 +13,7 @@ import { ShowGeneralApplication } from "@/components/dashboard/application/gener
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
import { ShowPreviewDeployments } from "@/components/dashboard/application/preview-deployments/show-preview-deployments";
import { UpdateApplication } from "@/components/dashboard/application/update-application";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
import { ProjectLayout } from "@/components/layouts/project-layout";
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
@@ -82,8 +83,6 @@ const Service = (
},
);
- const { mutateAsync, isLoading: isRemoving } =
- api.application.delete.useMutation();
const { data: auth } = api.auth.get.useQuery();
const { data: user } = api.user.byAuthId.useQuery(
{
@@ -177,34 +176,7 @@ const Service = (
{(auth?.rol === "admin" || user?.canDeleteServices) && (
- {
- await mutateAsync({
- applicationId: applicationId,
- })
- .then(() => {
- router.push(
- `/dashboard/project/${data?.projectId}`,
- );
- toast.success("Application deleted successfully");
- })
- .catch(() => {
- toast.error("Error deleting application");
- });
- }}
- >
-
-
-
-
+
)}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx
index dba3aea8..66c3ef53 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx
@@ -1,7 +1,7 @@
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
import { AddCommandCompose } from "@/components/dashboard/compose/advanced/add-command";
-import { DeleteCompose } from "@/components/dashboard/compose/delete-compose";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { ShowDeploymentsCompose } from "@/components/dashboard/compose/deployments/show-deployments-compose";
import { ShowDomainsCompose } from "@/components/dashboard/compose/domains/show-domains";
import { ShowGeneralCompose } from "@/components/dashboard/compose/general/show";
@@ -168,7 +168,7 @@ const Service = (
{(auth?.rol === "admin" || user?.canDeleteServices) && (
-
+
)}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx
index fed8faa3..4edf9f14 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
import { ShowExternalMariadbCredentials } from "@/components/dashboard/mariadb/general/show-external-mariadb-credentials";
import { ShowGeneralMariadb } from "@/components/dashboard/mariadb/general/show-general-mariadb";
@@ -67,8 +68,7 @@ const Mariadb = (
enabled: !!auth?.id && auth?.rol === "user",
},
);
- const { mutateAsync: remove, isLoading: isRemoving } =
- api.mariadb.remove.useMutation();
+
return (
)}
-
+
{(auth?.rol === "admin" || user?.canDeleteServices) && (
- {
- await remove({ mariadbId })
- .then(() => {
- router.push(
- `/dashboard/project/${data?.projectId}`,
- );
- toast.success("Mariadb deleted successfully");
- })
- .catch(() => {
- toast.error("Error deleting the mariadb");
- });
- }}
- >
-
-
-
-
+
)}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx
index 49dcfa65..ecd42841 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
import { ShowExternalMongoCredentials } from "@/components/dashboard/mongo/general/show-external-mongo-credentials";
import { ShowGeneralMongo } from "@/components/dashboard/mongo/general/show-general-mongo";
@@ -69,8 +70,6 @@ const Mongo = (
enabled: !!auth?.id && auth?.rol === "user",
},
);
- const { mutateAsync: remove, isLoading: isRemoving } =
- api.mongo.remove.useMutation();
return (
@@ -155,32 +154,7 @@ const Mongo = (
{(auth?.rol === "admin" || user?.canDeleteServices) && (
- {
- await remove({ mongoId })
- .then(() => {
- router.push(
- `/dashboard/project/${data?.projectId}`,
- );
- toast.success("Mongo deleted successfully");
- })
- .catch(() => {
- toast.error("Error deleting the mongo");
- });
- }}
- >
-
-
-
-
+
)}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx
index a6117a3a..5b851015 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
import { ShowExternalMysqlCredentials } from "@/components/dashboard/mysql/general/show-external-mysql-credentials";
@@ -68,8 +69,6 @@ const MySql = (
},
);
- const { mutateAsync: remove, isLoading: isRemoving } =
- api.mysql.remove.useMutation();
return (
{(auth?.rol === "admin" || user?.canDeleteServices) && (
- {
- await remove({ mysqlId })
- .then(() => {
- router.push(
- `/dashboard/project/${data?.projectId}`,
- );
- toast.success("Mysql deleted successfully");
- })
- .catch(() => {
- toast.error("Error deleting the mysql");
- });
- }}
- >
-
-
-
-
+
)}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx
index d7b4b8d3..78637254 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
import { ShowCustomCommand } from "@/components/dashboard/postgres/advanced/show-custom-command";
@@ -70,9 +71,6 @@ const Postgresql = (
},
);
- const { mutateAsync: remove, isLoading: isRemoving } =
- api.postgres.remove.useMutation();
-
return (
{(auth?.rol === "admin" || user?.canDeleteServices) && (
- {
- await remove({ postgresId })
- .then(() => {
- router.push(
- `/dashboard/project/${data?.projectId}`,
- );
- toast.success("Postgres deleted successfully");
- })
- .catch(() => {
- toast.error("Error deleting the postgres");
- });
- }}
- >
-
-
-
-
+
)}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx
index 4a85eac0..1eef98e4 100644
--- a/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx
+++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
+import { DeleteService } from "@/components/dashboard/compose/delete-service";
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
import { ShowCustomCommand } from "@/components/dashboard/postgres/advanced/show-custom-command";
import { ShowExternalRedisCredentials } from "@/components/dashboard/redis/general/show-external-redis-credentials";
@@ -68,8 +69,6 @@ const Redis = (
},
);
- const { mutateAsync: remove, isLoading: isRemoving } =
- api.redis.remove.useMutation();
return (
{(auth?.rol === "admin" || user?.canDeleteServices) && (
- {
- await remove({ redisId })
- .then(() => {
- router.push(
- `/dashboard/project/${data?.projectId}`,
- );
- toast.success("Redis deleted successfully");
- })
- .catch(() => {
- toast.error("Error deleting the redis");
- });
- }}
- >
-
-
-
-
+
)}
diff --git a/apps/dokploy/public/locales/ru/settings.json b/apps/dokploy/public/locales/ru/settings.json
index 1e71d710..0d87ed15 100644
--- a/apps/dokploy/public/locales/ru/settings.json
+++ b/apps/dokploy/public/locales/ru/settings.json
@@ -1,5 +1,6 @@
{
"settings.common.save": "Сохранить",
+ "settings.common.enterTerminal": "Открыть терминал",
"settings.server.domain.title": "Домен сервера",
"settings.server.domain.description": "Установите домен для вашего серверного приложения Dokploy.",
"settings.server.domain.form.domain": "Домен",
@@ -7,18 +8,26 @@
"settings.server.domain.form.certificate.label": "Сертификат",
"settings.server.domain.form.certificate.placeholder": "Выберите сертификат",
"settings.server.domain.form.certificateOptions.none": "Нет",
- "settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt (По умолчанию)",
+ "settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt",
"settings.server.webServer.title": "Веб-сервер",
"settings.server.webServer.description": "Перезагрузка или очистка веб-сервера.",
- "settings.server.webServer.server.label": "Сервер",
- "settings.server.webServer.traefik.label": "Traefik",
- "settings.server.webServer.storage.label": "Дисковое пространство",
"settings.server.webServer.actions": "Действия",
"settings.server.webServer.reload": "Перезагрузить",
"settings.server.webServer.watchLogs": "Просмотр логов",
"settings.server.webServer.updateServerIp": "Изменить IP адрес",
+ "settings.server.webServer.server.label": "Сервер",
+ "settings.server.webServer.traefik.label": "Traefik",
"settings.server.webServer.traefik.modifyEnv": "Изменить переменные окружения",
+ "settings.server.webServer.traefik.managePorts": "Назначение портов",
+ "settings.server.webServer.traefik.managePortsDescription": "Добавить или удалить дополнительные порты для Traefik",
+ "settings.server.webServer.traefik.targetPort": "Внутренний порт",
+ "settings.server.webServer.traefik.publishedPort": "Внешний порт",
+ "settings.server.webServer.traefik.addPort": "Добавить порт",
+ "settings.server.webServer.traefik.portsUpdated": "Порты успешно обновлены",
+ "settings.server.webServer.traefik.portsUpdateError": "Не удалось обновить порты",
+ "settings.server.webServer.traefik.publishMode": "Режим сопоставления",
+ "settings.server.webServer.storage.label": "Дисковое пространство",
"settings.server.webServer.storage.cleanUnusedImages": "Очистить неиспользуемые образы",
"settings.server.webServer.storage.cleanUnusedVolumes": "Очистить неиспользуемые тома",
"settings.server.webServer.storage.cleanStoppedContainers": "Очистить остановленные контейнеры",
@@ -40,5 +49,10 @@
"settings.appearance.themes.dark": "Темная",
"settings.appearance.themes.system": "Системная",
"settings.appearance.language": "Язык",
- "settings.appearance.languageDescription": "Select a language for your dashboard"
+ "settings.appearance.languageDescription": "Выберите язык для панели управления",
+
+ "settings.terminal.connectionSettings": "Настройки подключения",
+ "settings.terminal.ipAddress": "IP адрес",
+ "settings.terminal.port": "Порт",
+ "settings.terminal.username": "Имя пользователя"
}
diff --git a/apps/dokploy/public/templates/alist.svg b/apps/dokploy/public/templates/alist.svg
new file mode 100644
index 00000000..37d5fdcd
--- /dev/null
+++ b/apps/dokploy/public/templates/alist.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/dokploy/public/templates/answer.png b/apps/dokploy/public/templates/answer.png
new file mode 100644
index 00000000..3fca604d
Binary files /dev/null and b/apps/dokploy/public/templates/answer.png differ
diff --git a/apps/dokploy/public/templates/erpnext.svg b/apps/dokploy/public/templates/erpnext.svg
new file mode 100644
index 00000000..d699ea2a
--- /dev/null
+++ b/apps/dokploy/public/templates/erpnext.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/apps/dokploy/public/templates/maybe.svg b/apps/dokploy/public/templates/maybe.svg
new file mode 100644
index 00000000..a4a87736
--- /dev/null
+++ b/apps/dokploy/public/templates/maybe.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/dokploy/public/templates/spacedrive.png b/apps/dokploy/public/templates/spacedrive.png
new file mode 100644
index 00000000..a10fffd5
Binary files /dev/null and b/apps/dokploy/public/templates/spacedrive.png differ
diff --git a/apps/dokploy/server/api/routers/mariadb.ts b/apps/dokploy/server/api/routers/mariadb.ts
index 09f4d675..6e85d274 100644
--- a/apps/dokploy/server/api/routers/mariadb.ts
+++ b/apps/dokploy/server/api/routers/mariadb.ts
@@ -9,6 +9,7 @@ import {
apiSaveExternalPortMariaDB,
apiUpdateMariaDB,
} from "@/server/db/schema";
+import { cancelJobs } from "@/server/utils/backup";
import {
IS_CLOUD,
addNewService,
@@ -16,6 +17,7 @@ import {
createMariadb,
createMount,
deployMariadb,
+ findBackupsByDbId,
findMariadbById,
findProjectById,
findServerById,
@@ -211,8 +213,10 @@ export const mariadbRouter = createTRPCRouter({
});
}
+ const backups = await findBackupsByDbId(input.mariadbId, "mariadb");
const cleanupOperations = [
async () => await removeService(mongo?.appName, mongo.serverId),
+ async () => await cancelJobs(backups),
async () => await removeMariadbById(input.mariadbId),
];
diff --git a/apps/dokploy/server/api/routers/mongo.ts b/apps/dokploy/server/api/routers/mongo.ts
index b114b8d8..2bca3ec5 100644
--- a/apps/dokploy/server/api/routers/mongo.ts
+++ b/apps/dokploy/server/api/routers/mongo.ts
@@ -9,6 +9,7 @@ import {
apiSaveExternalPortMongo,
apiUpdateMongo,
} from "@/server/db/schema";
+import { cancelJobs } from "@/server/utils/backup";
import {
IS_CLOUD,
addNewService,
@@ -16,6 +17,7 @@ import {
createMongo,
createMount,
deployMongo,
+ findBackupsByDbId,
findMongoById,
findProjectById,
removeMongoById,
@@ -252,9 +254,11 @@ export const mongoRouter = createTRPCRouter({
message: "You are not authorized to delete this mongo",
});
}
+ const backups = await findBackupsByDbId(input.mongoId, "mongo");
const cleanupOperations = [
async () => await removeService(mongo?.appName, mongo.serverId),
+ async () => await cancelJobs(backups),
async () => await removeMongoById(input.mongoId),
];
diff --git a/apps/dokploy/server/api/routers/mysql.ts b/apps/dokploy/server/api/routers/mysql.ts
index 44d2537a..7ebf4623 100644
--- a/apps/dokploy/server/api/routers/mysql.ts
+++ b/apps/dokploy/server/api/routers/mysql.ts
@@ -12,6 +12,7 @@ import {
import { TRPCError } from "@trpc/server";
+import { cancelJobs } from "@/server/utils/backup";
import {
IS_CLOUD,
addNewService,
@@ -19,6 +20,7 @@ import {
createMount,
createMysql,
deployMySql,
+ findBackupsByDbId,
findMySqlById,
findProjectById,
removeMySqlById,
@@ -249,8 +251,10 @@ export const mysqlRouter = createTRPCRouter({
});
}
+ const backups = await findBackupsByDbId(input.mysqlId, "mysql");
const cleanupOperations = [
async () => await removeService(mongo?.appName, mongo.serverId),
+ async () => await cancelJobs(backups),
async () => await removeMySqlById(input.mysqlId),
];
diff --git a/apps/dokploy/server/api/routers/postgres.ts b/apps/dokploy/server/api/routers/postgres.ts
index 7d178943..92603a61 100644
--- a/apps/dokploy/server/api/routers/postgres.ts
+++ b/apps/dokploy/server/api/routers/postgres.ts
@@ -14,6 +14,7 @@ import {
apiSaveExternalPortPostgres,
apiUpdatePostgres,
} from "@/server/db/schema";
+import { cancelJobs } from "@/server/utils/backup";
import {
IS_CLOUD,
addNewService,
@@ -21,6 +22,7 @@ import {
createMount,
createPostgres,
deployPostgres,
+ findBackupsByDbId,
findPostgresById,
findProjectById,
removePostgresById,
@@ -231,8 +233,11 @@ export const postgresRouter = createTRPCRouter({
});
}
+ const backups = await findBackupsByDbId(input.postgresId, "postgres");
+
const cleanupOperations = [
removeService(postgres.appName, postgres.serverId),
+ cancelJobs(backups),
removePostgresById(input.postgresId),
];
diff --git a/apps/dokploy/server/api/routers/redis.ts b/apps/dokploy/server/api/routers/redis.ts
index 5883e50b..967fb51a 100644
--- a/apps/dokploy/server/api/routers/redis.ts
+++ b/apps/dokploy/server/api/routers/redis.ts
@@ -244,7 +244,6 @@ export const redisRouter = createTRPCRouter({
message: "You are not authorized to delete this Redis",
});
}
-
const cleanupOperations = [
async () => await removeService(redis?.appName, redis.serverId),
async () => await removeRedisById(input.redisId),
diff --git a/apps/dokploy/server/utils/backup.ts b/apps/dokploy/server/utils/backup.ts
index a178063f..2f141971 100644
--- a/apps/dokploy/server/utils/backup.ts
+++ b/apps/dokploy/server/utils/backup.ts
@@ -1,3 +1,10 @@
+import {
+ type BackupScheduleList,
+ IS_CLOUD,
+ removeScheduleBackup,
+ scheduleBackup,
+} from "@dokploy/server/index";
+
type QueueJob =
| {
type: "backup";
@@ -59,3 +66,19 @@ export const updateJob = async (job: QueueJob) => {
throw error;
}
};
+
+export const cancelJobs = async (backups: BackupScheduleList) => {
+ for (const backup of backups) {
+ if (backup.enabled) {
+ if (IS_CLOUD) {
+ await removeJob({
+ cronSchedule: backup.schedule,
+ backupId: backup.backupId,
+ type: "backup",
+ });
+ } else {
+ removeScheduleBackup(backup.backupId);
+ }
+ }
+ }
+};
diff --git a/apps/dokploy/styles/globals.css b/apps/dokploy/styles/globals.css
index 7b7977b9..74a1d276 100644
--- a/apps/dokploy/styles/globals.css
+++ b/apps/dokploy/styles/globals.css
@@ -4,6 +4,7 @@
@layer base {
:root {
+ --terminal-paste: rgba(0, 0, 0, 0.2);
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
@@ -51,6 +52,7 @@
}
.dark {
+ --terminal-paste: rgba(255, 255, 255, 0.2);
--background: 0 0% 0%;
--foreground: 0 0% 98%;
@@ -235,3 +237,8 @@
background-color: hsl(var(--muted-foreground) / 0.5);
}
}
+
+.xterm-bg-257.xterm-fg-257 {
+ background-color: var(--terminal-paste) !important;
+ color: currentColor !important;
+}
diff --git a/apps/dokploy/templates/alist/docker-compose.yml b/apps/dokploy/templates/alist/docker-compose.yml
new file mode 100644
index 00000000..9ff67c94
--- /dev/null
+++ b/apps/dokploy/templates/alist/docker-compose.yml
@@ -0,0 +1,14 @@
+version: '3.3'
+services:
+ alist:
+ image: xhofe/alist:v3.41.0
+ volumes:
+ - alist-data:/opt/alist/data
+ environment:
+ - PUID=0
+ - PGID=0
+ - UMASK=022
+ restart: unless-stopped
+
+volumes:
+ alist-data:
\ No newline at end of file
diff --git a/apps/dokploy/templates/alist/index.ts b/apps/dokploy/templates/alist/index.ts
new file mode 100644
index 00000000..2a27f570
--- /dev/null
+++ b/apps/dokploy/templates/alist/index.ts
@@ -0,0 +1,22 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const mainDomain = generateRandomDomain(schema);
+
+ const domains: DomainSchema[] = [
+ {
+ host: mainDomain,
+ port: 5244,
+ serviceName: "alist",
+ },
+ ];
+
+ return {
+ domains,
+ };
+}
diff --git a/apps/dokploy/templates/answer/docker-compose.yml b/apps/dokploy/templates/answer/docker-compose.yml
new file mode 100644
index 00000000..e17a6d1e
--- /dev/null
+++ b/apps/dokploy/templates/answer/docker-compose.yml
@@ -0,0 +1,31 @@
+services:
+ answer:
+ image: apache/answer:1.4.1
+ ports:
+ - '80'
+ restart: on-failure
+ volumes:
+ - answer-data:/data
+ depends_on:
+ db:
+ condition: service_healthy
+ db:
+ image: postgres:16
+ restart: always
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+ networks:
+ - dokploy-network
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_DB: answer
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+
+volumes:
+ answer-data:
+ db-data:
diff --git a/apps/dokploy/templates/answer/index.ts b/apps/dokploy/templates/answer/index.ts
new file mode 100644
index 00000000..36d48cb3
--- /dev/null
+++ b/apps/dokploy/templates/answer/index.ts
@@ -0,0 +1,33 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateHash,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const mainServiceHash = generateHash(schema.projectName);
+ const mainDomain = generateRandomDomain(schema);
+
+ const domains: DomainSchema[] = [
+ {
+ host: mainDomain,
+ port: 9080,
+ serviceName: "answer",
+ },
+ ];
+
+ const envs = [
+ `ANSWER_HOST=http://${mainDomain}`,
+ `SERVICE_HASH=${mainServiceHash}`,
+ ];
+
+ const mounts: Template["mounts"] = [];
+
+ return {
+ envs,
+ mounts,
+ domains,
+ };
+}
diff --git a/apps/dokploy/templates/erpnext/docker-compose.yml b/apps/dokploy/templates/erpnext/docker-compose.yml
new file mode 100644
index 00000000..def916be
--- /dev/null
+++ b/apps/dokploy/templates/erpnext/docker-compose.yml
@@ -0,0 +1,346 @@
+x-custom-image: &custom_image
+ image: ${IMAGE_NAME:-docker.io/frappe/erpnext}:${VERSION:-version-15}
+ pull_policy: ${PULL_POLICY:-always}
+ deploy:
+ restart_policy:
+ condition: always
+
+services:
+ backend:
+ <<: *custom_image
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:8000'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+
+ frontend:
+ <<: *custom_image
+ command:
+ - nginx-entrypoint.sh
+ depends_on:
+ backend:
+ condition: service_started
+ required: true
+ websocket:
+ condition: service_started
+ required: true
+ environment:
+ BACKEND: backend:8000
+ FRAPPE_SITE_NAME_HEADER: ${FRAPPE_SITE_NAME_HEADER:-$$host}
+ SOCKETIO: websocket:9000
+ UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
+ UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
+ UPSTREAM_REAL_IP_RECURSIVE: "off"
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+
+ networks:
+ - bench-network
+
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:8080'
+ interval: 2s
+ timeout: 30s
+ retries: 30
+
+ queue-default:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - default
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ queue-long:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - long
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ queue-short:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - short
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ scheduler:
+ <<: *custom_image
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ command:
+ - bench
+ - schedule
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ websocket:
+ <<: *custom_image
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:9000'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ command:
+ - node
+ - /home/frappe/frappe-bench/apps/frappe/socketio.js
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ configurator:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${CONFIGURE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ [[ $${REGENERATE_APPS_TXT} == "1" ]] && ls -1 apps > sites/apps.txt;
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && exit 0;
+ bench set-config -g db_host $$DB_HOST;
+ bench set-config -gp db_port $$DB_PORT;
+ bench set-config -g redis_cache "redis://$$REDIS_CACHE";
+ bench set-config -g redis_queue "redis://$$REDIS_QUEUE";
+ bench set-config -g redis_socketio "redis://$$REDIS_QUEUE";
+ bench set-config -gp socketio_port $$SOCKETIO_PORT;
+ environment:
+ DB_HOST: db
+ DB_PORT: "3306"
+ REDIS_CACHE: redis-cache:6379
+ REDIS_QUEUE: redis-queue:6379
+ SOCKETIO_PORT: "9000"
+ REGENERATE_APPS_TXT: "${REGENERATE_APPS_TXT:-0}"
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ create-site:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${CREATE_SITE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ wait-for-it -t 120 db:3306;
+ wait-for-it -t 120 redis-cache:6379;
+ wait-for-it -t 120 redis-queue:6379;
+ export start=`date +%s`;
+ until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
+ do
+ echo "Waiting for sites/common_site_config.json to be created";
+ sleep 5;
+ if (( `date +%s`-start > 120 )); then
+ echo "could not find sites/common_site_config.json with required keys";
+ exit 1
+ fi
+ done;
+ echo "sites/common_site_config.json found";
+ [[ -d "sites/${SITE_NAME}" ]] && echo "${SITE_NAME} already exists" && exit 0;
+ bench new-site --mariadb-user-host-login-scope='%' --admin-password=$${ADMIN_PASSWORD} --db-root-username=root --db-root-password=$${DB_ROOT_PASSWORD} $${INSTALL_APP_ARGS} $${SITE_NAME};
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ environment:
+ ADMIN_PASSWORD: ${ADMIN_PASSWORD}
+ DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
+ INSTALL_APP_ARGS: ${INSTALL_APP_ARGS}
+ SITE_NAME: ${SITE_NAME}
+ networks:
+ - bench-network
+
+ migration:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${MIGRATE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ curl -f http://${SITE_NAME}:8080/api/method/ping || echo "Site busy" && exit 0;
+ bench --site all set-config -p maintenance_mode 1;
+ bench --site all set-config -p pause_scheduler 1;
+ bench --site all migrate;
+ bench --site all set-config -p maintenance_mode 0;
+ bench --site all set-config -p pause_scheduler 0;
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ db:
+ image: mariadb:10.6
+ deploy:
+ restart_policy:
+ condition: always
+ healthcheck:
+ test: mysqladmin ping -h localhost --password=${DB_ROOT_PASSWORD}
+ interval: 1s
+ retries: 20
+ command:
+ - --character-set-server=utf8mb4
+ - --collation-server=utf8mb4_unicode_ci
+ - --skip-character-set-client-handshake
+ - --skip-innodb-read-only-compressed
+ environment:
+ - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+ - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+ volumes:
+ - db-data:/var/lib/mysql
+ networks:
+ - bench-network
+
+ redis-cache:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-cache-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+ redis-queue:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-queue-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+ redis-socketio:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-socketio-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+volumes:
+ db-data:
+ redis-cache-data:
+ redis-queue-data:
+ redis-socketio-data:
+ sites:
+
+networks:
+ bench-network:
\ No newline at end of file
diff --git a/apps/dokploy/templates/erpnext/index.ts b/apps/dokploy/templates/erpnext/index.ts
new file mode 100644
index 00000000..0be46c44
--- /dev/null
+++ b/apps/dokploy/templates/erpnext/index.ts
@@ -0,0 +1,37 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generatePassword,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const dbRootPassword = generatePassword(32);
+ const adminPassword = generatePassword(32);
+ const mainDomain = generateRandomDomain(schema);
+
+ const domains: DomainSchema[] = [
+ {
+ host: mainDomain,
+ port: 8080,
+ serviceName: "frontend",
+ },
+ ];
+
+ const envs = [
+ `SITE_NAME=${mainDomain}`,
+ `ADMIN_PASSWORD=${adminPassword}`,
+ `DB_ROOT_PASSWORD=${dbRootPassword}`,
+ "MIGRATE=1",
+ "CREATE_SITE=1",
+ "CONFIGURE=1",
+ "REGENERATE_APPS_TXT=1",
+ "INSTALL_APP_ARGS=--install-app erpnext",
+ "IMAGE_NAME=docker.io/frappe/erpnext",
+ "VERSION=version-15",
+ "FRAPPE_SITE_NAME_HEADER=",
+ ];
+
+ return { envs, domains };
+}
diff --git a/apps/dokploy/templates/maybe/docker-compose.yml b/apps/dokploy/templates/maybe/docker-compose.yml
new file mode 100644
index 00000000..017ca29b
--- /dev/null
+++ b/apps/dokploy/templates/maybe/docker-compose.yml
@@ -0,0 +1,37 @@
+services:
+ app:
+ image: ghcr.io/maybe-finance/maybe:sha-68c570eed8810fd59b5b33cca51bbad5eabb4cb4
+ restart: unless-stopped
+ volumes:
+ - ../files/uploads:/app/uploads
+ environment:
+ DATABASE_URL: postgresql://maybe:maybe@db:5432/maybe
+ SECRET_KEY_BASE: ${SECRET_KEY_BASE}
+ SELF_HOSTED: true
+ SYNTH_API_KEY: ${SYNTH_API_KEY}
+ RAILS_FORCE_SSL: "false"
+ RAILS_ASSUME_SSL: "false"
+ GOOD_JOB_EXECUTION_MODE: async
+ depends_on:
+ db:
+ condition: service_healthy
+
+ db:
+ image: postgres:16
+ restart: always
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+ networks:
+ - dokploy-network
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_DB: maybe
+ POSTGRES_USER: maybe
+ POSTGRES_PASSWORD: maybe
+
+volumes:
+ db-data:
diff --git a/apps/dokploy/templates/maybe/index.ts b/apps/dokploy/templates/maybe/index.ts
new file mode 100644
index 00000000..5eaf7a81
--- /dev/null
+++ b/apps/dokploy/templates/maybe/index.ts
@@ -0,0 +1,43 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateBase64,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const mainDomain = generateRandomDomain(schema);
+ const secretKeyBase = generateBase64(64);
+ const synthApiKey = generateBase64(32);
+
+ const domains: DomainSchema[] = [
+ {
+ host: mainDomain,
+ port: 3000,
+ serviceName: "app",
+ },
+ ];
+
+ const envs = [
+ `SECRET_KEY_BASE=${secretKeyBase}`,
+ "SELF_HOSTED=true",
+ `SYNTH_API_KEY=${synthApiKey}`,
+ "RAILS_FORCE_SSL=false",
+ "RAILS_ASSUME_SSL=false",
+ "GOOD_JOB_EXECUTION_MODE=async",
+ ];
+
+ const mounts: Template["mounts"] = [
+ {
+ filePath: "./uploads",
+ content: "This is where user uploads will be stored",
+ },
+ ];
+
+ return {
+ envs,
+ mounts,
+ domains,
+ };
+}
diff --git a/apps/dokploy/templates/spacedrive/docker-compose.yml b/apps/dokploy/templates/spacedrive/docker-compose.yml
new file mode 100644
index 00000000..b98d55ab
--- /dev/null
+++ b/apps/dokploy/templates/spacedrive/docker-compose.yml
@@ -0,0 +1,9 @@
+services:
+ server:
+ image: ghcr.io/spacedriveapp/spacedrive/server:latest
+ ports:
+ - 8080
+ environment:
+ - SD_AUTH=${SD_USERNAME}:${SD_PASSWORD}
+ volumes:
+ - /var/spacedrive:/var/spacedrive
diff --git a/apps/dokploy/templates/spacedrive/index.ts b/apps/dokploy/templates/spacedrive/index.ts
new file mode 100644
index 00000000..15db4b19
--- /dev/null
+++ b/apps/dokploy/templates/spacedrive/index.ts
@@ -0,0 +1,28 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generatePassword,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const randomDomain = generateRandomDomain(schema);
+ const secretKey = generatePassword();
+ const randomUsername = "admin"; // Default username
+
+ const domains: DomainSchema[] = [
+ {
+ host: randomDomain,
+ port: 8080,
+ serviceName: "server",
+ },
+ ];
+
+ const envs = [`SD_USERNAME=${randomUsername}`, `SD_PASSWORD=${secretKey}`];
+
+ return {
+ envs,
+ domains,
+ };
+}
diff --git a/apps/dokploy/templates/superset/docker-compose.yml b/apps/dokploy/templates/superset/docker-compose.yml
index 1766b86b..e3fb3454 100644
--- a/apps/dokploy/templates/superset/docker-compose.yml
+++ b/apps/dokploy/templates/superset/docker-compose.yml
@@ -13,8 +13,11 @@ services:
image: amancevice/superset
restart: always
depends_on:
- - db
- - redis
+ - superset_postgres
+ - superset_redis
+ volumes:
+ # This superset_config.py can be edited in Dokploy's UI Advanced -> Volume Mount
+ - ../files/superset/superset_config.py:/etc/superset/superset_config.py
environment:
SECRET_KEY: ${SECRET_KEY}
MAPBOX_API_KEY: ${MAPBOX_API_KEY}
@@ -22,11 +25,11 @@ services:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
REDIS_PASSWORD: ${REDIS_PASSWORD}
- volumes:
- # Note: superset_config.py can be edited in Dokploy's UI Volume Mount
- - ../files/superset/superset_config.py:/etc/superset/superset_config.py
+ # Ensure the hosts matches your service names below.
+ POSTGRES_HOST: superset_postgres
+ REDIS_HOST: superset_redis
- db:
+ superset_postgres:
image: postgres
restart: always
environment:
@@ -34,7 +37,7 @@ services:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- - postgres:/var/lib/postgresql/data
+ - superset_postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 30s
@@ -43,11 +46,11 @@ services:
networks:
- dokploy-network
- redis:
+ superset_redis:
image: redis
restart: always
volumes:
- - redis:/data
+ - superset_redis_data:/data
command: redis-server --requirepass ${REDIS_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
@@ -58,5 +61,5 @@ services:
- dokploy-network
volumes:
- postgres:
- redis:
+ superset_postgres_data:
+ superset_redis_data:
diff --git a/apps/dokploy/templates/superset/index.ts b/apps/dokploy/templates/superset/index.ts
index 6132f978..4994b639 100644
--- a/apps/dokploy/templates/superset/index.ts
+++ b/apps/dokploy/templates/superset/index.ts
@@ -47,13 +47,13 @@ CACHE_CONFIG = {
"CACHE_REDIS_HOST": "redis",
"CACHE_REDIS_PORT": 6379,
"CACHE_REDIS_DB": 1,
- "CACHE_REDIS_URL": f"redis://:{os.getenv('REDIS_PASSWORD')}@redis:6379/1",
+ "CACHE_REDIS_URL": f"redis://:{os.getenv('REDIS_PASSWORD')}@{os.getenv('REDIS_HOST')}:6379/1",
}
FILTER_STATE_CACHE_CONFIG = {**CACHE_CONFIG, "CACHE_KEY_PREFIX": "superset_filter_"}
EXPLORE_FORM_DATA_CACHE_CONFIG = {**CACHE_CONFIG, "CACHE_KEY_PREFIX": "superset_explore_form_"}
-SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{os.getenv('POSTGRES_USER')}:{os.getenv('POSTGRES_PASSWORD')}@db:5432/{os.getenv('POSTGRES_DB')}"
+SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{os.getenv('POSTGRES_USER')}:{os.getenv('POSTGRES_PASSWORD')}@{os.getenv('POSTGRES_HOST')}:5432/{os.getenv('POSTGRES_DB')}"
SQLALCHEMY_TRACK_MODIFICATIONS = True
`.trim(),
},
diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts
index 1bdb1ec1..7ba3829f 100644
--- a/apps/dokploy/templates/templates.ts
+++ b/apps/dokploy/templates/templates.ts
@@ -538,7 +538,7 @@ export const templates: TemplateData[] = [
website: "https://filebrowser.org/",
docs: "https://filebrowser.org/",
},
- tags: ["file", "manager"],
+ tags: ["file-manager", "storage"],
load: () => import("./filebrowser/index").then((m) => m.generate),
},
{
@@ -834,7 +834,7 @@ export const templates: TemplateData[] = [
website: "https://nextcloud.com/",
docs: "https://docs.nextcloud.com/",
},
- tags: ["file", "sync"],
+ tags: ["file-manager", "sync"],
load: () => import("./nextcloud-aio/index").then((m) => m.generate),
},
{
@@ -1341,4 +1341,86 @@ export const templates: TemplateData[] = [
tags: ["dashboard", "monitoring"],
load: () => import("./homarr/index").then((m) => m.generate),
},
+ {
+ id: "erpnext",
+ name: "ERPNext",
+ version: "version-15",
+ description: "100% Open Source and highly customizable ERP software.",
+ logo: "erpnext.svg",
+ links: {
+ github: "https://github.com/frappe/erpnext",
+ docs: "https://docs.frappe.io/erpnext",
+ website: "https://erpnext.com",
+ },
+ tags: [
+ "erp",
+ "accounts",
+ "manufacturing",
+ "retail",
+ "sales",
+ "pos",
+ "hrms",
+ ],
+ load: () => import("./erpnext/index").then((m) => m.generate),
+ },
+ {
+ id: "maybe",
+ name: "Maybe",
+ version: "latest",
+ description:
+ "Maybe is a self-hosted finance tracking application designed to simplify budgeting and expenses.",
+ logo: "maybe.svg",
+ links: {
+ github: "https://github.com/maybe-finance/maybe",
+ website: "https://maybe.finance/",
+ docs: "https://docs.maybe.finance/",
+ },
+ tags: ["finance", "self-hosted"],
+ load: () => import("./maybe/index").then((m) => m.generate),
+ },
+ {
+ id: "spacedrive",
+ name: "Spacedrive",
+ version: "latest",
+ description:
+ "Spacedrive is a cross-platform file manager. It connects your devices together to help you organize files from anywhere. powered by a virtual distributed filesystem (VDFS) written in Rust. Organize files across many devices in one place.",
+ links: {
+ github: "https://github.com/spacedriveapp/spacedrive",
+ website: "https://spacedrive.com/",
+ docs: "https://www.spacedrive.com/docs/product/getting-started/introduction",
+ },
+ logo: "spacedrive.png",
+ tags: ["file-manager", "vdfs", "storage"],
+ load: () => import("./spacedrive/index").then((m) => m.generate),
+ },
+ {
+ id: "alist",
+ name: "AList",
+ version: "v3.41.0",
+ description:
+ "🗂️A file list/WebDAV program that supports multiple storages, powered by Gin and Solidjs.",
+ logo: "alist.svg",
+ links: {
+ github: "https://github.com/AlistGo/alist",
+ website: "https://alist.nn.ci",
+ docs: "https://alist.nn.ci/guide/install/docker.html",
+ },
+ tags: ["file", "webdav", "storage"],
+ load: () => import("./alist/index").then((m) => m.generate),
+ },
+ {
+ id: "answer",
+ name: "Answer",
+ version: "v1.4.1",
+ description:
+ "Answer is an open-source Q&A platform for building a self-hosted question-and-answer service.",
+ logo: "answer.png",
+ links: {
+ github: "https://github.com/apache/answer",
+ website: "https://answer.apache.org/",
+ docs: "https://answer.apache.org/docs",
+ },
+ tags: ["q&a", "self-hosted"],
+ load: () => import("./answer/index").then((m) => m.generate),
+ },
];
diff --git a/packages/server/src/services/application.ts b/packages/server/src/services/application.ts
index 4c194e0f..da1b50af 100644
--- a/packages/server/src/services/application.ts
+++ b/packages/server/src/services/application.ts
@@ -451,7 +451,7 @@ export const deployPreviewApplication = async ({
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
});
application.appName = previewDeployment.appName;
- application.env = application.previewEnv;
+ application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain}`;
application.buildArgs = application.previewBuildArgs;
const admin = await findAdminById(application.project.adminId);
@@ -564,7 +564,7 @@ export const deployRemotePreviewApplication = async ({
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
});
application.appName = previewDeployment.appName;
- application.env = application.previewEnv;
+ application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain}`;
application.buildArgs = application.previewBuildArgs;
if (application.serverId) {
diff --git a/packages/server/src/services/backup.ts b/packages/server/src/services/backup.ts
index 70e37af4..ef3d0446 100644
--- a/packages/server/src/services/backup.ts
+++ b/packages/server/src/services/backup.ts
@@ -2,11 +2,13 @@ import { db } from "@dokploy/server/db";
import { type apiCreateBackup, backups } from "@dokploy/server/db/schema";
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
+import { IS_CLOUD } from "../constants";
+import { removeScheduleBackup, scheduleBackup } from "../utils/backups/utils";
export type Backup = typeof backups.$inferSelect;
export type BackupSchedule = Awaited>;
-
+export type BackupScheduleList = Awaited>;
export const createBackup = async (input: typeof apiCreateBackup._type) => {
const newBackup = await db
.insert(backups)
@@ -69,3 +71,20 @@ export const removeBackupById = async (backupId: string) => {
return result[0];
};
+
+export const findBackupsByDbId = async (
+ id: string,
+ type: "postgres" | "mysql" | "mariadb" | "mongo",
+) => {
+ const result = await db.query.backups.findMany({
+ where: eq(backups[`${type}Id`], id),
+ with: {
+ postgres: true,
+ mysql: true,
+ mariadb: true,
+ mongo: true,
+ destination: true,
+ },
+ });
+ return result || [];
+};
diff --git a/packages/server/src/services/settings.ts b/packages/server/src/services/settings.ts
index d22780c9..d37793ea 100644
--- a/packages/server/src/services/settings.ts
+++ b/packages/server/src/services/settings.ts
@@ -216,8 +216,8 @@ echo "$json_output"
};
export const cleanupFullDocker = async (serverId?: string | null) => {
- const cleanupImages = "docker image prune --all --force";
- const cleanupVolumes = "docker volume prune --all --force";
+ const cleanupImages = "docker image prune --force";
+ const cleanupVolumes = "docker volume prune --force";
const cleanupContainers = "docker container prune --force";
const cleanupSystem = "docker system prune --all --force --volumes";
const cleanupBuilder = "docker builder prune --all --force";
diff --git a/packages/server/src/setup/traefik-setup.ts b/packages/server/src/setup/traefik-setup.ts
index 270a4447..6a2a0133 100644
--- a/packages/server/src/setup/traefik-setup.ts
+++ b/packages/server/src/setup/traefik-setup.ts
@@ -189,10 +189,12 @@ export const getDefaultTraefikConfig = () => {
: {
swarm: {
exposedByDefault: false,
- watch: false,
+ watch: true,
},
docker: {
exposedByDefault: false,
+ watch: true,
+ network: "dokploy-network",
},
}),
file: {
@@ -243,10 +245,12 @@ export const getDefaultServerTraefikConfig = () => {
providers: {
swarm: {
exposedByDefault: false,
- watch: false,
+ watch: true,
},
docker: {
exposedByDefault: false,
+ watch: true,
+ network: "dokploy-network",
},
file: {
directory: "/etc/dokploy/traefik/dynamic",
diff --git a/packages/server/src/utils/docker/utils.ts b/packages/server/src/utils/docker/utils.ts
index 654d8330..64e98306 100644
--- a/packages/server/src/utils/docker/utils.ts
+++ b/packages/server/src/utils/docker/utils.ts
@@ -144,10 +144,11 @@ export const getContainerByName = (name: string): Promise => {
};
export const cleanUpUnusedImages = async (serverId?: string) => {
try {
+ const command = "docker image prune --force";
if (serverId) {
- await execAsyncRemote(serverId, "docker image prune --all --force");
+ await execAsyncRemote(serverId, command);
} else {
- await execAsync("docker image prune --all --force");
+ await execAsync(command);
}
} catch (error) {
console.error(error);
@@ -157,10 +158,11 @@ export const cleanUpUnusedImages = async (serverId?: string) => {
export const cleanStoppedContainers = async (serverId?: string) => {
try {
+ const command = "docker container prune --force";
if (serverId) {
- await execAsyncRemote(serverId, "docker container prune --force");
+ await execAsyncRemote(serverId, command);
} else {
- await execAsync("docker container prune --force");
+ await execAsync(command);
}
} catch (error) {
console.error(error);
@@ -170,10 +172,11 @@ export const cleanStoppedContainers = async (serverId?: string) => {
export const cleanUpUnusedVolumes = async (serverId?: string) => {
try {
+ const command = "docker volume prune --force";
if (serverId) {
- await execAsyncRemote(serverId, "docker volume prune --all --force");
+ await execAsyncRemote(serverId, command);
} else {
- await execAsync("docker volume prune --all --force");
+ await execAsync(command);
}
} catch (error) {
console.error(error);
@@ -199,21 +202,20 @@ export const cleanUpInactiveContainers = async () => {
};
export const cleanUpDockerBuilder = async (serverId?: string) => {
+ const command = "docker builder prune --all --force";
if (serverId) {
- await execAsyncRemote(serverId, "docker builder prune --all --force");
+ await execAsyncRemote(serverId, command);
} else {
- await execAsync("docker builder prune --all --force");
+ await execAsync(command);
}
};
export const cleanUpSystemPrune = async (serverId?: string) => {
+ const command = "docker system prune --all --force --volumes";
if (serverId) {
- await execAsyncRemote(
- serverId,
- "docker system prune --all --force --volumes",
- );
+ await execAsyncRemote(serverId, command);
} else {
- await execAsync("docker system prune --all --force --volumes");
+ await execAsync(command);
}
};
diff --git a/packages/server/src/utils/providers/git.ts b/packages/server/src/utils/providers/git.ts
index 6377b557..8f8a3830 100644
--- a/packages/server/src/utils/providers/git.ts
+++ b/packages/server/src/utils/providers/git.ts
@@ -69,6 +69,7 @@ export const cloneGitRepository = async (
});
}
+ const { port } = sanitizeRepoPathSSH(customGitUrl);
await spawnAsync(
"git",
[
@@ -91,7 +92,7 @@ export const cloneGitRepository = async (
env: {
...process.env,
...(customGitSSHKeyId && {
- GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath} -o UserKnownHostsFile=${knownHostsPath}`,
+ GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath}${port ? ` -p ${port}` : ""} -o UserKnownHostsFile=${knownHostsPath}`,
}),
},
},
@@ -168,7 +169,8 @@ export const getCustomGitCloneCommand = async (
);
if (customGitSSHKeyId) {
const sshKey = await findSSHKeyById(customGitSSHKeyId);
- const gitSshCommand = `ssh -i /tmp/id_rsa -o UserKnownHostsFile=${knownHostsPath}`;
+ const { port } = sanitizeRepoPathSSH(customGitUrl);
+ const gitSshCommand = `ssh -i /tmp/id_rsa${port ? ` -p ${port}` : ""} -o UserKnownHostsFile=${knownHostsPath}`;
command.push(
`
echo "${sshKey.privateKey}" > /tmp/id_rsa
@@ -304,6 +306,7 @@ export const cloneGitRawRepository = async (entity: {
});
}
+ const { port } = sanitizeRepoPathSSH(customGitUrl);
await spawnAsync(
"git",
[
@@ -322,7 +325,7 @@ export const cloneGitRawRepository = async (entity: {
env: {
...process.env,
...(customGitSSHKeyId && {
- GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath} -o UserKnownHostsFile=${knownHostsPath}`,
+ GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath}${port ? ` -p ${port}` : ""} -o UserKnownHostsFile=${knownHostsPath}`,
}),
},
},
@@ -381,7 +384,8 @@ export const cloneRawGitRepositoryRemote = async (compose: Compose) => {
command.push(`mkdir -p ${outputPath};`);
if (customGitSSHKeyId) {
const sshKey = await findSSHKeyById(customGitSSHKeyId);
- const gitSshCommand = `ssh -i /tmp/id_rsa -o UserKnownHostsFile=${knownHostsPath}`;
+ const { port } = sanitizeRepoPathSSH(customGitUrl);
+ const gitSshCommand = `ssh -i /tmp/id_rsa${port ? ` -p ${port}` : ""} -o UserKnownHostsFile=${knownHostsPath}`;
command.push(
`
echo "${sshKey.privateKey}" > /tmp/id_rsa
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6341be34..6f2cd6bc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -124,6 +124,12 @@ importers:
'@hookform/resolvers':
specifier: ^3.3.4
version: 3.9.0(react-hook-form@7.52.1(react@18.2.0))
+ '@lucia-auth/adapter-drizzle':
+ specifier: 1.0.7
+ version: 1.0.7(lucia@3.2.0)
+ '@octokit/auth-app':
+ specifier: ^6.0.4
+ version: 6.1.1
'@octokit/webhooks':
specifier: ^13.2.7
version: 13.3.0
@@ -184,6 +190,9 @@ importers:
'@radix-ui/react-tooltip':
specifier: ^1.0.7
version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@react-email/components':
+ specifier: ^0.0.21
+ version: 0.0.21(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
'@stepperize/react':
specifier: 4.0.1
version: 4.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -217,6 +226,9 @@ importers:
'@xterm/addon-attach':
specifier: 0.10.0
version: 0.10.0(@xterm/xterm@5.5.0)
+ '@xterm/addon-clipboard':
+ specifier: 0.1.0
+ version: 0.1.0(@xterm/xterm@5.5.0)
'@xterm/xterm':
specifier: ^5.4.0
version: 5.5.0
@@ -226,6 +238,12 @@ importers:
bcrypt:
specifier: 5.1.1
version: 5.1.1
+ bl:
+ specifier: 6.0.11
+ version: 6.0.11
+ boxen:
+ specifier: ^7.1.1
+ version: 7.1.1
bullmq:
specifier: 5.4.2
version: 5.4.2
@@ -247,6 +265,9 @@ importers:
date-fns:
specifier: 3.6.0
version: 3.6.0
+ dockerode:
+ specifier: 4.0.2
+ version: 4.0.2
dotenv:
specifier: 16.4.5
version: 16.4.5
@@ -259,6 +280,9 @@ importers:
fancy-ansi:
specifier: ^0.1.3
version: 0.1.3
+ hi-base32:
+ specifier: ^0.5.1
+ version: 0.5.1
i18next:
specifier: ^23.16.4
version: 23.16.5
@@ -292,21 +316,33 @@ importers:
next-themes:
specifier: ^0.2.1
version: 0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ node-os-utils:
+ specifier: 1.3.7
+ version: 1.3.7
node-pty:
specifier: 1.0.0
version: 1.0.0
node-schedule:
specifier: 2.1.1
version: 2.1.1
+ nodemailer:
+ specifier: 6.9.14
+ version: 6.9.14
octokit:
specifier: 3.1.2
version: 3.1.2
+ otpauth:
+ specifier: ^9.2.3
+ version: 9.3.4
postgres:
specifier: 3.4.4
version: 3.4.4
public-ip:
specifier: 6.0.2
version: 6.0.2
+ qrcode:
+ specifier: ^1.5.3
+ version: 1.5.4
react:
specifier: 18.2.0
version: 18.2.0
@@ -325,6 +361,9 @@ importers:
recharts:
specifier: ^2.12.7
version: 2.12.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ rotating-file-stream:
+ specifier: 3.2.3
+ version: 3.2.3
slugify:
specifier: ^1.6.6
version: 1.6.6
@@ -386,9 +425,18 @@ importers:
'@types/node':
specifier: ^18.17.0
version: 18.19.42
+ '@types/node-os-utils':
+ specifier: 1.3.4
+ version: 1.3.4
'@types/node-schedule':
specifier: 2.1.6
version: 2.1.6
+ '@types/nodemailer':
+ specifier: ^6.4.15
+ version: 6.4.16
+ '@types/qrcode':
+ specifier: ^1.5.5
+ version: 1.5.5
'@types/react':
specifier: 18.3.5
version: 18.3.5
@@ -3503,6 +3551,11 @@ packages:
peerDependencies:
'@xterm/xterm': ^5.0.0
+ '@xterm/addon-clipboard@0.1.0':
+ resolution: {integrity: sha512-zdoM7p53T5sv/HbRTyp4hY0kKmEQ3MZvAvEtiXqNIHc/JdpqwByCtsTaQF5DX2n4hYdXRPO4P/eOS0QEhX1nPw==}
+ peerDependencies:
+ '@xterm/xterm': ^5.4.0
+
'@xterm/xterm@5.5.0':
resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==}
@@ -5011,6 +5064,9 @@ packages:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
+ js-base64@3.7.7:
+ resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
+
js-beautify@1.15.1:
resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==}
engines: {node: '>=14'}
@@ -9894,6 +9950,11 @@ snapshots:
dependencies:
'@xterm/xterm': 5.5.0
+ '@xterm/addon-clipboard@0.1.0(@xterm/xterm@5.5.0)':
+ dependencies:
+ '@xterm/xterm': 5.5.0
+ js-base64: 3.7.7
+
'@xterm/xterm@5.5.0': {}
'@xtuc/ieee754@1.2.0': {}
@@ -11410,6 +11471,8 @@ snapshots:
joycon@3.1.1: {}
+ js-base64@3.7.7: {}
+
js-beautify@1.15.1:
dependencies:
config-chain: 1.1.13