fix: don't cancel schedule deployments running outside the panel process on restart (#5053)

Fixes #4986. initCancelDeployments blindly marked every 'running'
deployment as 'cancelled' on boot, including schedule runs whose
actual work (docker exec into another container, or SSH to a remote
host) is decoupled from the Dokploy process and keeps running after
a restart. Now only deployments with no schedule, or schedules of
type dokploy-server (a real child process), get cancelled.

Also resolve any stale 'running' deployment for a schedule when a
new run starts, so restarted panels don't leave ghost 'running' rows
forever.
This commit is contained in:
Mauricio Siu
2026-08-11 21:33:49 -06:00
committed by GitHub
parent 3cad115155
commit f12ecc3350
2 changed files with 43 additions and 3 deletions
@@ -453,6 +453,19 @@ export const createDeploymentSchedule = async (
schedule.compose?.serverId ||
schedule.server?.serverId;
await removeLastTenDeployments(deployment.scheduleId, "schedule", serverId);
await db
.update(deployments)
.set({
status: "error",
errorMessage: "Superseded by a new run of this schedule.",
finishedAt: new Date().toISOString(),
})
.where(
and(
eq(deployments.scheduleId, deployment.scheduleId),
eq(deployments.status, "running"),
),
);
try {
const { SCHEDULES_PATH } = paths(!!serverId);
const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss");
@@ -1,4 +1,9 @@
import { applications, compose, deployments } from "@dokploy/server/db/schema";
import {
applications,
compose,
deployments,
schedules,
} from "@dokploy/server/db/schema";
import { eq, inArray } from "drizzle-orm";
import { db } from "../../db/index";
@@ -6,15 +11,37 @@ export const initCancelDeployments = async () => {
try {
console.log("Setting up cancel deployments....");
const runningDeployments = await db
.select({
deploymentId: deployments.deploymentId,
scheduleId: deployments.scheduleId,
scheduleType: schedules.scheduleType,
})
.from(deployments)
.leftJoin(schedules, eq(deployments.scheduleId, schedules.scheduleId))
.where(eq(deployments.status, "running"));
const deploymentIdsToCancel = runningDeployments
.filter(
(deployment) =>
!deployment.scheduleId ||
deployment.scheduleType === "dokploy-server",
)
.map((deployment) => deployment.deploymentId);
if (deploymentIdsToCancel.length === 0) {
console.log("Cancelled 0 deployments");
return;
}
const result = await db
.update(deployments)
.set({
status: "cancelled",
})
.where(eq(deployments.status, "running"))
.where(inArray(deployments.deploymentId, deploymentIdsToCancel))
.returning();
// Reset the related services so they don't stay stuck in "running".
const applicationIds = [
...new Set(
result