diff --git a/packages/server/src/utils/builders/railpack.ts b/packages/server/src/utils/builders/railpack.ts index 62fa9f975..b12296a56 100644 --- a/packages/server/src/utils/builders/railpack.ts +++ b/packages/server/src/utils/builders/railpack.ts @@ -44,10 +44,15 @@ export const getRailpackCommand = (application: ApplicationNested) => { const secretsHash = calculateSecretsHash(envVariables); const cacheKey = cleanCache ? nanoid(10) : undefined; - // Build command + // Build command. + // Use a unique builder name per build so concurrent deployments don't race + // on a shared "builder-containerd" instance (create/use/rm collisions). + const builderName = `railpack-${appName}-${nanoid(6)}`; const buildArgs = [ "buildx", "build", + "--builder", + builderName, ...(cacheKey ? [ "--build-arg", @@ -84,17 +89,16 @@ export const getRailpackCommand = (application: ApplicationNested) => { const bashCommand = ` -# Ensure we have a builder with containerd +# Ensure we have a builder with containerd (isolated per build) export RAILPACK_VERSION=${application.railpackVersion} bash -c "$(curl -fsSL https://railpack.com/install.sh)" -docker buildx create --use --name builder-containerd --driver docker-container || true -docker buildx use builder-containerd +docker buildx create --name ${builderName} --driver docker-container || true echo "Preparing Railpack build plan..." ; -railpack ${prepareArgs.join(" ")} || { +railpack ${prepareArgs.join(" ")} || { echo "❌ Railpack prepare failed" ; - docker buildx rm builder-containerd || true + docker buildx rm ${builderName} || true exit 1; } echo "✅ Railpack prepare completed." ; @@ -102,13 +106,13 @@ echo "✅ Railpack prepare completed." ; echo "Building with Railpack frontend..." ; # Export environment variables for secrets ${exportEnvs.join("\n")} -docker ${buildArgs.join(" ")} || { +docker ${buildArgs.join(" ")} || { echo "❌ Railpack build failed" ; - docker buildx rm builder-containerd || true + docker buildx rm ${builderName} || true exit 1; } echo "✅ Railpack build completed." ; -docker buildx rm builder-containerd +docker buildx rm ${builderName} || true `; return bashCommand; diff --git a/packages/server/src/utils/startup/cancel-deployments.ts b/packages/server/src/utils/startup/cancel-deployments.ts index 5c0a871f1..34766c187 100644 --- a/packages/server/src/utils/startup/cancel-deployments.ts +++ b/packages/server/src/utils/startup/cancel-deployments.ts @@ -1,5 +1,5 @@ -import { deployments } from "@dokploy/server/db/schema"; -import { eq } from "drizzle-orm"; +import { applications, compose, deployments } from "@dokploy/server/db/schema"; +import { eq, inArray } from "drizzle-orm"; import { db } from "../../db/index"; export const initCancelDeployments = async () => { @@ -14,6 +14,36 @@ export const initCancelDeployments = async () => { .where(eq(deployments.status, "running")) .returning(); + // Reset the related services so they don't stay stuck in "running". + const applicationIds = [ + ...new Set( + result + .map((deployment) => deployment.applicationId) + .filter((id): id is string => !!id), + ), + ]; + const composeIds = [ + ...new Set( + result + .map((deployment) => deployment.composeId) + .filter((id): id is string => !!id), + ), + ]; + + if (applicationIds.length > 0) { + await db + .update(applications) + .set({ applicationStatus: "idle" }) + .where(inArray(applications.applicationId, applicationIds)); + } + + if (composeIds.length > 0) { + await db + .update(compose) + .set({ composeStatus: "idle" }) + .where(inArray(compose.composeId, composeIds)); + } + console.log(`Cancelled ${result.length} deployments`); } catch (error) { console.error(error);