mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
fix: add docker cleanup toggle to remote server creation (#4559)
* fix: add docker cleanup toggle to remote server creation and update forms * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -200,7 +200,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
|||||||
Time between health checks (e.g., 10000000000 for 10 seconds)
|
Time between health checks (e.g., 10000000000 for 10 seconds)
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="number" placeholder="10000000000" {...field} value={field.value ?? ""} />
|
<Input
|
||||||
|
type="number"
|
||||||
|
placeholder="10000000000"
|
||||||
|
{...field}
|
||||||
|
value={field.value ?? ""}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -217,7 +222,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
|||||||
Maximum time to wait for health check response
|
Maximum time to wait for health check response
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="number" placeholder="10000000000" {...field} value={field.value ?? ""} />
|
<Input
|
||||||
|
type="number"
|
||||||
|
placeholder="10000000000"
|
||||||
|
{...field}
|
||||||
|
value={field.value ?? ""}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -234,7 +244,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
|||||||
Initial grace period before health checks begin
|
Initial grace period before health checks begin
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="number" placeholder="10000000000" {...field} value={field.value ?? ""} />
|
<Input
|
||||||
|
type="number"
|
||||||
|
placeholder="10000000000"
|
||||||
|
{...field}
|
||||||
|
value={field.value ?? ""}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -252,7 +267,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
|
|||||||
unhealthy
|
unhealthy
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="number" placeholder="3" {...field} value={field.value ?? ""} />
|
<Input
|
||||||
|
type="number"
|
||||||
|
placeholder="3"
|
||||||
|
{...field}
|
||||||
|
value={field.value ?? ""}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ const Schema = z.object({
|
|||||||
message: "SSH Key is required",
|
message: "SSH Key is required",
|
||||||
}),
|
}),
|
||||||
serverType: z.enum(["deploy", "build"]).default("deploy"),
|
serverType: z.enum(["deploy", "build"]).default("deploy"),
|
||||||
|
enableDockerCleanup: z.boolean().default(true),
|
||||||
});
|
});
|
||||||
|
|
||||||
type Schema = z.infer<typeof Schema>;
|
type Schema = z.infer<typeof Schema>;
|
||||||
@@ -90,6 +92,7 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
|
|||||||
username: "root",
|
username: "root",
|
||||||
sshKeyId: "",
|
sshKeyId: "",
|
||||||
serverType: "deploy",
|
serverType: "deploy",
|
||||||
|
enableDockerCleanup: true,
|
||||||
},
|
},
|
||||||
resolver: zodResolver(Schema),
|
resolver: zodResolver(Schema),
|
||||||
});
|
});
|
||||||
@@ -103,6 +106,7 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
|
|||||||
username: data?.username || "root",
|
username: data?.username || "root",
|
||||||
sshKeyId: data?.sshKeyId || "",
|
sshKeyId: data?.sshKeyId || "",
|
||||||
serverType: data?.serverType || "deploy",
|
serverType: data?.serverType || "deploy",
|
||||||
|
enableDockerCleanup: data?.enableDockerCleanup ?? true,
|
||||||
});
|
});
|
||||||
}, [form, form.reset, form.formState.isSubmitSuccessful, data]);
|
}, [form, form.reset, form.formState.isSubmitSuccessful, data]);
|
||||||
|
|
||||||
@@ -119,6 +123,7 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
|
|||||||
username: data.username || "root",
|
username: data.username || "root",
|
||||||
sshKeyId: data.sshKeyId || "",
|
sshKeyId: data.sshKeyId || "",
|
||||||
serverType: data.serverType || "deploy",
|
serverType: data.serverType || "deploy",
|
||||||
|
enableDockerCleanup: data.enableDockerCleanup,
|
||||||
serverId: serverId || "",
|
serverId: serverId || "",
|
||||||
})
|
})
|
||||||
.then(async (_data) => {
|
.then(async (_data) => {
|
||||||
@@ -418,6 +423,27 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="enableDockerCleanup"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
|
||||||
|
<div className="space-y-0.5">
|
||||||
|
<FormLabel>Enable Docker Cleanup</FormLabel>
|
||||||
|
<FormDescription>
|
||||||
|
Automatically prune unused Docker images daily. Keeps disk
|
||||||
|
usage in check on this remote server.
|
||||||
|
</FormDescription>
|
||||||
|
</div>
|
||||||
|
<FormControl>
|
||||||
|
<Switch
|
||||||
|
checked={field.value}
|
||||||
|
onCheckedChange={field.onChange}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import {
|
|||||||
redis,
|
redis,
|
||||||
server,
|
server,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
|
import { applyDockerCleanupSchedule } from "@/server/utils/docker-cleanup";
|
||||||
|
|
||||||
export const serverRouter = createTRPCRouter({
|
export const serverRouter = createTRPCRouter({
|
||||||
create: withPermission("server", "create")
|
create: withPermission("server", "create")
|
||||||
@@ -63,6 +64,11 @@ export const serverRouter = createTRPCRouter({
|
|||||||
input,
|
input,
|
||||||
ctx.session.activeOrganizationId,
|
ctx.session.activeOrganizationId,
|
||||||
);
|
);
|
||||||
|
await applyDockerCleanupSchedule(
|
||||||
|
project.serverId,
|
||||||
|
ctx.session.activeOrganizationId,
|
||||||
|
input.enableDockerCleanup,
|
||||||
|
);
|
||||||
await audit(ctx, {
|
await audit(ctx, {
|
||||||
action: "create",
|
action: "create",
|
||||||
resourceType: "server",
|
resourceType: "server",
|
||||||
@@ -456,6 +462,12 @@ export const serverRouter = createTRPCRouter({
|
|||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await applyDockerCleanupSchedule(
|
||||||
|
input.serverId,
|
||||||
|
ctx.session.activeOrganizationId,
|
||||||
|
input.enableDockerCleanup,
|
||||||
|
);
|
||||||
|
|
||||||
await audit(ctx, {
|
await audit(ctx, {
|
||||||
action: "update",
|
action: "update",
|
||||||
resourceType: "server",
|
resourceType: "server",
|
||||||
|
|||||||
39
apps/dokploy/server/utils/docker-cleanup.ts
Normal file
39
apps/dokploy/server/utils/docker-cleanup.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
CLEANUP_CRON_JOB,
|
||||||
|
cleanupAll,
|
||||||
|
IS_CLOUD,
|
||||||
|
sendDockerCleanupNotifications,
|
||||||
|
} from "@dokploy/server";
|
||||||
|
import { scheduledJobs, scheduleJob } from "node-schedule";
|
||||||
|
import { removeJob, schedule } from "./backup";
|
||||||
|
|
||||||
|
export const applyDockerCleanupSchedule = async (
|
||||||
|
serverId: string,
|
||||||
|
organizationId: string,
|
||||||
|
enable: boolean,
|
||||||
|
) => {
|
||||||
|
if (enable) {
|
||||||
|
if (IS_CLOUD) {
|
||||||
|
await schedule({
|
||||||
|
cronSchedule: CLEANUP_CRON_JOB,
|
||||||
|
serverId,
|
||||||
|
type: "server",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
scheduleJob(serverId, CLEANUP_CRON_JOB, async () => {
|
||||||
|
await cleanupAll(serverId);
|
||||||
|
await sendDockerCleanupNotifications(organizationId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (IS_CLOUD) {
|
||||||
|
await removeJob({
|
||||||
|
cronSchedule: CLEANUP_CRON_JOB,
|
||||||
|
serverId,
|
||||||
|
type: "server",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
scheduledJobs[serverId]?.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -147,8 +147,12 @@ export const apiCreateServer = createSchema
|
|||||||
username: true,
|
username: true,
|
||||||
sshKeyId: true,
|
sshKeyId: true,
|
||||||
serverType: true,
|
serverType: true,
|
||||||
|
enableDockerCleanup: true,
|
||||||
})
|
})
|
||||||
.required();
|
.required()
|
||||||
|
.extend({
|
||||||
|
enableDockerCleanup: z.boolean().default(true),
|
||||||
|
});
|
||||||
|
|
||||||
export const apiFindOneServer = z.object({
|
export const apiFindOneServer = z.object({
|
||||||
serverId: z.string().min(1),
|
serverId: z.string().min(1),
|
||||||
@@ -170,10 +174,12 @@ export const apiUpdateServer = createSchema
|
|||||||
username: true,
|
username: true,
|
||||||
sshKeyId: true,
|
sshKeyId: true,
|
||||||
serverType: true,
|
serverType: true,
|
||||||
|
enableDockerCleanup: true,
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
.extend({
|
.extend({
|
||||||
command: z.string().optional(),
|
command: z.string().optional(),
|
||||||
|
enableDockerCleanup: z.boolean().default(true),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const apiUpdateServerMonitoring = createSchema
|
export const apiUpdateServerMonitoring = createSchema
|
||||||
|
|||||||
Reference in New Issue
Block a user