diff --git a/apps/dokploy/components/proprietary/license-keys/license-key.tsx b/apps/dokploy/components/proprietary/license-keys/license-key.tsx
new file mode 100644
index 000000000..665c85e50
--- /dev/null
+++ b/apps/dokploy/components/proprietary/license-keys/license-key.tsx
@@ -0,0 +1,108 @@
+import { Key } from "lucide-react";
+import Link from "next/link";
+import { useEffect, useState } from "react";
+import { toast } from "sonner";
+import { Button } from "@/components/ui/button";
+import { CardTitle } from "@/components/ui/card";
+import { Input } from "@/components/ui/input";
+import { Switch } from "@/components/ui/switch";
+import { api } from "@/utils/api";
+
+export function LicenseKeySettings() {
+ const utils = api.useUtils();
+ const { data, isLoading } = api.licenseKey.getEnterpriseSettings.useQuery();
+ const { mutateAsync: updateEnterpriseSettings, isLoading: isSaving } =
+ api.licenseKey.updateEnterpriseSettings.useMutation();
+
+ const [licenseKey, setLicenseKey] = useState("");
+
+ useEffect(() => {
+ if (data?.licenseKey !== undefined) {
+ setLicenseKey(data.licenseKey ?? "");
+ }
+ }, [data?.licenseKey]);
+
+ const enabled = !!data?.enableEnterpriseFeatures;
+
+ return (
+
+
+
+
+
+ License Key
+
+
+
+
+ {enabled ? "Enabled" : "Disabled"}
+
+ {
+ try {
+ await updateEnterpriseSettings({
+ enableEnterpriseFeatures: next,
+ });
+ await utils.licenseKey.getEnterpriseSettings.invalidate();
+ toast.success("Enterprise features updated");
+ } catch (error) {
+ console.error(error);
+ toast.error("Failed to update enterprise features");
+ }
+ }}
+ />
+
+
+
+
+ To unlock extra features you need an enterprise license key. Contact us{" "}
+
+ here
+
+ .
+
+
+
+ {enabled && (
+
+
+
+ setLicenseKey(e.target.value)}
+ />
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/apps/dokploy/pages/dashboard/settings/server.tsx b/apps/dokploy/pages/dashboard/settings/server.tsx
index 009d1d2bc..7de3578d5 100644
--- a/apps/dokploy/pages/dashboard/settings/server.tsx
+++ b/apps/dokploy/pages/dashboard/settings/server.tsx
@@ -6,8 +6,8 @@ import superjson from "superjson";
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
import { WebDomain } from "@/components/dashboard/settings/web-domain";
import { WebServer } from "@/components/dashboard/settings/web-server";
-import { LicenseKeySettings } from "@/components/dashboard/settings/web-server/license-key";
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
+import { LicenseKeySettings } from "@/components/proprietary/license-keys/license-key";
import { Card } from "@/components/ui/card";
import { appRouter } from "@/server/api/root";
import { api } from "@/utils/api";
diff --git a/apps/dokploy/server/api/root.ts b/apps/dokploy/server/api/root.ts
index 63ce38d10..12a021ff7 100644
--- a/apps/dokploy/server/api/root.ts
+++ b/apps/dokploy/server/api/root.ts
@@ -22,6 +22,7 @@ import { mountRouter } from "./routers/mount";
import { mysqlRouter } from "./routers/mysql";
import { notificationRouter } from "./routers/notification";
import { organizationRouter } from "./routers/organization";
+import { licenseKeyRouter } from "./routers/proprietary/license-key";
import { portRouter } from "./routers/port";
import { postgresRouter } from "./routers/postgres";
import { previewDeploymentRouter } from "./routers/preview-deployment";
@@ -82,6 +83,7 @@ export const appRouter = createTRPCRouter({
swarm: swarmRouter,
ai: aiRouter,
organization: organizationRouter,
+ licenseKey: licenseKeyRouter,
schedule: scheduleRouter,
rollback: rollbackRouter,
volumeBackups: volumeBackupsRouter,
diff --git a/apps/dokploy/server/api/routers/proprietary/license-key.ts b/apps/dokploy/server/api/routers/proprietary/license-key.ts
new file mode 100644
index 000000000..7ec2ff2c6
--- /dev/null
+++ b/apps/dokploy/server/api/routers/proprietary/license-key.ts
@@ -0,0 +1,52 @@
+import { user } from "@dokploy/server/db/schema";
+import { TRPCError } from "@trpc/server";
+import { eq } from "drizzle-orm";
+import { z } from "zod";
+import { adminProcedure, createTRPCRouter } from "@/server/api/trpc";
+import { db } from "@/server/db";
+
+export const licenseKeyRouter = createTRPCRouter({
+ getEnterpriseSettings: adminProcedure.query(async ({ ctx }) => {
+ const currentUserId = ctx.user.id;
+ const currentUser = await db.query.user.findFirst({
+ where: eq(user.id, currentUserId),
+ });
+
+ if (!currentUser) {
+ throw new TRPCError({
+ code: "NOT_FOUND",
+ message: "User not found",
+ });
+ }
+
+ return {
+ enableEnterpriseFeatures: !!currentUser.enableEnterpriseFeatures,
+ licenseKey: currentUser.licenseKey ?? "",
+ };
+ }),
+
+ updateEnterpriseSettings: adminProcedure
+ .input(
+ z.object({
+ enableEnterpriseFeatures: z.boolean().optional(),
+ licenseKey: z.string().optional(),
+ }),
+ )
+ .mutation(async ({ ctx, input }) => {
+ const currentUserId = ctx.user.id;
+
+ await db
+ .update(user)
+ .set({
+ ...(input.enableEnterpriseFeatures === undefined
+ ? {}
+ : { enableEnterpriseFeatures: input.enableEnterpriseFeatures }),
+ ...(input.licenseKey === undefined
+ ? {}
+ : { licenseKey: input.licenseKey }),
+ })
+ .where(eq(user.id, currentUserId));
+
+ return true;
+ }),
+});