From 999dc7d3600241b1161b10461c04707b11622dce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 05:47:52 +0000 Subject: [PATCH 1/4] Initial plan From 139c06b63df216ea506cb0f2e623c4e16b6fe19c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 05:52:38 +0000 Subject: [PATCH 2/4] Add port validation to database external ports Co-authored-by: Siumauricio <47042324+Siumauricio@users.noreply.github.com> --- apps/dokploy/server/api/routers/mariadb.ts | 15 +++++++++++++++ apps/dokploy/server/api/routers/mongo.ts | 15 +++++++++++++++ apps/dokploy/server/api/routers/mysql.ts | 15 +++++++++++++++ apps/dokploy/server/api/routers/postgres.ts | 15 +++++++++++++++ apps/dokploy/server/api/routers/redis.ts | 15 +++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/apps/dokploy/server/api/routers/mariadb.ts b/apps/dokploy/server/api/routers/mariadb.ts index 7d4bd2e50..b52b737a5 100644 --- a/apps/dokploy/server/api/routers/mariadb.ts +++ b/apps/dokploy/server/api/routers/mariadb.ts @@ -1,5 +1,6 @@ import { addNewService, + checkPortInUse, checkServiceAccess, createMariadb, createMount, @@ -172,6 +173,20 @@ export const mariadbRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + mongo.serverId || undefined, + ); + if (portCheck.isInUse) { + throw new TRPCError({ + code: "CONFLICT", + message: `Port ${input.externalPort} is already in use by ${portCheck.conflictingContainer}`, + }); + } + } + await updateMariadbById(input.mariadbId, { externalPort: input.externalPort, }); diff --git a/apps/dokploy/server/api/routers/mongo.ts b/apps/dokploy/server/api/routers/mongo.ts index ae0fa4741..661c808db 100644 --- a/apps/dokploy/server/api/routers/mongo.ts +++ b/apps/dokploy/server/api/routers/mongo.ts @@ -1,5 +1,6 @@ import { addNewService, + checkPortInUse, checkServiceAccess, createMongo, createMount, @@ -189,6 +190,20 @@ export const mongoRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + mongo.serverId || undefined, + ); + if (portCheck.isInUse) { + throw new TRPCError({ + code: "CONFLICT", + message: `Port ${input.externalPort} is already in use by ${portCheck.conflictingContainer}`, + }); + } + } + await updateMongoById(input.mongoId, { externalPort: input.externalPort, }); diff --git a/apps/dokploy/server/api/routers/mysql.ts b/apps/dokploy/server/api/routers/mysql.ts index 5204fedc8..ffbf9c593 100644 --- a/apps/dokploy/server/api/routers/mysql.ts +++ b/apps/dokploy/server/api/routers/mysql.ts @@ -1,5 +1,6 @@ import { addNewService, + checkPortInUse, checkServiceAccess, createMount, createMysql, @@ -187,6 +188,20 @@ export const mysqlRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + mongo.serverId || undefined, + ); + if (portCheck.isInUse) { + throw new TRPCError({ + code: "CONFLICT", + message: `Port ${input.externalPort} is already in use by ${portCheck.conflictingContainer}`, + }); + } + } + await updateMySqlById(input.mysqlId, { externalPort: input.externalPort, }); diff --git a/apps/dokploy/server/api/routers/postgres.ts b/apps/dokploy/server/api/routers/postgres.ts index e1718bff1..97db0b878 100644 --- a/apps/dokploy/server/api/routers/postgres.ts +++ b/apps/dokploy/server/api/routers/postgres.ts @@ -1,5 +1,6 @@ import { addNewService, + checkPortInUse, checkServiceAccess, createMount, createPostgres, @@ -192,6 +193,20 @@ export const postgresRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + postgres.serverId || undefined, + ); + if (portCheck.isInUse) { + throw new TRPCError({ + code: "CONFLICT", + message: `Port ${input.externalPort} is already in use by ${portCheck.conflictingContainer}`, + }); + } + } + await updatePostgresById(input.postgresId, { externalPort: input.externalPort, }); diff --git a/apps/dokploy/server/api/routers/redis.ts b/apps/dokploy/server/api/routers/redis.ts index d377b1707..0f09ae0dd 100644 --- a/apps/dokploy/server/api/routers/redis.ts +++ b/apps/dokploy/server/api/routers/redis.ts @@ -1,5 +1,6 @@ import { addNewService, + checkPortInUse, checkServiceAccess, createMount, createRedis, @@ -211,6 +212,20 @@ export const redisRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + mongo.serverId || undefined, + ); + if (portCheck.isInUse) { + throw new TRPCError({ + code: "CONFLICT", + message: `Port ${input.externalPort} is already in use by ${portCheck.conflictingContainer}`, + }); + } + } + await updateRedisById(input.redisId, { externalPort: input.externalPort, }); From a86fe46b7b570b3e32963fa4b48f8a44a2ce3ce7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 05:54:23 +0000 Subject: [PATCH 3/4] Fix variable naming in database routers Co-authored-by: Siumauricio <47042324+Siumauricio@users.noreply.github.com> --- apps/dokploy/server/api/routers/mariadb.ts | 8 ++++---- apps/dokploy/server/api/routers/mysql.ts | 8 ++++---- apps/dokploy/server/api/routers/redis.ts | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/dokploy/server/api/routers/mariadb.ts b/apps/dokploy/server/api/routers/mariadb.ts index b52b737a5..1f58eec1b 100644 --- a/apps/dokploy/server/api/routers/mariadb.ts +++ b/apps/dokploy/server/api/routers/mariadb.ts @@ -163,9 +163,9 @@ export const mariadbRouter = createTRPCRouter({ saveExternalPort: protectedProcedure .input(apiSaveExternalPortMariaDB) .mutation(async ({ input, ctx }) => { - const mongo = await findMariadbById(input.mariadbId); + const mariadb = await findMariadbById(input.mariadbId); if ( - mongo.environment.project.organizationId !== + mariadb.environment.project.organizationId !== ctx.session.activeOrganizationId ) { throw new TRPCError({ @@ -177,7 +177,7 @@ export const mariadbRouter = createTRPCRouter({ if (input.externalPort) { const portCheck = await checkPortInUse( input.externalPort, - mongo.serverId || undefined, + mariadb.serverId || undefined, ); if (portCheck.isInUse) { throw new TRPCError({ @@ -191,7 +191,7 @@ export const mariadbRouter = createTRPCRouter({ externalPort: input.externalPort, }); await deployMariadb(input.mariadbId); - return mongo; + return mariadb; }), deploy: protectedProcedure .input(apiDeployMariaDB) diff --git a/apps/dokploy/server/api/routers/mysql.ts b/apps/dokploy/server/api/routers/mysql.ts index ffbf9c593..9af93b556 100644 --- a/apps/dokploy/server/api/routers/mysql.ts +++ b/apps/dokploy/server/api/routers/mysql.ts @@ -178,9 +178,9 @@ export const mysqlRouter = createTRPCRouter({ saveExternalPort: protectedProcedure .input(apiSaveExternalPortMySql) .mutation(async ({ input, ctx }) => { - const mongo = await findMySqlById(input.mysqlId); + const mysql = await findMySqlById(input.mysqlId); if ( - mongo.environment.project.organizationId !== + mysql.environment.project.organizationId !== ctx.session.activeOrganizationId ) { throw new TRPCError({ @@ -192,7 +192,7 @@ export const mysqlRouter = createTRPCRouter({ if (input.externalPort) { const portCheck = await checkPortInUse( input.externalPort, - mongo.serverId || undefined, + mysql.serverId || undefined, ); if (portCheck.isInUse) { throw new TRPCError({ @@ -206,7 +206,7 @@ export const mysqlRouter = createTRPCRouter({ externalPort: input.externalPort, }); await deployMySql(input.mysqlId); - return mongo; + return mysql; }), deploy: protectedProcedure .input(apiDeployMySql) diff --git a/apps/dokploy/server/api/routers/redis.ts b/apps/dokploy/server/api/routers/redis.ts index 0f09ae0dd..a5cc7c9aa 100644 --- a/apps/dokploy/server/api/routers/redis.ts +++ b/apps/dokploy/server/api/routers/redis.ts @@ -202,9 +202,9 @@ export const redisRouter = createTRPCRouter({ saveExternalPort: protectedProcedure .input(apiSaveExternalPortRedis) .mutation(async ({ input, ctx }) => { - const mongo = await findRedisById(input.redisId); + const redis = await findRedisById(input.redisId); if ( - mongo.environment.project.organizationId !== + redis.environment.project.organizationId !== ctx.session.activeOrganizationId ) { throw new TRPCError({ @@ -216,7 +216,7 @@ export const redisRouter = createTRPCRouter({ if (input.externalPort) { const portCheck = await checkPortInUse( input.externalPort, - mongo.serverId || undefined, + redis.serverId || undefined, ); if (portCheck.isInUse) { throw new TRPCError({ @@ -230,7 +230,7 @@ export const redisRouter = createTRPCRouter({ externalPort: input.externalPort, }); await deployRedis(input.redisId); - return mongo; + return redis; }), deploy: protectedProcedure .input(apiDeployRedis) From 66448ff6c22ce1b675a1f1299642f4d7697af4b5 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Thu, 5 Feb 2026 02:31:02 -0600 Subject: [PATCH 4/4] fix: improve error handling for external port updates in database credential components - Updated error handling in the ShowExternal*Credentials components for MariaDB, MongoDB, MySQL, PostgreSQL, and Redis to display specific error messages when saving the external port fails. --- .../mariadb/general/show-external-mariadb-credentials.tsx | 4 ++-- .../mongo/general/show-external-mongo-credentials.tsx | 4 ++-- .../mysql/general/show-external-mysql-credentials.tsx | 4 ++-- .../postgres/general/show-external-postgres-credentials.tsx | 4 ++-- .../redis/general/show-external-redis-credentials.tsx | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx b/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx index 8745db286..86fe71ed4 100644 --- a/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx +++ b/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx @@ -73,8 +73,8 @@ export const ShowExternalMariadbCredentials = ({ mariadbId }: Props) => { toast.success("External Port updated"); await refetch(); }) - .catch(() => { - toast.error("Error saving the external port"); + .catch((error: Error) => { + toast.error(error?.message || "Error saving the external port"); }); }; diff --git a/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx b/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx index d30061db5..acc74066f 100644 --- a/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx +++ b/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx @@ -73,8 +73,8 @@ export const ShowExternalMongoCredentials = ({ mongoId }: Props) => { toast.success("External Port updated"); await refetch(); }) - .catch(() => { - toast.error("Error saving the external port"); + .catch((error: Error) => { + toast.error(error?.message || "Error saving the external port"); }); }; diff --git a/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx b/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx index dfaa36f6b..6e6cbe018 100644 --- a/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx +++ b/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx @@ -73,8 +73,8 @@ export const ShowExternalMysqlCredentials = ({ mysqlId }: Props) => { toast.success("External Port updated"); await refetch(); }) - .catch(() => { - toast.error("Error saving the external port"); + .catch((error: Error) => { + toast.error(error?.message || "Error saving the external port"); }); }; diff --git a/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx b/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx index 46b3772a0..1d34c010a 100644 --- a/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx +++ b/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx @@ -75,8 +75,8 @@ export const ShowExternalPostgresCredentials = ({ postgresId }: Props) => { toast.success("External Port updated"); await refetch(); }) - .catch(() => { - toast.error("Error saving the external port"); + .catch((error: Error) => { + toast.error(error?.message || "Error saving the external port"); }); }; diff --git a/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx b/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx index 8edd92389..9511af628 100644 --- a/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx +++ b/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx @@ -74,8 +74,8 @@ export const ShowExternalRedisCredentials = ({ redisId }: Props) => { toast.success("External Port updated"); await refetch(); }) - .catch(() => { - toast.error("Error saving the external port"); + .catch((error: Error) => { + toast.error(error?.message || "Error saving the external port"); }); };