mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Fix/monitoring (#1271)
* refactor: make request to dokploy server to proxy requests * refactor: lint * refactor: use dokploy/monitoring tag image * refactor: use canary in development or canary tags * refactor: adjust logic * refactor: update name
This commit is contained in:
@@ -131,54 +131,59 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between flex-wrap gap-2">
|
||||||
<h2 className="text-2xl font-bold tracking-tight">
|
<h2 className="text-2xl font-bold tracking-tight">
|
||||||
Container Monitoring
|
Container Monitoring
|
||||||
</h2>
|
</h2>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-4 flex-wrap">
|
||||||
<span className="text-sm text-muted-foreground">Data points:</span>
|
<div>
|
||||||
<Select
|
<span className="text-sm text-muted-foreground">Data points:</span>
|
||||||
value={dataPoints}
|
<Select
|
||||||
onValueChange={(value: keyof typeof DATA_POINTS_OPTIONS) =>
|
value={dataPoints}
|
||||||
setDataPoints(value)
|
onValueChange={(value: keyof typeof DATA_POINTS_OPTIONS) =>
|
||||||
}
|
setDataPoints(value)
|
||||||
>
|
}
|
||||||
<SelectTrigger className="w-[180px]">
|
>
|
||||||
<SelectValue placeholder="Select points" />
|
<SelectTrigger className="w-[180px]">
|
||||||
</SelectTrigger>
|
<SelectValue placeholder="Select points" />
|
||||||
<SelectContent>
|
</SelectTrigger>
|
||||||
{Object.entries(DATA_POINTS_OPTIONS).map(([value, label]) => (
|
<SelectContent>
|
||||||
<SelectItem key={value} value={value}>
|
{Object.entries(DATA_POINTS_OPTIONS).map(([value, label]) => (
|
||||||
{label}
|
<SelectItem key={value} value={value}>
|
||||||
</SelectItem>
|
{label}
|
||||||
))}
|
</SelectItem>
|
||||||
</SelectContent>
|
))}
|
||||||
</Select>
|
</SelectContent>
|
||||||
<span className="text-sm text-muted-foreground">
|
</Select>
|
||||||
Refresh interval:
|
</div>
|
||||||
</span>
|
|
||||||
<Select
|
<div>
|
||||||
value={refreshInterval}
|
<span className="text-sm text-muted-foreground">
|
||||||
onValueChange={(value: keyof typeof REFRESH_INTERVALS) =>
|
Refresh interval:
|
||||||
setRefreshInterval(value)
|
</span>
|
||||||
}
|
<Select
|
||||||
>
|
value={refreshInterval}
|
||||||
<SelectTrigger className="w-[180px]">
|
onValueChange={(value: keyof typeof REFRESH_INTERVALS) =>
|
||||||
<SelectValue placeholder="Select interval" />
|
setRefreshInterval(value)
|
||||||
</SelectTrigger>
|
}
|
||||||
<SelectContent>
|
>
|
||||||
{Object.entries(REFRESH_INTERVALS).map(([value, label]) => (
|
<SelectTrigger className="w-[180px]">
|
||||||
<SelectItem key={value} value={value}>
|
<SelectValue placeholder="Select interval" />
|
||||||
{label}
|
</SelectTrigger>
|
||||||
</SelectItem>
|
<SelectContent>
|
||||||
))}
|
{Object.entries(REFRESH_INTERVALS).map(([value, label]) => (
|
||||||
</SelectContent>
|
<SelectItem key={value} value={value}>
|
||||||
</Select>
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Stats Cards */}
|
{/* Stats Cards */}
|
||||||
<div className="grid gap-4 md:grid-cols-4">
|
<div className="grid gap-4 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
|
||||||
<Card className="p-6 bg-transparent">
|
<Card className="p-6 bg-transparent">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Cpu className="h-4 w-4 text-muted-foreground" />
|
<Cpu className="h-4 w-4 text-muted-foreground" />
|
||||||
@@ -236,13 +241,13 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-sm font-medium text-muted-foreground">Name</h4>
|
<h4 className="text-sm font-medium text-muted-foreground">Name</h4>
|
||||||
<p className="mt-1">{metrics.Name}</p>
|
<p className="mt-1 truncate">{metrics.Name}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Charts Grid */}
|
{/* Charts Grid */}
|
||||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-2">
|
<div className="grid gap-4 grid-cols-1 md:grid-cols-1 xl:grid-cols-2">
|
||||||
<ContainerCPUChart data={historicalData} />
|
<ContainerCPUChart data={historicalData} />
|
||||||
<ContainerMemoryChart data={historicalData} />
|
<ContainerMemoryChart data={historicalData} />
|
||||||
<ContainerBlockChart data={historicalData} />
|
<ContainerBlockChart data={historicalData} />
|
||||||
|
|||||||
@@ -151,53 +151,58 @@ export const ShowPaidMonitoring = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4 pt-5 pb-10 w-full px-4">
|
<div className="space-y-4 pt-5 pb-10 w-full md:px-4">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex items-center justify-between flex-wrap gap-2">
|
||||||
<h2 className="text-2xl font-bold tracking-tight">System Monitoring</h2>
|
<h2 className="text-2xl font-bold tracking-tight">System Monitoring</h2>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-4 flex-wrap">
|
||||||
<span className="text-sm text-muted-foreground">Data points:</span>
|
<div>
|
||||||
<Select
|
<span className="text-sm text-muted-foreground">Data points:</span>
|
||||||
value={dataPoints}
|
<Select
|
||||||
onValueChange={(value: keyof typeof DATA_POINTS_OPTIONS) =>
|
value={dataPoints}
|
||||||
setDataPoints(value)
|
onValueChange={(value: keyof typeof DATA_POINTS_OPTIONS) =>
|
||||||
}
|
setDataPoints(value)
|
||||||
>
|
}
|
||||||
<SelectTrigger className="w-[180px]">
|
>
|
||||||
<SelectValue placeholder="Select points" />
|
<SelectTrigger className="w-[180px]">
|
||||||
</SelectTrigger>
|
<SelectValue placeholder="Select points" />
|
||||||
<SelectContent>
|
</SelectTrigger>
|
||||||
{Object.entries(DATA_POINTS_OPTIONS).map(([value, label]) => (
|
<SelectContent>
|
||||||
<SelectItem key={value} value={value}>
|
{Object.entries(DATA_POINTS_OPTIONS).map(([value, label]) => (
|
||||||
{label}
|
<SelectItem key={value} value={value}>
|
||||||
</SelectItem>
|
{label}
|
||||||
))}
|
</SelectItem>
|
||||||
</SelectContent>
|
))}
|
||||||
</Select>
|
</SelectContent>
|
||||||
<span className="text-sm text-muted-foreground">
|
</Select>
|
||||||
Refresh interval:
|
</div>
|
||||||
</span>
|
|
||||||
<Select
|
<div>
|
||||||
value={refreshInterval}
|
<span className="text-sm text-muted-foreground">
|
||||||
onValueChange={(value: keyof typeof REFRESH_INTERVALS) =>
|
Refresh interval:
|
||||||
setRefreshInterval(value)
|
</span>
|
||||||
}
|
<Select
|
||||||
>
|
value={refreshInterval}
|
||||||
<SelectTrigger className="w-[180px]">
|
onValueChange={(value: keyof typeof REFRESH_INTERVALS) =>
|
||||||
<SelectValue placeholder="Select interval" />
|
setRefreshInterval(value)
|
||||||
</SelectTrigger>
|
}
|
||||||
<SelectContent>
|
>
|
||||||
{Object.entries(REFRESH_INTERVALS).map(([value, label]) => (
|
<SelectTrigger className="w-[180px]">
|
||||||
<SelectItem key={value} value={value}>
|
<SelectValue placeholder="Select interval" />
|
||||||
{label}
|
</SelectTrigger>
|
||||||
</SelectItem>
|
<SelectContent>
|
||||||
))}
|
{Object.entries(REFRESH_INTERVALS).map(([value, label]) => (
|
||||||
</SelectContent>
|
<SelectItem key={value} value={value}>
|
||||||
</Select>
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Stats Cards */}
|
{/* Stats Cards */}
|
||||||
<div className="grid gap-4 md:grid-cols-4">
|
<div className="grid gap-4 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
|
||||||
<div className="rounded-lg border text-card-foreground shadow-sm p-6">
|
<div className="rounded-lg border text-card-foreground shadow-sm p-6">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Clock className="h-4 w-4 text-muted-foreground" />
|
<Clock className="h-4 w-4 text-muted-foreground" />
|
||||||
@@ -260,7 +265,7 @@ export const ShowPaidMonitoring = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Charts Grid */}
|
{/* Charts Grid */}
|
||||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-2">
|
<div className="grid gap-4 grid-cols-1 md:grid-cols-1 xl:grid-cols-2">
|
||||||
<CPUChart data={historicalData} />
|
<CPUChart data={historicalData} />
|
||||||
<MemoryChart data={historicalData} />
|
<MemoryChart data={historicalData} />
|
||||||
<DiskChart data={metrics} />
|
<DiskChart data={metrics} />
|
||||||
|
|||||||
@@ -58,7 +58,11 @@ export const getContainers = async (serverId?: string | null) => {
|
|||||||
serverId,
|
serverId,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter((container) => !container.name.includes("dokploy"));
|
.filter(
|
||||||
|
(container) =>
|
||||||
|
!container.name.includes("dokploy") ||
|
||||||
|
container.name.includes("dokploy-monitoring"),
|
||||||
|
);
|
||||||
|
|
||||||
return containers;
|
return containers;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { findServerById } from "@dokploy/server/services/server";
|
import { findServerById } from "@dokploy/server/services/server";
|
||||||
import type { ContainerCreateOptions } from "dockerode";
|
import type { ContainerCreateOptions } from "dockerode";
|
||||||
|
import { IS_CLOUD } from "../constants";
|
||||||
import { findAdminById } from "../services/admin";
|
import { findAdminById } from "../services/admin";
|
||||||
|
import { getDokployImageTag } from "../services/settings";
|
||||||
import { pullImage, pullRemoteImage } from "../utils/docker/utils";
|
import { pullImage, pullRemoteImage } from "../utils/docker/utils";
|
||||||
import { execAsync, execAsyncRemote } from "../utils/process/execAsync";
|
import { execAsync, execAsyncRemote } from "../utils/process/execAsync";
|
||||||
import { getRemoteDocker } from "../utils/servers/remote-docker";
|
import { getRemoteDocker } from "../utils/servers/remote-docker";
|
||||||
@@ -8,8 +10,17 @@ import { getRemoteDocker } from "../utils/servers/remote-docker";
|
|||||||
export const setupMonitoring = async (serverId: string) => {
|
export const setupMonitoring = async (serverId: string) => {
|
||||||
const server = await findServerById(serverId);
|
const server = await findServerById(serverId);
|
||||||
|
|
||||||
const containerName = "mauricio-monitoring";
|
|
||||||
const imageName = "dokploy/monitoring:canary";
|
const containerName = "dokploy-monitoring";
|
||||||
|
let imageName = "dokploy/monitoring:latest";
|
||||||
|
|
||||||
|
if (
|
||||||
|
(getDokployImageTag() !== "latest" ||
|
||||||
|
process.env.NODE_ENV === "development") &&
|
||||||
|
!IS_CLOUD
|
||||||
|
) {
|
||||||
|
imageName = "dokploy/monitoring:canary";
|
||||||
|
}
|
||||||
|
|
||||||
const settings: ContainerCreateOptions = {
|
const settings: ContainerCreateOptions = {
|
||||||
name: containerName,
|
name: containerName,
|
||||||
@@ -73,8 +84,16 @@ export const setupMonitoring = async (serverId: string) => {
|
|||||||
export const setupWebMonitoring = async (adminId: string) => {
|
export const setupWebMonitoring = async (adminId: string) => {
|
||||||
const admin = await findAdminById(adminId);
|
const admin = await findAdminById(adminId);
|
||||||
|
|
||||||
const containerName = "mauricio-monitoring";
|
const containerName = "dokploy-monitoring";
|
||||||
const imageName = "dokploy/monitoring:canary";
|
let imageName = "dokploy/monitoring:latest";
|
||||||
|
|
||||||
|
if (
|
||||||
|
(getDokployImageTag() !== "latest" ||
|
||||||
|
process.env.NODE_ENV === "development") &&
|
||||||
|
!IS_CLOUD
|
||||||
|
) {
|
||||||
|
imageName = "dokploy/monitoring:canary";
|
||||||
|
}
|
||||||
|
|
||||||
const settings: ContainerCreateOptions = {
|
const settings: ContainerCreateOptions = {
|
||||||
name: containerName,
|
name: containerName,
|
||||||
|
|||||||
Reference in New Issue
Block a user