diff --git a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx index cfe747d27e..7185ed7ff2 100644 --- a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx @@ -22,6 +22,13 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; import { api, type RouterOutputs } from "@/utils/api"; import { ShowRollbackSettings } from "../rollbacks/show-rollback-settings"; import { CancelQueues } from "./cancel-queues"; @@ -59,11 +66,13 @@ export const ShowDeployments = ({ const [activeLog, setActiveLog] = useState< RouterOutputs["deployment"]["all"][number] | null >(null); + const [deploymentLimit, setDeploymentLimit] = useState(10); const { data: deployments, isLoading: isLoadingDeployments } = api.deployment.allByType.useQuery( { id, type, + limit: deploymentLimit, }, { enabled: !!id, @@ -140,10 +149,29 @@ export const ShowDeployments = ({
Deployments - See the last 10 deployments for this {type} + See the last {deploymentLimit} deployments for this {type}
+
+ + Show: + + +
{(type === "application" || type === "compose") && ( )} diff --git a/apps/dokploy/server/api/routers/deployment.ts b/apps/dokploy/server/api/routers/deployment.ts index 9004a0a054..1be5506d63 100644 --- a/apps/dokploy/server/api/routers/deployment.ts +++ b/apps/dokploy/server/api/routers/deployment.ts @@ -37,7 +37,10 @@ export const deploymentRouter = createTRPCRouter({ message: "You are not authorized to access this application", }); } - return await findAllDeploymentsByApplicationId(input.applicationId); + return await findAllDeploymentsByApplicationId( + input.applicationId, + input.limit, + ); }), allByCompose: protectedProcedure @@ -53,7 +56,7 @@ export const deploymentRouter = createTRPCRouter({ message: "You are not authorized to access this compose", }); } - return await findAllDeploymentsByComposeId(input.composeId); + return await findAllDeploymentsByComposeId(input.composeId, input.limit); }), allByServer: protectedProcedure .input(apiFindAllByServer) @@ -65,7 +68,7 @@ export const deploymentRouter = createTRPCRouter({ message: "You are not authorized to access this server", }); } - return await findAllDeploymentsByServerId(input.serverId); + return await findAllDeploymentsByServerId(input.serverId, input.limit); }), allByType: protectedProcedure @@ -74,11 +77,11 @@ export const deploymentRouter = createTRPCRouter({ const deploymentsList = await db.query.deployments.findMany({ where: eq(deployments[`${input.type}Id`], input.id), orderBy: desc(deployments.createdAt), + limit: input.limit, with: { rollback: true, }, }); - return deploymentsList; }), diff --git a/packages/server/src/db/schema/deployment.ts b/packages/server/src/db/schema/deployment.ts index b950703c8a..e748ed87f7 100644 --- a/packages/server/src/db/schema/deployment.ts +++ b/packages/server/src/db/schema/deployment.ts @@ -216,6 +216,7 @@ export const apiFindAllByApplication = schema }) .extend({ applicationId: z.string().min(1), + limit: z.number().min(1).max(100).optional().default(10), }) .required(); @@ -225,6 +226,7 @@ export const apiFindAllByCompose = schema }) .extend({ composeId: z.string().min(1), + limit: z.number().min(1).max(100).optional().default(10), }) .required(); @@ -234,6 +236,7 @@ export const apiFindAllByServer = schema }) .extend({ serverId: z.string().min(1), + limit: z.number().min(1).max(100).optional().default(10), }) .required(); @@ -249,5 +252,6 @@ export const apiFindAllByType = z "backup", "volumeBackup", ]), + limit: z.number().min(1).max(100).optional().default(10), }) .required(); diff --git a/packages/server/src/services/deployment.ts b/packages/server/src/services/deployment.ts index 6244ec8eb6..c92146b5f9 100644 --- a/packages/server/src/services/deployment.ts +++ b/packages/server/src/services/deployment.ts @@ -14,6 +14,7 @@ import { } from "@dokploy/server/db/schema"; import { removeDirectoryIfExistsContent } from "@dokploy/server/utils/filesystem/directory"; import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; +import { logger } from "../lib/logger"; import { TRPCError } from "@trpc/server"; import { format } from "date-fns"; import { desc, eq } from "drizzle-orm"; @@ -75,7 +76,7 @@ export const createDeployment = async ( ) => { const application = await findApplicationById(deployment.applicationId); try { - await removeLastTenDeployments( + await removeLastOneHundredDeployments( deployment.applicationId, "application", application.serverId, @@ -158,7 +159,7 @@ export const createDeploymentPreview = async ( deployment.previewDeploymentId, ); try { - await removeLastTenDeployments( + await removeLastOneHundredDeployments( deployment.previewDeploymentId, "previewDeployment", previewDeployment?.application?.serverId, @@ -239,7 +240,7 @@ export const createDeploymentCompose = async ( ) => { const compose = await findComposeById(deployment.composeId); try { - await removeLastTenDeployments( + await removeLastOneHundredDeployments( deployment.composeId, "compose", compose.serverId, @@ -327,7 +328,11 @@ export const createDeploymentBackup = async ( serverId = backup.compose?.serverId; } try { - await removeLastTenDeployments(deployment.backupId, "backup", serverId); + await removeLastOneHundredDeployments( + deployment.backupId, + "backup", + serverId, + ); const { LOGS_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${backup.appName}-${formattedDateTime}.log`; @@ -401,7 +406,11 @@ export const createDeploymentSchedule = async ( schedule.application?.serverId || schedule.compose?.serverId || schedule.server?.serverId; - await removeLastTenDeployments(deployment.scheduleId, "schedule", serverId); + await removeLastOneHundredDeployments( + deployment.scheduleId, + "schedule", + serverId, + ); const { SCHEDULES_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${schedule.appName}-${formattedDateTime}.log`; @@ -475,7 +484,7 @@ export const createDeploymentVolumeBackup = async ( try { const serverId = volumeBackup.application?.serverId || volumeBackup.compose?.serverId; - await removeLastTenDeployments( + await removeLastOneHundredDeployments( deployment.volumeBackupId, "volumeBackup", serverId, @@ -608,7 +617,7 @@ export const removeDeployments = async (application: Application) => { await removeDeploymentsByApplicationId(applicationId); }; -const removeLastTenDeployments = async ( +const removeLastOneHundredDeployments = async ( id: string, type: | "application" @@ -621,8 +630,8 @@ const removeLastTenDeployments = async ( serverId?: string | null, ) => { const deploymentList = await getDeploymentsByType(id, type); - if (deploymentList.length > 10) { - const deploymentsToDelete = deploymentList.slice(10); + if (deploymentList.length > 100) { + const deploymentsToDelete = deploymentList.slice(100); if (serverId) { let command = ""; for (const oldDeployment of deploymentsToDelete) { @@ -701,18 +710,24 @@ export const removeDeploymentsByComposeId = async (compose: Compose) => { export const findAllDeploymentsByApplicationId = async ( applicationId: string, + limit?: number, ) => { const deploymentsList = await db.query.deployments.findMany({ where: eq(deployments.applicationId, applicationId), orderBy: desc(deployments.createdAt), + ...(limit ? { limit } : {}), }); return deploymentsList; }; -export const findAllDeploymentsByComposeId = async (composeId: string) => { +export const findAllDeploymentsByComposeId = async ( + composeId: string, + limit?: number, +) => { const deploymentsList = await db.query.deployments.findMany({ where: eq(deployments.composeId, composeId), orderBy: desc(deployments.createdAt), + ...(limit ? { limit } : {}), }); return deploymentsList; }; @@ -824,10 +839,14 @@ export const removeDeploymentsByServerId = async (server: Server) => { .returning(); }; -export const findAllDeploymentsByServerId = async (serverId: string) => { +export const findAllDeploymentsByServerId = async ( + serverId: string, + limit?: number, +) => { const deploymentsList = await db.query.deployments.findMany({ where: eq(deployments.serverId, serverId), orderBy: desc(deployments.createdAt), + ...(limit ? { limit } : {}), }); return deploymentsList; };