mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge branch 'canary' into feature/delete-docker-volumes
This commit is contained in:
@@ -21,6 +21,7 @@ import { mysqlRouter } from "./routers/mysql";
|
||||
import { notificationRouter } from "./routers/notification";
|
||||
import { portRouter } from "./routers/port";
|
||||
import { postgresRouter } from "./routers/postgres";
|
||||
import { previewDeploymentRouter } from "./routers/preview-deployment";
|
||||
import { projectRouter } from "./routers/project";
|
||||
import { redirectsRouter } from "./routers/redirects";
|
||||
import { redisRouter } from "./routers/redis";
|
||||
@@ -30,8 +31,8 @@ import { serverRouter } from "./routers/server";
|
||||
import { settingsRouter } from "./routers/settings";
|
||||
import { sshRouter } from "./routers/ssh-key";
|
||||
import { stripeRouter } from "./routers/stripe";
|
||||
import { swarmRouter } from "./routers/swarm";
|
||||
import { userRouter } from "./routers/user";
|
||||
import { previewDeploymentRouter } from "./routers/preview-deployment";
|
||||
|
||||
/**
|
||||
* This is the primary router for your server.
|
||||
@@ -73,6 +74,7 @@ export const appRouter = createTRPCRouter({
|
||||
github: githubRouter,
|
||||
server: serverRouter,
|
||||
stripe: stripeRouter,
|
||||
swarm: swarmRouter,
|
||||
});
|
||||
|
||||
// export type definition of API
|
||||
|
||||
@@ -188,9 +188,9 @@ export const authRouter = createTRPCRouter({
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const currentAuth = await findAuthByEmail(ctx.user.email);
|
||||
|
||||
if (input.password) {
|
||||
if (input.currentPassword || input.password) {
|
||||
const correctPassword = bcrypt.compareSync(
|
||||
input.password,
|
||||
input.currentPassword || "",
|
||||
currentAuth?.password || "",
|
||||
);
|
||||
if (!correctPassword) {
|
||||
@@ -268,7 +268,9 @@ export const authRouter = createTRPCRouter({
|
||||
|
||||
return auth;
|
||||
}),
|
||||
|
||||
verifyToken: protectedProcedure.mutation(async () => {
|
||||
return true;
|
||||
}),
|
||||
one: adminProcedure.input(apiFindOneAuth).query(async ({ input }) => {
|
||||
const auth = await findAuthById(input.id);
|
||||
return auth;
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from "@/server/db/schema";
|
||||
import { removeJob, schedule } from "@/server/utils/backup";
|
||||
import {
|
||||
DEFAULT_UPDATE_DATA,
|
||||
IS_CLOUD,
|
||||
canAccessToTraefikFiles,
|
||||
cleanStoppedContainers,
|
||||
@@ -25,6 +26,8 @@ import {
|
||||
findAdminById,
|
||||
findServerById,
|
||||
getDokployImage,
|
||||
getDokployImageTag,
|
||||
getUpdateData,
|
||||
initializeTraefik,
|
||||
logRotationManager,
|
||||
parseRawConfig,
|
||||
@@ -267,11 +270,11 @@ export const settingsRouter = createTRPCRouter({
|
||||
message: "You are not authorized to access this admin",
|
||||
});
|
||||
}
|
||||
await updateAdmin(ctx.user.authId, {
|
||||
const adminUpdated = await updateAdmin(ctx.user.authId, {
|
||||
enableDockerCleanup: input.enableDockerCleanup,
|
||||
});
|
||||
|
||||
if (admin.enableDockerCleanup) {
|
||||
if (adminUpdated?.enableDockerCleanup) {
|
||||
scheduleJob("docker-cleanup", "0 0 * * *", async () => {
|
||||
console.log(
|
||||
`Docker Cleanup ${new Date().toLocaleString()}] Running...`,
|
||||
@@ -342,17 +345,20 @@ export const settingsRouter = createTRPCRouter({
|
||||
writeConfig("middlewares", input.traefikConfig);
|
||||
return true;
|
||||
}),
|
||||
|
||||
checkAndUpdateImage: adminProcedure.mutation(async () => {
|
||||
getUpdateData: adminProcedure.mutation(async () => {
|
||||
if (IS_CLOUD) {
|
||||
return true;
|
||||
return DEFAULT_UPDATE_DATA;
|
||||
}
|
||||
return await pullLatestRelease();
|
||||
|
||||
return await getUpdateData();
|
||||
}),
|
||||
updateServer: adminProcedure.mutation(async () => {
|
||||
if (IS_CLOUD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await pullLatestRelease();
|
||||
|
||||
await spawnAsync("docker", [
|
||||
"service",
|
||||
"update",
|
||||
@@ -361,12 +367,16 @@ export const settingsRouter = createTRPCRouter({
|
||||
getDokployImage(),
|
||||
"dokploy",
|
||||
]);
|
||||
|
||||
return true;
|
||||
}),
|
||||
|
||||
getDokployVersion: adminProcedure.query(() => {
|
||||
return packageInfo.version;
|
||||
}),
|
||||
getReleaseTag: adminProcedure.query(() => {
|
||||
return getDokployImageTag();
|
||||
}),
|
||||
readDirectories: protectedProcedure
|
||||
.input(apiServerSchema)
|
||||
.query(async ({ ctx, input }) => {
|
||||
@@ -706,6 +716,83 @@ export const settingsRouter = createTRPCRouter({
|
||||
throw new Error("Failed to check GPU status");
|
||||
}
|
||||
}),
|
||||
updateTraefikPorts: adminProcedure
|
||||
.input(
|
||||
z.object({
|
||||
serverId: z.string().optional(),
|
||||
additionalPorts: z.array(
|
||||
z.object({
|
||||
targetPort: z.number(),
|
||||
publishedPort: z.number(),
|
||||
publishMode: z.enum(["ingress", "host"]).default("host"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
if (IS_CLOUD && !input.serverId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "Please set a serverId to update Traefik ports",
|
||||
});
|
||||
}
|
||||
await initializeTraefik({
|
||||
serverId: input.serverId,
|
||||
additionalPorts: input.additionalPorts,
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Error to update Traefik ports",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
getTraefikPorts: adminProcedure
|
||||
.input(apiServerSchema)
|
||||
.query(async ({ input }) => {
|
||||
const command = `docker service inspect --format='{{json .Endpoint.Ports}}' dokploy-traefik`;
|
||||
|
||||
try {
|
||||
let stdout = "";
|
||||
if (input?.serverId) {
|
||||
const result = await execAsyncRemote(input.serverId, command);
|
||||
stdout = result.stdout;
|
||||
} else if (!IS_CLOUD) {
|
||||
const result = await execAsync(command);
|
||||
stdout = result.stdout;
|
||||
}
|
||||
|
||||
const ports: {
|
||||
Protocol: string;
|
||||
TargetPort: number;
|
||||
PublishedPort: number;
|
||||
PublishMode: string;
|
||||
}[] = JSON.parse(stdout.trim());
|
||||
|
||||
// Filter out the default ports (80, 443, and optionally 8080)
|
||||
const additionalPorts = ports
|
||||
.filter((port) => ![80, 443, 8080].includes(port.PublishedPort))
|
||||
.map((port) => ({
|
||||
targetPort: port.TargetPort,
|
||||
publishedPort: port.PublishedPort,
|
||||
publishMode: port.PublishMode.toLowerCase() as "host" | "ingress",
|
||||
}));
|
||||
|
||||
return additionalPorts;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Failed to get Traefik ports",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
});
|
||||
// {
|
||||
// "Parallelism": 1,
|
||||
|
||||
44
apps/dokploy/server/api/routers/swarm.ts
Normal file
44
apps/dokploy/server/api/routers/swarm.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import {
|
||||
getApplicationInfo,
|
||||
getNodeApplications,
|
||||
getNodeInfo,
|
||||
getSwarmNodes,
|
||||
} from "@dokploy/server";
|
||||
import { z } from "zod";
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
|
||||
export const swarmRouter = createTRPCRouter({
|
||||
getNodes: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
serverId: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
return await getSwarmNodes(input.serverId);
|
||||
}),
|
||||
getNodeInfo: protectedProcedure
|
||||
.input(z.object({ nodeId: z.string(), serverId: z.string().optional() }))
|
||||
.query(async ({ input }) => {
|
||||
return await getNodeInfo(input.nodeId, input.serverId);
|
||||
}),
|
||||
getNodeApps: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
serverId: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
return getNodeApplications(input.serverId);
|
||||
}),
|
||||
getAppInfos: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
appName: z.string(),
|
||||
serverId: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
return await getApplicationInfo(input.appName, input.serverId);
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user