mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-07 06:55:23 +02:00
Merge pull request #3064 from fir4tozden/fix/docker-cleanup-clears-away-all-unused-residue
fix: docker cleanup clears away all unused residue
This commit is contained in:
@@ -56,7 +56,7 @@ export const user = pgTable("user", {
|
||||
host: text("host"),
|
||||
letsEncryptEmail: text("letsEncryptEmail"),
|
||||
sshPrivateKey: text("sshPrivateKey"),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(true),
|
||||
logCleanupCron: text("logCleanupCron").default("0 0 * * *"),
|
||||
role: text("role").notNull().default("user"),
|
||||
// Metrics
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { readdirSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { docker } from "@dokploy/server/constants";
|
||||
import { cleanupAll } from "@dokploy/server/utils/docker/utils";
|
||||
import {
|
||||
execAsync,
|
||||
execAsyncRemote,
|
||||
@@ -215,38 +216,6 @@ echo "$json_output"
|
||||
return result;
|
||||
};
|
||||
|
||||
export const cleanupFullDocker = async (serverId?: string | null) => {
|
||||
const cleanupImages = "docker image prune --force";
|
||||
const cleanupVolumes = "docker volume prune --force";
|
||||
const cleanupContainers = "docker container prune --force";
|
||||
const cleanupSystem = "docker system prune --force --volumes";
|
||||
const cleanupBuilder = "docker builder prune --force";
|
||||
|
||||
try {
|
||||
if (serverId) {
|
||||
await execAsyncRemote(
|
||||
serverId,
|
||||
`
|
||||
${cleanupImages}
|
||||
${cleanupVolumes}
|
||||
${cleanupContainers}
|
||||
${cleanupSystem}
|
||||
${cleanupBuilder}
|
||||
`,
|
||||
);
|
||||
}
|
||||
await execAsync(`
|
||||
${cleanupImages}
|
||||
${cleanupVolumes}
|
||||
${cleanupContainers}
|
||||
${cleanupSystem}
|
||||
${cleanupBuilder}
|
||||
`);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
export const getDockerResourceType = async (
|
||||
resourceName: string,
|
||||
serverId?: string,
|
||||
|
||||
@@ -6,11 +6,7 @@ import { eq } from "drizzle-orm";
|
||||
import { scheduleJob } from "node-schedule";
|
||||
import { db } from "../../db/index";
|
||||
import { startLogCleanup } from "../access-log/handler";
|
||||
import {
|
||||
cleanUpDockerBuilder,
|
||||
cleanUpSystemPrune,
|
||||
cleanUpUnusedImages,
|
||||
} from "../docker/utils";
|
||||
import { cleanupAll } from "../docker/utils";
|
||||
import { sendDockerCleanupNotifications } from "../notifications/docker-cleanup";
|
||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||
import { getS3Credentials, scheduleBackup } from "./utils";
|
||||
@@ -34,9 +30,9 @@ export const initCronJobs = async () => {
|
||||
console.log(
|
||||
`Docker Cleanup ${new Date().toLocaleString()}] Running docker cleanup`,
|
||||
);
|
||||
await cleanUpUnusedImages();
|
||||
await cleanUpDockerBuilder();
|
||||
await cleanUpSystemPrune();
|
||||
|
||||
await cleanupAll();
|
||||
|
||||
await sendDockerCleanupNotifications(admin.user.id);
|
||||
});
|
||||
}
|
||||
@@ -50,9 +46,9 @@ export const initCronJobs = async () => {
|
||||
console.log(
|
||||
`SERVER-BACKUP[${new Date().toLocaleString()}] Running Cleanup ${name}`,
|
||||
);
|
||||
await cleanUpUnusedImages(serverId);
|
||||
await cleanUpDockerBuilder(serverId);
|
||||
await cleanUpSystemPrune(serverId);
|
||||
|
||||
await cleanupAll(serverId);
|
||||
|
||||
await sendDockerCleanupNotifications(
|
||||
admin.user.id,
|
||||
`Docker cleanup for Server ${name} (${serverId})`,
|
||||
|
||||
@@ -144,81 +144,117 @@ export const getContainerByName = (name: string): Promise<ContainerInfo> => {
|
||||
});
|
||||
});
|
||||
};
|
||||
export const cleanUpUnusedImages = async (serverId?: string) => {
|
||||
try {
|
||||
const command = "docker image prune --force";
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
} else {
|
||||
await execAsync(command);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const cleanStoppedContainers = async (serverId?: string) => {
|
||||
/**
|
||||
* Docker commands passed through this method are held during Docker's build or pull process.
|
||||
*
|
||||
* https://github.com/Dokploy/dokploy/pull/3064
|
||||
* https://github.com/fir4tozden
|
||||
*/
|
||||
export const dockerSafeExec = (exec: string) => `CHECK_INTERVAL=10
|
||||
|
||||
echo "Preparing for execution..."
|
||||
|
||||
while true; do
|
||||
PROCESSES=$(ps aux | grep -E "docker build|docker pull" | grep -v grep)
|
||||
|
||||
if [ -z "$PROCESSES" ]; then
|
||||
echo "Docker is idle. Starting execution..."
|
||||
break
|
||||
else
|
||||
echo "Docker is busy. Will check again in $CHECK_INTERVAL seconds..."
|
||||
sleep $CHECK_INTERVAL
|
||||
fi
|
||||
done
|
||||
|
||||
${exec}
|
||||
|
||||
echo "Execution completed."`;
|
||||
|
||||
export const cleanupContainers = async (serverId?: string) => {
|
||||
try {
|
||||
const command = "docker container prune --force";
|
||||
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
await execAsyncRemote(serverId, dockerSafeExec(command));
|
||||
} else {
|
||||
await execAsync(command);
|
||||
await execAsync(dockerSafeExec(command));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const cleanUpUnusedVolumes = async (serverId?: string) => {
|
||||
export const cleanupImages = async (serverId?: string) => {
|
||||
try {
|
||||
const command = "docker volume prune --force";
|
||||
const command = "docker image prune --all --force";
|
||||
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
await execAsyncRemote(serverId, dockerSafeExec(command));
|
||||
} else await execAsync(dockerSafeExec(command));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const cleanupVolumes = async (serverId?: string) => {
|
||||
try {
|
||||
const command = "docker volume prune --all --force";
|
||||
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, dockerSafeExec(command));
|
||||
} else {
|
||||
await execAsync(command);
|
||||
await execAsync(dockerSafeExec(command));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const cleanUpInactiveContainers = async () => {
|
||||
export const cleanupBuilders = async (serverId?: string) => {
|
||||
try {
|
||||
const containers = await docker.listContainers({ all: true });
|
||||
const inactiveContainers = containers.filter(
|
||||
(container) => container.State !== "running",
|
||||
);
|
||||
const command = "docker builder prune --all --force";
|
||||
|
||||
for (const container of inactiveContainers) {
|
||||
await docker.getContainer(container.Id).remove({ force: true });
|
||||
console.log(`Cleaning up inactive container: ${container.Id}`);
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, dockerSafeExec(command));
|
||||
} else {
|
||||
await execAsync(dockerSafeExec(command));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error cleaning up inactive containers:", error);
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const cleanUpDockerBuilder = async (serverId?: string) => {
|
||||
const command = "docker builder prune --all --force";
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
} else {
|
||||
await execAsync(command);
|
||||
export const cleanupSystem = async (serverId?: string) => {
|
||||
try {
|
||||
const command = "docker system prune --all --volumes --force";
|
||||
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, dockerSafeExec(command));
|
||||
} else {
|
||||
await execAsync(dockerSafeExec(command));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const cleanUpSystemPrune = async (serverId?: string) => {
|
||||
const command = "docker system prune --force --volumes";
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
} else {
|
||||
await execAsync(command);
|
||||
}
|
||||
export const cleanupAll = async (serverId?: string) => {
|
||||
await cleanupContainers(serverId);
|
||||
await cleanupImages(serverId);
|
||||
await cleanupVolumes(serverId);
|
||||
await cleanupBuilders(serverId);
|
||||
await cleanupSystem(serverId);
|
||||
};
|
||||
|
||||
export const startService = async (appName: string) => {
|
||||
|
||||
Reference in New Issue
Block a user