mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-21 07:05:21 +02:00
302 lines
8.1 KiB
TypeScript
302 lines
8.1 KiB
TypeScript
import {
|
|
containerKill,
|
|
containerRemove,
|
|
containerRestart,
|
|
containerStart,
|
|
containerStop,
|
|
findServerById,
|
|
getConfig,
|
|
getContainers,
|
|
getContainersByAppLabel,
|
|
getContainersByAppNameMatch,
|
|
getServiceContainersByAppName,
|
|
getStackContainersByAppName,
|
|
uploadFileToContainer,
|
|
} from "@dokploy/server";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { z } from "zod";
|
|
import { audit } from "@/server/api/utils/audit";
|
|
import { uploadFileToContainerSchema } from "@/utils/schema";
|
|
import { createTRPCRouter, withPermission } from "../trpc";
|
|
|
|
export const containerIdRegex = /^[a-zA-Z0-9.\-_]+$/;
|
|
|
|
export const dockerRouter = createTRPCRouter({
|
|
getContainers: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getContainers(input.serverId);
|
|
}),
|
|
|
|
restartContainer: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerRestart(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "start",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
startContainer: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerStart(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "start",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
stopContainer: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerStop(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "stop",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
killContainer: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerKill(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "stop",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
removeContainer: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerRemove(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "delete",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
getConfig: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getConfig(input.containerId, input.serverId);
|
|
}),
|
|
|
|
getContainersByAppNameMatch: withPermission("service", "read")
|
|
.input(
|
|
z.object({
|
|
appType: z.enum(["stack", "docker-compose"]).optional(),
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getContainersByAppNameMatch(
|
|
input.appName,
|
|
input.appType,
|
|
input.serverId,
|
|
);
|
|
}),
|
|
|
|
getContainersByAppLabel: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
type: z.enum(["standalone", "swarm"]),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getContainersByAppLabel(
|
|
input.appName,
|
|
input.type,
|
|
input.serverId,
|
|
);
|
|
}),
|
|
|
|
getStackContainersByAppName: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getStackContainersByAppName(input.appName, input.serverId);
|
|
}),
|
|
|
|
getServiceContainersByAppName: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getServiceContainersByAppName(input.appName, input.serverId);
|
|
}),
|
|
|
|
uploadFileToContainer: withPermission("docker", "read")
|
|
.input(uploadFileToContainerSchema)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
|
|
const file = input.file;
|
|
if (!(file instanceof File)) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Invalid file provided",
|
|
});
|
|
}
|
|
|
|
// Convert File to Buffer
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const fileBuffer = Buffer.from(arrayBuffer);
|
|
|
|
await uploadFileToContainer(
|
|
input.containerId,
|
|
fileBuffer,
|
|
file.name,
|
|
input.destinationPath,
|
|
input.serverId || null,
|
|
);
|
|
|
|
return { success: true, message: "File uploaded successfully" };
|
|
}),
|
|
});
|