Merge pull request #3599 from Dokploy/copilot/fix-postgres-deployment-port-conflict
Some checks are pending
Auto PR to main when version changes / create-pr (push) Waiting to run
Build Docker images / build-and-push-cloud-image (push) Waiting to run
Build Docker images / build-and-push-schedule-image (push) Waiting to run
Build Docker images / build-and-push-server-image (push) Waiting to run
Dokploy Docker Build / docker-amd (push) Waiting to run
Dokploy Docker Build / docker-arm (push) Waiting to run
Dokploy Docker Build / combine-manifests (push) Blocked by required conditions
Dokploy Docker Build / generate-release (push) Blocked by required conditions
autofix.ci / format (push) Waiting to run
Dokploy Monitoring Build / docker-amd (push) Waiting to run
Dokploy Monitoring Build / docker-arm (push) Waiting to run
Dokploy Monitoring Build / combine-manifests (push) Blocked by required conditions
Generate and Sync OpenAPI / Generate OpenAPI and commit to Dokploy repo (push) Waiting to run

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
commit ca7d3f8cb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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)