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"); }); }; diff --git a/apps/dokploy/server/api/routers/mariadb.ts b/apps/dokploy/server/api/routers/mariadb.ts index 7d4bd2e50..1f58eec1b 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, @@ -162,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({ @@ -172,11 +173,25 @@ export const mariadbRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + mariadb.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, }); await deployMariadb(input.mariadbId); - return mongo; + return mariadb; }), deploy: protectedProcedure .input(apiDeployMariaDB) 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..9af93b556 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, @@ -177,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({ @@ -187,11 +188,25 @@ export const mysqlRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + mysql.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, }); await deployMySql(input.mysqlId); - return mongo; + return mysql; }), deploy: protectedProcedure .input(apiDeployMySql) 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..a5cc7c9aa 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, @@ -201,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({ @@ -211,11 +212,25 @@ export const redisRouter = createTRPCRouter({ message: "You are not authorized to save this external port", }); } + + if (input.externalPort) { + const portCheck = await checkPortInUse( + input.externalPort, + redis.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, }); await deployRedis(input.redisId); - return mongo; + return redis; }), deploy: protectedProcedure .input(apiDeployRedis)