mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-03 21:15:23 +02:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e79f8c4b72 | ||
|
|
26e2a24f63 | ||
|
|
830feabd70 | ||
|
|
122a3d110d | ||
|
|
c05edb313f | ||
|
|
1ec2853862 | ||
|
|
5c2709248c | ||
|
|
bc79074441 | ||
|
|
5ada451916 | ||
|
|
6b0d9240dd | ||
|
|
499022a328 | ||
|
|
2a89be6efc | ||
|
|
412bb9e874 | ||
|
|
6290c217f1 | ||
|
|
4babdd45ea | ||
|
|
24bff96898 |
@@ -99,6 +99,10 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
|
|||||||
<img src=".github/sponsors/american-cloud.png" alt="AmericanCloud" height="70"/>
|
<img src=".github/sponsors/american-cloud.png" alt="AmericanCloud" height="70"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a href="https://tolgee.io/?utm_source=github_dokploy&utm_medium=banner&utm_campaign=dokploy" target="_blank" style="display: inline-block; margin-right: 10px;">
|
||||||
|
<img src="https://dokploy.com/tolgee-logo.png" alt="Tolgee" height="80"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Elite Contributors 🥈 -->
|
<!-- Elite Contributors 🥈 -->
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -79,6 +80,11 @@ export const ShowRollbackSettings = ({ applicationId, children }: Props) => {
|
|||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
Configure how rollbacks work for this application
|
Configure how rollbacks work for this application
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
|
<AlertBlock>
|
||||||
|
Having rollbacks enabled increases storage usage. Be careful with
|
||||||
|
this option. Note that manually cleaning the cache may delete
|
||||||
|
rollback images, making them unavailable for future rollbacks.
|
||||||
|
</AlertBlock>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dokploy",
|
"name": "dokploy",
|
||||||
"version": "v0.23.2",
|
"version": "v0.23.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -4,24 +4,24 @@ import { users_temp } from "@dokploy/server/db/schema";
|
|||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const result = await findAdmin();
|
const result = await findAdmin();
|
||||||
|
|
||||||
const update = await db
|
const update = await db
|
||||||
.update(users_temp)
|
.update(users_temp)
|
||||||
.set({
|
.set({
|
||||||
twoFactorEnabled: false,
|
twoFactorEnabled: false,
|
||||||
})
|
})
|
||||||
.where(eq(users_temp.id, result.userId));
|
.where(eq(users_temp.id, result.userId));
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
console.log("2FA reset successful");
|
console.log("2FA reset successful");
|
||||||
} else {
|
} else {
|
||||||
console.log("Password reset failed");
|
console.log("Password reset failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error resetting 2FA", error);
|
console.log("Error resetting 2FA", error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -837,6 +837,14 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
getLogCleanupStatus: adminProcedure.query(async () => {
|
getLogCleanupStatus: adminProcedure.query(async () => {
|
||||||
return getLogCleanupStatus();
|
return getLogCleanupStatus();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
getDokployCloudIps: adminProcedure.query(async () => {
|
||||||
|
if (!IS_CLOUD) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const ips = process.env.DOKPLOY_CLOUD_IPS?.split(",");
|
||||||
|
return ips;
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getTraefikPorts = async (serverId?: string) => {
|
export const getTraefikPorts = async (serverId?: string) => {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { createInsertSchema } from "drizzle-zod";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { deployments } from "./deployment";
|
import { deployments } from "./deployment";
|
||||||
|
import type { Application } from "@dokploy/server/services/application";
|
||||||
|
import type { Project } from "@dokploy/server/services/project";
|
||||||
|
|
||||||
export const rollbacks = pgTable("rollback", {
|
export const rollbacks = pgTable("rollback", {
|
||||||
rollbackId: text("rollbackId")
|
rollbackId: text("rollbackId")
|
||||||
@@ -20,7 +22,7 @@ export const rollbacks = pgTable("rollback", {
|
|||||||
createdAt: text("createdAt")
|
createdAt: text("createdAt")
|
||||||
.notNull()
|
.notNull()
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
.$defaultFn(() => new Date().toISOString()),
|
||||||
fullContext: jsonb("fullContext"),
|
fullContext: jsonb("fullContext").$type<Application & { project: Project }>(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Rollback = typeof rollbacks.$inferSelect;
|
export type Rollback = typeof rollbacks.$inferSelect;
|
||||||
|
|||||||
@@ -12,14 +12,16 @@ import type { ApplicationNested } from "../utils/builders";
|
|||||||
import { execAsync, execAsyncRemote } from "../utils/process/execAsync";
|
import { execAsync, execAsyncRemote } from "../utils/process/execAsync";
|
||||||
import type { CreateServiceOptions } from "dockerode";
|
import type { CreateServiceOptions } from "dockerode";
|
||||||
import { findDeploymentById } from "./deployment";
|
import { findDeploymentById } from "./deployment";
|
||||||
|
import { prepareEnvironmentVariables } from "../utils/docker/utils";
|
||||||
|
|
||||||
export const createRollback = async (
|
export const createRollback = async (
|
||||||
input: z.infer<typeof createRollbackSchema>,
|
input: z.infer<typeof createRollbackSchema>,
|
||||||
) => {
|
) => {
|
||||||
await db.transaction(async (tx) => {
|
await db.transaction(async (tx) => {
|
||||||
|
const { fullContext, ...other } = input;
|
||||||
const rollback = await tx
|
const rollback = await tx
|
||||||
.insert(rollbacks)
|
.insert(rollbacks)
|
||||||
.values(input)
|
.values(other)
|
||||||
.returning()
|
.returning()
|
||||||
.then((res) => res[0]);
|
.then((res) => res[0]);
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ export const createRollback = async (
|
|||||||
.update(rollbacks)
|
.update(rollbacks)
|
||||||
.set({
|
.set({
|
||||||
image: tagImage,
|
image: tagImage,
|
||||||
fullContext: JSON.stringify(rest),
|
fullContext: rest,
|
||||||
})
|
})
|
||||||
.where(eq(rollbacks.rollbackId, rollback.rollbackId));
|
.where(eq(rollbacks.rollbackId, rollback.rollbackId));
|
||||||
|
|
||||||
@@ -150,10 +152,16 @@ export const rollback = async (rollbackId: string) => {
|
|||||||
|
|
||||||
const application = await findApplicationById(deployment.applicationId);
|
const application = await findApplicationById(deployment.applicationId);
|
||||||
|
|
||||||
|
const envVariables = prepareEnvironmentVariables(
|
||||||
|
result?.fullContext?.env || "",
|
||||||
|
result.fullContext?.project?.env || "",
|
||||||
|
);
|
||||||
|
|
||||||
await rollbackApplication(
|
await rollbackApplication(
|
||||||
application.appName,
|
application.appName,
|
||||||
result.image || "",
|
result.image || "",
|
||||||
application.serverId,
|
application.serverId,
|
||||||
|
envVariables,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -161,6 +169,7 @@ const rollbackApplication = async (
|
|||||||
appName: string,
|
appName: string,
|
||||||
image: string,
|
image: string,
|
||||||
serverId?: string | null,
|
serverId?: string | null,
|
||||||
|
env: string[] = [],
|
||||||
) => {
|
) => {
|
||||||
const docker = await getRemoteDocker(serverId);
|
const docker = await getRemoteDocker(serverId);
|
||||||
|
|
||||||
@@ -169,6 +178,7 @@ const rollbackApplication = async (
|
|||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
ContainerSpec: {
|
ContainerSpec: {
|
||||||
Image: image,
|
Image: image,
|
||||||
|
Env: env,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const runComposeBackup = async (
|
|||||||
) => {
|
) => {
|
||||||
const { projectId, name } = compose;
|
const { projectId, name } = compose;
|
||||||
const project = await findProjectById(projectId);
|
const project = await findProjectById(projectId);
|
||||||
const { prefix } = backup;
|
const { prefix, databaseType } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.dump.gz`;
|
const backupFileName = `${new Date().toISOString()}.dump.gz`;
|
||||||
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
@@ -46,9 +46,10 @@ export const runComposeBackup = async (
|
|||||||
await sendDatabaseBackupNotifications({
|
await sendDatabaseBackupNotifications({
|
||||||
applicationName: name,
|
applicationName: name,
|
||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
databaseType: "mongodb",
|
databaseType: getDatabaseType(databaseType),
|
||||||
type: "success",
|
type: "success",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
@@ -57,14 +58,31 @@ export const runComposeBackup = async (
|
|||||||
await sendDatabaseBackupNotifications({
|
await sendDatabaseBackupNotifications({
|
||||||
applicationName: name,
|
applicationName: name,
|
||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
databaseType: "mongodb",
|
databaseType: getDatabaseType(databaseType),
|
||||||
type: "error",
|
type: "error",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDatabaseType = (databaseType: BackupSchedule["databaseType"]) => {
|
||||||
|
if (databaseType === "mongo") {
|
||||||
|
return "mongodb";
|
||||||
|
}
|
||||||
|
if (databaseType === "postgres") {
|
||||||
|
return "postgres";
|
||||||
|
}
|
||||||
|
if (databaseType === "mariadb") {
|
||||||
|
return "mariadb";
|
||||||
|
}
|
||||||
|
if (databaseType === "mysql") {
|
||||||
|
return "mysql";
|
||||||
|
}
|
||||||
|
return "mongodb";
|
||||||
|
};
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export const runMariadbBackup = async (
|
|||||||
databaseType: "mariadb",
|
databaseType: "mariadb",
|
||||||
type: "success",
|
type: "success",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -60,6 +61,7 @@ export const runMariadbBackup = async (
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
|||||||
databaseType: "mongodb",
|
databaseType: "mongodb",
|
||||||
type: "success",
|
type: "success",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -58,6 +59,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
|||||||
databaseType: "mysql",
|
databaseType: "mysql",
|
||||||
type: "success",
|
type: "success",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -59,6 +60,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export const runPostgresBackup = async (
|
|||||||
databaseType: "postgres",
|
databaseType: "postgres",
|
||||||
type: "success",
|
type: "success",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
@@ -62,6 +63,7 @@ export const runPostgresBackup = async (
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
|
databaseName: backup.database,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { createWriteStream } from "node:fs";
|
import { createWriteStream } from "node:fs";
|
||||||
import { join } from "node:path";
|
|
||||||
import type { InferResultType } from "@dokploy/server/types/with";
|
import type { InferResultType } from "@dokploy/server/types/with";
|
||||||
import type { CreateServiceOptions } from "dockerode";
|
import type { CreateServiceOptions } from "dockerode";
|
||||||
import { uploadImage, uploadImageRemoteCommand } from "../cluster/upload";
|
import { uploadImage, uploadImageRemoteCommand } from "../cluster/upload";
|
||||||
@@ -211,16 +210,20 @@ export const mechanizeDockerContainer = async (
|
|||||||
|
|
||||||
const getImageName = (application: ApplicationNested) => {
|
const getImageName = (application: ApplicationNested) => {
|
||||||
const { appName, sourceType, dockerImage, registry } = application;
|
const { appName, sourceType, dockerImage, registry } = application;
|
||||||
|
const imageName = `${appName}:latest`;
|
||||||
if (sourceType === "docker") {
|
if (sourceType === "docker") {
|
||||||
return dockerImage || "ERROR-NO-IMAGE-PROVIDED";
|
return dockerImage || "ERROR-NO-IMAGE-PROVIDED";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registry) {
|
if (registry) {
|
||||||
return join(registry.registryUrl, registry.imagePrefix || "", appName);
|
const { registryUrl, imagePrefix, username } = registry;
|
||||||
|
const registryTag = imagePrefix
|
||||||
|
? `${registryUrl}/${imagePrefix}/${imageName}`
|
||||||
|
: `${registryUrl}/${username}/${imageName}`;
|
||||||
|
return registryTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${appName}:latest`;
|
return imageName;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAuthConfig = (application: ApplicationNested) => {
|
const getAuthConfig = (application: ApplicationNested) => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { WriteStream } from "node:fs";
|
import type { WriteStream } from "node:fs";
|
||||||
import path, { join } from "node:path";
|
|
||||||
import type { ApplicationNested } from "../builders";
|
import type { ApplicationNested } from "../builders";
|
||||||
import { spawnAsync } from "../process/spawnAsync";
|
import { spawnAsync } from "../process/spawnAsync";
|
||||||
|
|
||||||
@@ -13,19 +12,22 @@ export const uploadImage = async (
|
|||||||
throw new Error("Registry not found");
|
throw new Error("Registry not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const { registryUrl, imagePrefix } = registry;
|
const { registryUrl, imagePrefix, username } = registry;
|
||||||
const { appName } = application;
|
const { appName } = application;
|
||||||
const imageName = `${appName}:latest`;
|
const imageName = `${appName}:latest`;
|
||||||
|
|
||||||
const finalURL = registryUrl;
|
const finalURL = registryUrl;
|
||||||
|
|
||||||
const registryTag = path
|
// Build registry tag in correct format: registry.com/owner/image:tag
|
||||||
.join(registryUrl, join(imagePrefix || "", imageName))
|
// For ghcr.io: ghcr.io/username/image:tag
|
||||||
.replace(/\/+/g, "/");
|
// For docker.io: docker.io/username/image:tag
|
||||||
|
const registryTag = imagePrefix
|
||||||
|
? `${registryUrl}/${imagePrefix}/${imageName}`
|
||||||
|
: `${registryUrl}/${username}/${imageName}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
writeStream.write(
|
writeStream.write(
|
||||||
`📦 [Enabled Registry] Uploading image to ${registry.registryType} | ${imageName} | ${finalURL}\n`,
|
`📦 [Enabled Registry] Uploading image to ${registry.registryType} | ${imageName} | ${finalURL} | ${registryTag}\n`,
|
||||||
);
|
);
|
||||||
const loginCommand = spawnAsync(
|
const loginCommand = spawnAsync(
|
||||||
"docker",
|
"docker",
|
||||||
@@ -67,15 +69,16 @@ export const uploadImageRemoteCommand = (
|
|||||||
throw new Error("Registry not found");
|
throw new Error("Registry not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const { registryUrl, imagePrefix } = registry;
|
const { registryUrl, imagePrefix, username } = registry;
|
||||||
const { appName } = application;
|
const { appName } = application;
|
||||||
const imageName = `${appName}:latest`;
|
const imageName = `${appName}:latest`;
|
||||||
|
|
||||||
const finalURL = registryUrl;
|
const finalURL = registryUrl;
|
||||||
|
|
||||||
const registryTag = path
|
// Build registry tag in correct format: registry.com/owner/image:tag
|
||||||
.join(registryUrl, join(imagePrefix || "", imageName))
|
const registryTag = imagePrefix
|
||||||
.replace(/\/+/g, "/");
|
? `${registryUrl}/${imagePrefix}/${imageName}`
|
||||||
|
: `${registryUrl}/${username}/${imageName}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const command = `
|
const command = `
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
type,
|
type,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
organizationId,
|
organizationId,
|
||||||
|
databaseName,
|
||||||
}: {
|
}: {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
applicationName: string;
|
applicationName: string;
|
||||||
@@ -26,6 +27,7 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
type: "error" | "success";
|
type: "error" | "success";
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
|
databaseName: string;
|
||||||
}) => {
|
}) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const unixDate = ~~(Number(date) / 1000);
|
const unixDate = ~~(Number(date) / 1000);
|
||||||
@@ -90,6 +92,11 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
value: databaseType,
|
value: databaseType,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: decorate("`📂`", "Database Name"),
|
||||||
|
value: databaseName,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: decorate("`📅`", "Date"),
|
name: decorate("`📅`", "Date"),
|
||||||
value: `<t:${unixDate}:D>`,
|
value: `<t:${unixDate}:D>`,
|
||||||
@@ -136,6 +143,7 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
`${decorate("🛠️", `Project: ${projectName}`)}` +
|
`${decorate("🛠️", `Project: ${projectName}`)}` +
|
||||||
`${decorate("⚙️", `Application: ${applicationName}`)}` +
|
`${decorate("⚙️", `Application: ${applicationName}`)}` +
|
||||||
`${decorate("❔", `Type: ${databaseType}`)}` +
|
`${decorate("❔", `Type: ${databaseType}`)}` +
|
||||||
|
`${decorate("📂", `Database Name: ${databaseName}`)}` +
|
||||||
`${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
|
`${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
|
||||||
`${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`,
|
`${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`,
|
||||||
);
|
);
|
||||||
@@ -150,7 +158,7 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
? `\n\n<b>Error:</b>\n<pre>${errorMessage}</pre>`
|
? `\n\n<b>Error:</b>\n<pre>${errorMessage}</pre>`
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
const messageText = `<b>${statusEmoji} Database Backup ${typeStatus}</b>\n\n<b>Project:</b> ${projectName}\n<b>Application:</b> ${applicationName}\n<b>Type:</b> ${databaseType}\n<b>Date:</b> ${format(date, "PP")}\n<b>Time:</b> ${format(date, "pp")}${isError ? errorMsg : ""}`;
|
const messageText = `<b>${statusEmoji} Database Backup ${typeStatus}</b>\n\n<b>Project:</b> ${projectName}\n<b>Application:</b> ${applicationName}\n<b>Type:</b> ${databaseType}\n<b>Database Name:</b> ${databaseName}\n<b>Date:</b> ${format(date, "PP")}\n<b>Time:</b> ${format(date, "pp")}${isError ? errorMsg : ""}`;
|
||||||
|
|
||||||
await sendTelegramNotification(telegram, messageText);
|
await sendTelegramNotification(telegram, messageText);
|
||||||
}
|
}
|
||||||
@@ -191,6 +199,10 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
value: databaseType,
|
value: databaseType,
|
||||||
short: true,
|
short: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Database Name",
|
||||||
|
value: databaseName,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "Time",
|
title: "Time",
|
||||||
value: date.toLocaleString(),
|
value: date.toLocaleString(),
|
||||||
|
|||||||
Reference in New Issue
Block a user