Merge pull request #3599 from Dokploy/copilot/fix-postgres-deployment-port-conflict

fix: add port conflict validation for database external ports
This commit is contained in:
Mauricio Siu
2026-02-05 02:31:20 -06:00
committed by GitHub
10 changed files with 94 additions and 19 deletions

View File

@@ -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");
});
};

View File

@@ -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");
});
};

View File

@@ -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");
});
};

View File

@@ -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");
});
};

View File

@@ -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");
});
};

View File

@@ -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)

View File

@@ -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,
});

View File

@@ -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)

View File

@@ -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,
});

View File

@@ -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)