From 499022a3283bcaf5ca1ef61b937441bd78d7ed80 Mon Sep 17 00:00:00 2001 From: Douglas Camargo Date: Mon, 23 Jun 2025 22:35:40 -0300 Subject: [PATCH 1/7] feat: add database name in database backup notification --- packages/server/src/utils/backups/compose.ts | 2 ++ packages/server/src/utils/backups/mariadb.ts | 2 ++ packages/server/src/utils/backups/mongo.ts | 2 ++ packages/server/src/utils/backups/mysql.ts | 2 ++ packages/server/src/utils/backups/postgres.ts | 2 ++ .../src/utils/notifications/database-backup.ts | 14 +++++++++++++- 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/server/src/utils/backups/compose.ts b/packages/server/src/utils/backups/compose.ts index 82fb8828a..039b765dc 100644 --- a/packages/server/src/utils/backups/compose.ts +++ b/packages/server/src/utils/backups/compose.ts @@ -49,6 +49,7 @@ export const runComposeBackup = async ( databaseType: "mongodb", type: "success", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "done"); @@ -62,6 +63,7 @@ export const runComposeBackup = async ( // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "error"); diff --git a/packages/server/src/utils/backups/mariadb.ts b/packages/server/src/utils/backups/mariadb.ts index 70bad1698..bca65bfd6 100644 --- a/packages/server/src/utils/backups/mariadb.ts +++ b/packages/server/src/utils/backups/mariadb.ts @@ -48,6 +48,7 @@ export const runMariadbBackup = async ( databaseType: "mariadb", type: "success", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "done"); } catch (error) { @@ -60,6 +61,7 @@ export const runMariadbBackup = async ( // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "error"); throw error; diff --git a/packages/server/src/utils/backups/mongo.ts b/packages/server/src/utils/backups/mongo.ts index 806fd5c0f..9ef147a51 100644 --- a/packages/server/src/utils/backups/mongo.ts +++ b/packages/server/src/utils/backups/mongo.ts @@ -46,6 +46,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => { databaseType: "mongodb", type: "success", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "done"); } catch (error) { @@ -58,6 +59,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => { // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "error"); throw error; diff --git a/packages/server/src/utils/backups/mysql.ts b/packages/server/src/utils/backups/mysql.ts index 2ba8a0e12..1397c835f 100644 --- a/packages/server/src/utils/backups/mysql.ts +++ b/packages/server/src/utils/backups/mysql.ts @@ -47,6 +47,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => { databaseType: "mysql", type: "success", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "done"); } catch (error) { @@ -59,6 +60,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => { // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "error"); throw error; diff --git a/packages/server/src/utils/backups/postgres.ts b/packages/server/src/utils/backups/postgres.ts index 9ce2025a9..c02bae96a 100644 --- a/packages/server/src/utils/backups/postgres.ts +++ b/packages/server/src/utils/backups/postgres.ts @@ -50,6 +50,7 @@ export const runPostgresBackup = async ( databaseType: "postgres", type: "success", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "done"); @@ -62,6 +63,7 @@ export const runPostgresBackup = async ( // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, + databaseName: backup.database }); await updateDeploymentStatus(deployment.deploymentId, "error"); diff --git a/packages/server/src/utils/notifications/database-backup.ts b/packages/server/src/utils/notifications/database-backup.ts index 37a4a1ff2..21279a3b2 100644 --- a/packages/server/src/utils/notifications/database-backup.ts +++ b/packages/server/src/utils/notifications/database-backup.ts @@ -19,6 +19,7 @@ export const sendDatabaseBackupNotifications = async ({ type, errorMessage, organizationId, + databaseName }: { projectName: string; applicationName: string; @@ -26,6 +27,7 @@ export const sendDatabaseBackupNotifications = async ({ type: "error" | "success"; organizationId: string; errorMessage?: string; + databaseName: string; }) => { const date = new Date(); const unixDate = ~~(Number(date) / 1000); @@ -90,6 +92,11 @@ export const sendDatabaseBackupNotifications = async ({ value: databaseType, inline: true, }, + { + name: decorate("`📂`", "Database Name"), + value: databaseName, + inline: true, + }, { name: decorate("`📅`", "Date"), value: ``, @@ -136,6 +143,7 @@ export const sendDatabaseBackupNotifications = async ({ `${decorate("🛠️", `Project: ${projectName}`)}` + `${decorate("⚙️", `Application: ${applicationName}`)}` + `${decorate("❔", `Type: ${databaseType}`)}` + + `${decorate("📂", `Database Name: ${databaseName}`)}` + `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` + `${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`, ); @@ -150,7 +158,7 @@ export const sendDatabaseBackupNotifications = async ({ ? `\n\nError:\n
${errorMessage}
` : ""; - const messageText = `${statusEmoji} Database Backup ${typeStatus}\n\nProject: ${projectName}\nApplication: ${applicationName}\nType: ${databaseType}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}${isError ? errorMsg : ""}`; + const messageText = `${statusEmoji} Database Backup ${typeStatus}\n\nProject: ${projectName}\nApplication: ${applicationName}\nType: ${databaseType}\nDatabase Name: ${databaseName}\nDate: ${format(date, "PP")}\nTime: ${format(date, "pp")}${isError ? errorMsg : ""}`; await sendTelegramNotification(telegram, messageText); } @@ -191,6 +199,10 @@ export const sendDatabaseBackupNotifications = async ({ value: databaseType, short: true, }, + { + title: "Database Name", + value: databaseName + }, { title: "Time", value: date.toLocaleString(), From 6b0d9240dd24e9a72d3d9d7c7caa673cfaeb72d4 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Thu, 26 Jun 2025 21:00:51 -0600 Subject: [PATCH 2/7] feat(settings): add query to retrieve Dokploy cloud IPs - Implemented a new admin procedure to fetch cloud IPs from environment variables. - Returns an empty array if not in cloud mode. --- apps/dokploy/server/api/routers/settings.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/dokploy/server/api/routers/settings.ts b/apps/dokploy/server/api/routers/settings.ts index 149af7046..0d07bbea0 100644 --- a/apps/dokploy/server/api/routers/settings.ts +++ b/apps/dokploy/server/api/routers/settings.ts @@ -837,6 +837,14 @@ export const settingsRouter = createTRPCRouter({ getLogCleanupStatus: adminProcedure.query(async () => { 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) => { From bc79074441ab931f946eed7d052df29fee9f635d Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 03:13:41 +0000 Subject: [PATCH 3/7] [autofix.ci] apply automated fixes --- packages/server/src/utils/backups/compose.ts | 4 ++-- packages/server/src/utils/backups/mariadb.ts | 4 ++-- packages/server/src/utils/backups/mongo.ts | 4 ++-- packages/server/src/utils/backups/mysql.ts | 4 ++-- packages/server/src/utils/backups/postgres.ts | 4 ++-- packages/server/src/utils/notifications/database-backup.ts | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/server/src/utils/backups/compose.ts b/packages/server/src/utils/backups/compose.ts index 039b765dc..1ccf0f8fb 100644 --- a/packages/server/src/utils/backups/compose.ts +++ b/packages/server/src/utils/backups/compose.ts @@ -49,7 +49,7 @@ export const runComposeBackup = async ( databaseType: "mongodb", type: "success", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "done"); @@ -63,7 +63,7 @@ export const runComposeBackup = async ( // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "error"); diff --git a/packages/server/src/utils/backups/mariadb.ts b/packages/server/src/utils/backups/mariadb.ts index bca65bfd6..8760095c8 100644 --- a/packages/server/src/utils/backups/mariadb.ts +++ b/packages/server/src/utils/backups/mariadb.ts @@ -48,7 +48,7 @@ export const runMariadbBackup = async ( databaseType: "mariadb", type: "success", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "done"); } catch (error) { @@ -61,7 +61,7 @@ export const runMariadbBackup = async ( // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "error"); throw error; diff --git a/packages/server/src/utils/backups/mongo.ts b/packages/server/src/utils/backups/mongo.ts index 9ef147a51..e626efa01 100644 --- a/packages/server/src/utils/backups/mongo.ts +++ b/packages/server/src/utils/backups/mongo.ts @@ -46,7 +46,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => { databaseType: "mongodb", type: "success", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "done"); } catch (error) { @@ -59,7 +59,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => { // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "error"); throw error; diff --git a/packages/server/src/utils/backups/mysql.ts b/packages/server/src/utils/backups/mysql.ts index 1397c835f..6f6678421 100644 --- a/packages/server/src/utils/backups/mysql.ts +++ b/packages/server/src/utils/backups/mysql.ts @@ -47,7 +47,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => { databaseType: "mysql", type: "success", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "done"); } catch (error) { @@ -60,7 +60,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => { // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "error"); throw error; diff --git a/packages/server/src/utils/backups/postgres.ts b/packages/server/src/utils/backups/postgres.ts index c02bae96a..1f7b6a2d2 100644 --- a/packages/server/src/utils/backups/postgres.ts +++ b/packages/server/src/utils/backups/postgres.ts @@ -50,7 +50,7 @@ export const runPostgresBackup = async ( databaseType: "postgres", type: "success", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "done"); @@ -63,7 +63,7 @@ export const runPostgresBackup = async ( // @ts-ignore errorMessage: error?.message || "Error message not provided", organizationId: project.organizationId, - databaseName: backup.database + databaseName: backup.database, }); await updateDeploymentStatus(deployment.deploymentId, "error"); diff --git a/packages/server/src/utils/notifications/database-backup.ts b/packages/server/src/utils/notifications/database-backup.ts index 21279a3b2..044e3a0cf 100644 --- a/packages/server/src/utils/notifications/database-backup.ts +++ b/packages/server/src/utils/notifications/database-backup.ts @@ -19,7 +19,7 @@ export const sendDatabaseBackupNotifications = async ({ type, errorMessage, organizationId, - databaseName + databaseName, }: { projectName: string; applicationName: string; @@ -201,7 +201,7 @@ export const sendDatabaseBackupNotifications = async ({ }, { title: "Database Name", - value: databaseName + value: databaseName, }, { title: "Time", From 5c2709248c0df735e1777036ef9643d47b5f93e8 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:00:51 -0600 Subject: [PATCH 4/7] fix(upload): refactor registry tag construction for image uploads - Updated the logic for constructing the registry tag in the uploadImage and uploadImageRemoteCommand functions to ensure correct formatting. - Removed unnecessary path imports and streamlined the code for better readability. --- packages/server/src/utils/builders/index.ts | 11 ++++++---- packages/server/src/utils/cluster/upload.ts | 23 ++++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/server/src/utils/builders/index.ts b/packages/server/src/utils/builders/index.ts index 198b953d7..4f8dfa2f3 100644 --- a/packages/server/src/utils/builders/index.ts +++ b/packages/server/src/utils/builders/index.ts @@ -1,5 +1,4 @@ import { createWriteStream } from "node:fs"; -import { join } from "node:path"; import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { uploadImage, uploadImageRemoteCommand } from "../cluster/upload"; @@ -211,16 +210,20 @@ export const mechanizeDockerContainer = async ( const getImageName = (application: ApplicationNested) => { const { appName, sourceType, dockerImage, registry } = application; - + const imageName = `${appName}:latest`; if (sourceType === "docker") { return dockerImage || "ERROR-NO-IMAGE-PROVIDED"; } 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) => { diff --git a/packages/server/src/utils/cluster/upload.ts b/packages/server/src/utils/cluster/upload.ts index 980ace67c..f982d414b 100644 --- a/packages/server/src/utils/cluster/upload.ts +++ b/packages/server/src/utils/cluster/upload.ts @@ -1,5 +1,4 @@ import type { WriteStream } from "node:fs"; -import path, { join } from "node:path"; import type { ApplicationNested } from "../builders"; import { spawnAsync } from "../process/spawnAsync"; @@ -13,19 +12,22 @@ export const uploadImage = async ( throw new Error("Registry not found"); } - const { registryUrl, imagePrefix } = registry; + const { registryUrl, imagePrefix, username } = registry; const { appName } = application; const imageName = `${appName}:latest`; const finalURL = registryUrl; - const registryTag = path - .join(registryUrl, join(imagePrefix || "", imageName)) - .replace(/\/+/g, "/"); + // Build registry tag in correct format: registry.com/owner/image:tag + // For ghcr.io: ghcr.io/username/image:tag + // For docker.io: docker.io/username/image:tag + const registryTag = imagePrefix + ? `${registryUrl}/${imagePrefix}/${imageName}` + : `${registryUrl}/${username}/${imageName}`; try { 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( "docker", @@ -67,15 +69,16 @@ export const uploadImageRemoteCommand = ( throw new Error("Registry not found"); } - const { registryUrl, imagePrefix } = registry; + const { registryUrl, imagePrefix, username } = registry; const { appName } = application; const imageName = `${appName}:latest`; const finalURL = registryUrl; - const registryTag = path - .join(registryUrl, join(imagePrefix || "", imageName)) - .replace(/\/+/g, "/"); + // Build registry tag in correct format: registry.com/owner/image:tag + const registryTag = imagePrefix + ? `${registryUrl}/${imagePrefix}/${imageName}` + : `${registryUrl}/${username}/${imageName}`; try { const command = ` From c05edb313fdd977a450883273b14a15ceec93051 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:32:18 -0600 Subject: [PATCH 5/7] fix(backups): enhance database type handling in compose backup process - Added a new function to determine the database type based on the backup configuration. - Updated notifications to use the correct database type instead of a hardcoded value. --- packages/server/src/utils/backups/compose.ts | 22 +++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/server/src/utils/backups/compose.ts b/packages/server/src/utils/backups/compose.ts index 82fb8828a..e431a5786 100644 --- a/packages/server/src/utils/backups/compose.ts +++ b/packages/server/src/utils/backups/compose.ts @@ -15,7 +15,7 @@ export const runComposeBackup = async ( ) => { const { projectId, name } = compose; const project = await findProjectById(projectId); - const { prefix } = backup; + const { prefix, databaseType } = backup; const destination = backup.destination; const backupFileName = `${new Date().toISOString()}.dump.gz`; const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`; @@ -46,7 +46,7 @@ export const runComposeBackup = async ( await sendDatabaseBackupNotifications({ applicationName: name, projectName: project.name, - databaseType: "mongodb", + databaseType: getDatabaseType(databaseType), type: "success", organizationId: project.organizationId, }); @@ -57,7 +57,7 @@ export const runComposeBackup = async ( await sendDatabaseBackupNotifications({ applicationName: name, projectName: project.name, - databaseType: "mongodb", + databaseType: getDatabaseType(databaseType), type: "error", // @ts-ignore errorMessage: error?.message || "Error message not provided", @@ -68,3 +68,19 @@ export const runComposeBackup = async ( 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"; +}; From 26e2a24f63f99254fe10feb1e63e86f40d0224dc Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:57:36 -0600 Subject: [PATCH 6/7] chore: update version in package.json to v0.23.4 --- apps/dokploy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index ef14fd3b3..86aac4e4e 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -1,6 +1,6 @@ { "name": "dokploy", - "version": "v0.23.3", + "version": "v0.23.4", "private": true, "license": "Apache-2.0", "type": "module", From e79f8c4b7267952d2eca79808eecd1338954ae2b Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Fri, 27 Jun 2025 00:11:02 -0600 Subject: [PATCH 7/7] feat: add Tolgee sponsorship banner to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d192d6f75..e2969f76f 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,10 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com). AmericanCloud + + Tolgee + +