mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-19 07:01:35 +00:00
330 lines
10 KiB
TypeScript
330 lines
10 KiB
TypeScript
import {
|
|
execAsync,
|
|
execAsyncRemote,
|
|
} from "@dokploy/server/utils/process/execAsync";
|
|
|
|
export const getContainers = async (serverId?: string | null) => {
|
|
try {
|
|
const command =
|
|
"docker ps -a --format 'CONTAINER ID : {{.ID}} | Name: {{.Names}} | Image: {{.Image}} | Ports: {{.Ports}} | State: {{.State}} | Status: {{.Status}}'";
|
|
let stdout = "";
|
|
let stderr = "";
|
|
|
|
if (serverId) {
|
|
const result = await execAsyncRemote(serverId, command);
|
|
|
|
stdout = result.stdout;
|
|
stderr = result.stderr;
|
|
} else {
|
|
const result = await execAsync(command);
|
|
stdout = result.stdout;
|
|
stderr = result.stderr;
|
|
}
|
|
if (stderr) {
|
|
console.error(`Error: ${stderr}`);
|
|
return;
|
|
}
|
|
|
|
const lines = stdout.trim().split("\n");
|
|
|
|
const containers = lines
|
|
.map((line) => {
|
|
const parts = line.split(" | ");
|
|
const containerId = parts[0]
|
|
? parts[0].replace("CONTAINER ID : ", "").trim()
|
|
: "No container id";
|
|
const name = parts[1]
|
|
? parts[1].replace("Name: ", "").trim()
|
|
: "No container name";
|
|
const image = parts[2]
|
|
? parts[2].replace("Image: ", "").trim()
|
|
: "No image";
|
|
const ports = parts[3]
|
|
? parts[3].replace("Ports: ", "").trim()
|
|
: "No ports";
|
|
const state = parts[4]
|
|
? parts[4].replace("State: ", "").trim()
|
|
: "No state";
|
|
const status = parts[5]
|
|
? parts[5].replace("Status: ", "").trim()
|
|
: "No status";
|
|
return {
|
|
containerId,
|
|
name,
|
|
image,
|
|
ports,
|
|
state,
|
|
status,
|
|
serverId,
|
|
};
|
|
})
|
|
.filter((container) => !container.name.includes("dokploy"));
|
|
|
|
return containers;
|
|
} catch (error) {
|
|
console.error(error);
|
|
|
|
return [];
|
|
}
|
|
};
|
|
|
|
export const getConfig = async (
|
|
containerId: string,
|
|
serverId?: string | null,
|
|
) => {
|
|
try {
|
|
const command = `docker inspect ${containerId} --format='{{json .}}'`;
|
|
let stdout = "";
|
|
let stderr = "";
|
|
if (serverId) {
|
|
const result = await execAsyncRemote(serverId, command);
|
|
stdout = result.stdout;
|
|
stderr = result.stderr;
|
|
} else {
|
|
const result = await execAsync(command);
|
|
stdout = result.stdout;
|
|
stderr = result.stderr;
|
|
}
|
|
|
|
if (stderr) {
|
|
console.error(`Error: ${stderr}`);
|
|
return;
|
|
}
|
|
|
|
const config = JSON.parse(stdout);
|
|
|
|
return config;
|
|
} catch (error) {}
|
|
};
|
|
|
|
export const getContainersByAppNameMatch = async (
|
|
appName: string,
|
|
appType?: "stack" | "docker-compose",
|
|
serverId?: string,
|
|
) => {
|
|
try {
|
|
let result: string[] = [];
|
|
const cmd =
|
|
"docker ps -a --format 'CONTAINER ID : {{.ID}} | Name: {{.Names}} | State: {{.State}}'";
|
|
|
|
const command =
|
|
appType === "docker-compose"
|
|
? `${cmd} --filter='label=com.docker.compose.project=${appName}'`
|
|
: `${cmd} | grep '^.*Name: ${appName}'`;
|
|
if (serverId) {
|
|
const { stdout, stderr } = await execAsyncRemote(serverId, command);
|
|
|
|
if (stderr) {
|
|
return [];
|
|
}
|
|
|
|
if (!stdout) return [];
|
|
result = stdout.trim().split("\n");
|
|
} else {
|
|
const { stdout, stderr } = await execAsync(command);
|
|
|
|
if (stderr) {
|
|
return [];
|
|
}
|
|
|
|
if (!stdout) return [];
|
|
|
|
result = stdout.trim().split("\n");
|
|
}
|
|
|
|
const containers = result.map((line) => {
|
|
const parts = line.split(" | ");
|
|
const containerId = parts[0]
|
|
? parts[0].replace("CONTAINER ID : ", "").trim()
|
|
: "No container id";
|
|
const name = parts[1]
|
|
? parts[1].replace("Name: ", "").trim()
|
|
: "No container name";
|
|
|
|
const state = parts[2]
|
|
? parts[2].replace("State: ", "").trim()
|
|
: "No state";
|
|
return {
|
|
containerId,
|
|
name,
|
|
state,
|
|
};
|
|
});
|
|
|
|
return containers || [];
|
|
} catch (error) {}
|
|
|
|
return [];
|
|
};
|
|
|
|
export const getContainersByAppLabel = async (
|
|
appName: string,
|
|
serverId?: string,
|
|
) => {
|
|
try {
|
|
let stdout = "";
|
|
let stderr = "";
|
|
|
|
const command = `docker ps --filter "label=com.docker.swarm.service.name=${appName}" --format 'CONTAINER ID : {{.ID}} | Name: {{.Names}} | State: {{.State}}'`;
|
|
if (serverId) {
|
|
const result = await execAsyncRemote(serverId, command);
|
|
stdout = result.stdout;
|
|
stderr = result.stderr;
|
|
} else {
|
|
const result = await execAsync(command);
|
|
stdout = result.stdout;
|
|
stderr = result.stderr;
|
|
}
|
|
if (stderr) {
|
|
console.error(`Error: ${stderr}`);
|
|
return;
|
|
}
|
|
|
|
if (!stdout) return [];
|
|
|
|
const lines = stdout.trim().split("\n");
|
|
|
|
const containers = lines.map((line) => {
|
|
const parts = line.split(" | ");
|
|
const containerId = parts[0]
|
|
? parts[0].replace("CONTAINER ID : ", "").trim()
|
|
: "No container id";
|
|
const name = parts[1]
|
|
? parts[1].replace("Name: ", "").trim()
|
|
: "No container name";
|
|
const state = parts[2]
|
|
? parts[2].replace("State: ", "").trim()
|
|
: "No state";
|
|
return {
|
|
containerId,
|
|
name,
|
|
state,
|
|
};
|
|
});
|
|
|
|
return containers || [];
|
|
} catch (error) {}
|
|
|
|
return [];
|
|
};
|
|
|
|
export const containerRestart = async (containerId: string) => {
|
|
try {
|
|
const { stdout, stderr } = await execAsync(
|
|
`docker container restart ${containerId}`,
|
|
);
|
|
|
|
if (stderr) {
|
|
console.error(`Error: ${stderr}`);
|
|
return;
|
|
}
|
|
|
|
const config = JSON.parse(stdout);
|
|
|
|
return config;
|
|
} catch (error) {}
|
|
};
|
|
|
|
export const getSwarmNodes = async () => {
|
|
try {
|
|
const { stdout, stderr } = await execAsync(
|
|
"docker node ls --format '{{json .}}'",
|
|
);
|
|
|
|
if (stderr) {
|
|
console.error(`Error: ${stderr}`);
|
|
return;
|
|
}
|
|
|
|
const nodes = JSON.parse(stdout);
|
|
|
|
const nodesArray = stdout
|
|
.trim()
|
|
.split("\n")
|
|
.map((line) => JSON.parse(line));
|
|
return nodesArray;
|
|
} catch (error) {}
|
|
};
|
|
|
|
export const getNodeInfo = async (nodeId: string) => {
|
|
try {
|
|
const { stdout, stderr } = await execAsync(
|
|
`docker node inspect ${nodeId} --format '{{json .}}'`,
|
|
);
|
|
|
|
if (stderr) {
|
|
console.error(`Error: ${stderr}`);
|
|
return;
|
|
}
|
|
|
|
const nodeInfo = JSON.parse(stdout);
|
|
|
|
return nodeInfo;
|
|
} catch (error) {}
|
|
};
|
|
|
|
export const getNodeApplications = async () => {
|
|
try {
|
|
// TODO: Implement this
|
|
// const { stdout, stderr } = await execAsync(
|
|
// `docker service ls --format '{{json .}}'`
|
|
// );
|
|
|
|
const stdout = `{"ID":"pxvnj68dxom9","Image":"dokploy/dokploy:latest","Mode":"replicated","Name":"dokploy","Ports":"","Replicas":"1/1"}
|
|
{"ID":"1sweo6dr2vrn","Image":"postgres:16","Mode":"replicated","Name":"dokploy-postgres","Ports":"","Replicas":"1/1"}
|
|
{"ID":"tnl2fck3rbop","Image":"redis:7","Mode":"replicated","Name":"dokploy-redis","Ports":"","Replicas":"1/1"}
|
|
{"ID":"o9ady4y1p96x","Image":"traefik:v3.1.2","Mode":"replicated","Name":"dokploy-traefik","Ports":"","Replicas":"1/1"}
|
|
{"ID":"rsxe3l71h9y4","Image":"esports-manager-api-eg8t7w:latest","Mode":"replicated","Name":"esports-manager-api-eg8t7w","Ports":"","Replicas":"1/1"}
|
|
{"ID":"fw52vzcw5dc0","Image":"team-synix-admin-dvgspy:latest","Mode":"replicated","Name":"team-synix-admin-dvgspy","Ports":"","Replicas":"1/1"}
|
|
{"ID":"551bwmtd6b4t","Image":"team-synix-leaderboard-9vx8ca:latest","Mode":"replicated","Name":"team-synix-leaderboard-9vx8ca","Ports":"","Replicas":"1/1"}
|
|
{"ID":"h1eyg3g1tyn3","Image":"postgres:15","Mode":"replicated","Name":"team-synix-webpage-db-fkivnf","Ports":"","Replicas":"1/1"}`;
|
|
|
|
// if (stderr) {
|
|
// console.error(`Error: ${stderr}`);
|
|
// return;
|
|
// }
|
|
|
|
const appArray = stdout
|
|
.trim()
|
|
.split("\n")
|
|
.map((line) => JSON.parse(line));
|
|
|
|
console.log(appArray);
|
|
return appArray;
|
|
} catch (error) {}
|
|
};
|
|
|
|
export const getApplicationInfo = async (appName: string) => {
|
|
try {
|
|
// TODO: Implement this
|
|
// const { stdout, stderr } = await execAsync(
|
|
// `docker service ps ${appName} --format '{{json .}}'`
|
|
// );
|
|
|
|
const stdout = `{"CurrentState":"Running 2 weeks ago","DesiredState":"Running","Error":"","ID":"nx8jxlmb8niw","Image":"postgres:16","Name":"dokploy-postgres.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Running 2 weeks ago","DesiredState":"Running","Error":"","ID":"s288g9lwtvi4","Image":"redis:7","Name":"dokploy-redis.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Running 2 weeks ago","DesiredState":"Running","Error":"","ID":"2vcmejz51b23","Image":"traefik:v3.1.2","Name":"dokploy-traefik.1","Node":"v2202411192718297480","Ports":"*:80-\u003e80/tcp,*:80-\u003e80/tcp,*:443-\u003e443/tcp,*:443-\u003e443/tcp"}
|
|
{"CurrentState":"Running 26 hours ago","DesiredState":"Running","Error":"","ID":"79iatnbsm2um","Image":"dokploy/dokploy:latest","Name":"dokploy.1","Node":"v2202411192718297480","Ports":"*:3000-\u003e3000/tcp,*:3000-\u003e3000/tcp"}
|
|
{"CurrentState":"Shutdown 26 hours ago","DesiredState":"Shutdown","Error":"","ID":"zcwxs501zs7w","Image":"dokploy/dokploy:latest","Name":"dokploy.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Shutdown 7 days ago","DesiredState":"Shutdown","Error":"","ID":"t59qhkoenno4","Image":"dokploy/dokploy:latest","Name":"dokploy.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Shutdown 7 days ago","DesiredState":"Shutdown","Error":"","ID":"o5xtcuj6um7e","Image":"dokploy/dokploy:latest","Name":"dokploy.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Running 2 weeks ago","DesiredState":"Running","Error":"","ID":"q1lr9rmf452g","Image":"esports-manager-api-eg8t7w:latest","Name":"esports-manager-api-eg8t7w.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Shutdown 2 weeks ago","DesiredState":"Shutdown","Error":"","ID":"y9ixpg6b8qdo","Image":"esports-manager-api-eg8t7w:latest","Name":"esports-manager-api-eg8t7w.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Running 24 hours ago","DesiredState":"Running","Error":"","ID":"xgcb919qjg1a","Image":"team-synix-admin-dvgspy:latest","Name":"team-synix-admin-dvgspy.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Running 26 hours ago","DesiredState":"Running","Error":"","ID":"7yi95wh8zhh6","Image":"team-synix-leaderboard-9vx8ca:latest","Name":"team-synix-leaderboard-9vx8ca.1","Node":"v2202411192718297480","Ports":""}
|
|
{"CurrentState":"Running 2 weeks ago","DesiredState":"Running","Error":"","ID":"89yzsnghpbq6","Image":"postgres:15","Name":"team-synix-webpage-db-fkivnf.1","Node":"v2202411192718297480","Ports":""}`;
|
|
|
|
// if (stderr) {
|
|
// console.error(`Error: ${stderr}`);
|
|
// return;
|
|
// }
|
|
|
|
const appArray = stdout
|
|
.trim()
|
|
.split("\n")
|
|
.map((line) => JSON.parse(line));
|
|
|
|
return appArray;
|
|
} catch (error) {}
|
|
};
|