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:
Mauricio Siu
2026-06-06 14:21:57 -06:00
committed by GitHub
parent 57ef96a458
commit e6fc3db08f
5 changed files with 108 additions and 5 deletions
@@ -200,7 +200,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
Time between health checks (e.g., 10000000000 for 10 seconds)
</FormDescription>
<FormControl>
<Input type="number" placeholder="10000000000" {...field} value={field.value ?? ""} />
<Input
type="number"
placeholder="10000000000"
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
@@ -217,7 +222,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
Maximum time to wait for health check response
</FormDescription>
<FormControl>
<Input type="number" placeholder="10000000000" {...field} value={field.value ?? ""} />
<Input
type="number"
placeholder="10000000000"
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
@@ -234,7 +244,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
Initial grace period before health checks begin
</FormDescription>
<FormControl>
<Input type="number" placeholder="10000000000" {...field} value={field.value ?? ""} />
<Input
type="number"
placeholder="10000000000"
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
@@ -252,7 +267,12 @@ export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => {
unhealthy
</FormDescription>
<FormControl>
<Input type="number" placeholder="3" {...field} value={field.value ?? ""} />
<Input
type="number"
placeholder="3"
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
@@ -36,6 +36,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
@@ -53,6 +54,7 @@ const Schema = z.object({
message: "SSH Key is required",
}),
serverType: z.enum(["deploy", "build"]).default("deploy"),
enableDockerCleanup: z.boolean().default(true),
});
type Schema = z.infer<typeof Schema>;
@@ -90,6 +92,7 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
username: "root",
sshKeyId: "",
serverType: "deploy",
enableDockerCleanup: true,
},
resolver: zodResolver(Schema),
});
@@ -103,6 +106,7 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
username: data?.username || "root",
sshKeyId: data?.sshKeyId || "",
serverType: data?.serverType || "deploy",
enableDockerCleanup: data?.enableDockerCleanup ?? true,
});
}, [form, form.reset, form.formState.isSubmitSuccessful, data]);
@@ -119,6 +123,7 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
username: data.username || "root",
sshKeyId: data.sshKeyId || "",
serverType: data.serverType || "deploy",
enableDockerCleanup: data.enableDockerCleanup,
serverId: serverId || "",
})
.then(async (_data) => {
@@ -418,6 +423,27 @@ export const HandleServers = ({ serverId, asButton = false }: Props) => {
</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>
<DialogFooter>
+12
View File
@@ -45,6 +45,7 @@ import {
redis,
server,
} from "@/server/db/schema";
import { applyDockerCleanupSchedule } from "@/server/utils/docker-cleanup";
export const serverRouter = createTRPCRouter({
create: withPermission("server", "create")
@@ -63,6 +64,11 @@ export const serverRouter = createTRPCRouter({
input,
ctx.session.activeOrganizationId,
);
await applyDockerCleanupSchedule(
project.serverId,
ctx.session.activeOrganizationId,
input.enableDockerCleanup,
);
await audit(ctx, {
action: "create",
resourceType: "server",
@@ -456,6 +462,12 @@ export const serverRouter = createTRPCRouter({
...input,
});
await applyDockerCleanupSchedule(
input.serverId,
ctx.session.activeOrganizationId,
input.enableDockerCleanup,
);
await audit(ctx, {
action: "update",
resourceType: "server",
@@ -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();
}
}
};
+7 -1
View File
@@ -147,8 +147,12 @@ export const apiCreateServer = createSchema
username: true,
sshKeyId: true,
serverType: true,
enableDockerCleanup: true,
})
.required();
.required()
.extend({
enableDockerCleanup: z.boolean().default(true),
});
export const apiFindOneServer = z.object({
serverId: z.string().min(1),
@@ -170,10 +174,12 @@ export const apiUpdateServer = createSchema
username: true,
sshKeyId: true,
serverType: true,
enableDockerCleanup: true,
})
.required()
.extend({
command: z.string().optional(),
enableDockerCleanup: z.boolean().default(true),
});
export const apiUpdateServerMonitoring = createSchema