diff --git a/apps/dokploy/pages/api/cron/refresh-license-validity.ts b/apps/dokploy/pages/api/cron/refresh-license-validity.ts deleted file mode 100644 index bd932ce71..000000000 --- a/apps/dokploy/pages/api/cron/refresh-license-validity.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from "next"; -import { refreshAllLicenseValidity } from "@/server/utils/enterprise"; - -/** - * Cron endpoint to refresh isValidEnterpriseLicense for all users with a license key. - * Call every 2 weeks (e.g. 0 0 1,15 * * for 1st and 15th, or via your hosting cron). - * - * Requires CRON_SECRET in Authorization header or query: ?secret=CRON_SECRET - */ -export default async function handler( - req: NextApiRequest, - res: NextApiResponse, -) { - if (req.method !== "GET" && req.method !== "POST") { - return res.status(405).json({ error: "Method not allowed" }); - } - - const secret = - process.env.CRON_SECRET ?? process.env.LICENSE_CRON_SECRET; - if (!secret) { - return res.status(500).json({ - error: "CRON_SECRET or LICENSE_CRON_SECRET not configured", - }); - } - - const authHeader = req.headers.authorization; - const bearer = authHeader?.startsWith("Bearer ") - ? authHeader.slice(7) - : undefined; - const querySecret = typeof req.query.secret === "string" ? req.query.secret : undefined; - - if (bearer !== secret && querySecret !== secret) { - return res.status(401).json({ error: "Unauthorized" }); - } - - try { - const result = await refreshAllLicenseValidity(); - return res.status(200).json(result); - } catch (err) { - console.error("refresh-license-validity:", err); - return res - .status(500) - .json({ - error: err instanceof Error ? err.message : "Refresh failed", - }); - } -} diff --git a/apps/dokploy/server/server.ts b/apps/dokploy/server/server.ts index e594538c6..dbd7c2638 100644 --- a/apps/dokploy/server/server.ts +++ b/apps/dokploy/server/server.ts @@ -6,6 +6,7 @@ import { IS_CLOUD, initCancelDeployments, initCronJobs, + initEnterpriseBackupCronJobs, initializeNetwork, initSchedules, initVolumeBackupsCronJobs, @@ -15,6 +16,7 @@ import { import { config } from "dotenv"; import next from "next"; import { migration } from "@/server/db/migration"; +import packageInfo from "../package.json"; import { setupDockerContainerLogsWebSocketServer } from "./wss/docker-container-logs"; import { setupDockerContainerTerminalWebSocketServer } from "./wss/docker-container-terminal"; import { setupDockerStatsMonitoringSocketServer } from "./wss/docker-stats"; @@ -33,13 +35,14 @@ if (process.env.NODE_ENV === "production" && !IS_CLOUD) { setupDirectories(); createDefaultTraefikConfig(); createDefaultServerTraefikConfig(); - console.log("✅ Critical initialization complete"); + console.log("✅ initialization complete"); } const app = next({ dev, turbopack: process.env.TURBOPACK === "1" }); const handle = app.getRequestHandler(); void app.prepare().then(async () => { try { + console.log("Running DokployVersion: ", packageInfo.version); const server = http.createServer((req, res) => { handle(req, res); }); @@ -71,6 +74,8 @@ void app.prepare().then(async () => { server.listen(PORT, HOST); console.log(`Server Started on: http://${HOST}:${PORT}`); + await initEnterpriseBackupCronJobs(); + if (!IS_CLOUD) { console.log("Starting Deployment Worker"); const { deploymentWorker } = await import("./queues/deployments-queue"); diff --git a/packages/server/src/utils/crons/enterprise.ts b/packages/server/src/utils/crons/enterprise.ts index a7693eccd..8e915b35f 100644 --- a/packages/server/src/utils/crons/enterprise.ts +++ b/packages/server/src/utils/crons/enterprise.ts @@ -1,22 +1,28 @@ -import { member } from "@dokploy/server/db/schema"; import { getPublicIpWithFallback } from "@dokploy/server/wss/utils"; -import { eq } from "drizzle-orm"; +import { and, eq, isNotNull } from "drizzle-orm"; import { scheduleJob } from "node-schedule"; import { db } from "../../db/index"; import { user as userSchema } from "../../db/schema/user"; export const initEnterpriseBackupCronJobs = async () => { - console.log("Setting up enterprise backup cron jobs...."); - - const admins = await db.query.member.findMany({ - where: eq(member.role, "owner"), - with: { - user: true, - }, + const users = await db.query.user.findMany({ + where: and( + isNotNull(userSchema.licenseKey), + isNotNull(userSchema.enableEnterpriseFeatures), + eq(userSchema.isValidEnterpriseLicense, true), + ), }); - for (const admin of admins) { - const { user } = admin; + if (users.length === 0) { + return; + } + + console.log( + "Setting up enterprise backup cron jobs for users....", + users.length, + ); + + for (const user of users) { if (user.isValidEnterpriseLicense) { scheduleJob(`enterprise-backup-${user.id}`, "0 0 */14 * *", async () => { try {