From 0c8c0844b1c1cc1e29998220549272e71d693667 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:32:37 -0600 Subject: [PATCH 1/6] refactor: make request to dokploy server to proxy requests --- .../show-paid-container-monitoring.tsx | 115 +++++----------- .../paid/servers/show-paid-monitoring.tsx | 127 +++++++----------- .../services/application/[applicationId].tsx | 2 + .../services/compose/[composeId].tsx | 2 +- .../services/mariadb/[mariadbId].tsx | 2 +- .../[projectId]/services/mongo/[mongoId].tsx | 2 +- .../[projectId]/services/mysql/[mysqlId].tsx | 2 +- .../services/postgres/[postgresId].tsx | 2 +- .../[projectId]/services/redis/[redisId].tsx | 2 +- apps/dokploy/server/api/routers/admin.ts | 118 ++++++++++++++++ 10 files changed, 209 insertions(+), 165 deletions(-) diff --git a/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx b/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx index c49be0c4..194bf720 100644 --- a/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx +++ b/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx @@ -12,6 +12,7 @@ import { ContainerBlockChart } from "./container-block-chart"; import { ContainerCPUChart } from "./container-cpu-chart"; import { ContainerMemoryChart } from "./container-memory-chart"; import { ContainerNetworkChart } from "./container-network-chart"; +import { api } from "@/utils/api"; const REFRESH_INTERVALS = { "5000": "5 Seconds", @@ -70,84 +71,36 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => { const [metrics, setMetrics] = useState( {} as ContainerMetric, ); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(null); const [dataPoints, setDataPoints] = useState("50"); const [refreshInterval, setRefreshInterval] = useState("5000"); - const fetchMetrics = async () => { - try { - const url = new URL(`${baseUrl}/metrics/containers`); - - // if (dataPoints !== "all") { - url.searchParams.append("limit", dataPoints); - // } - - if (!appName) { - throw new Error( - [ - "No Application Selected:", - "", - "Make Sure to select an application to monitor.", - ].join("\n"), - ); - } - - url.searchParams.append("appName", appName); - - const response = await fetch(url.toString(), { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - - if (!response.ok) { - throw new Error( - `Error ${response.status}: ${response.statusText}. Please verify that the application "${appName}" is running and this service is included in the monitoring configuration.`, - ); - } - - const data = await response.json(); - if (!Array.isArray(data) || data.length === 0) { - throw new Error( - [ - `No monitoring data available for "${appName}". This could be because:`, - "", - "1. The container was recently started - wait a few minutes for data to be collected", - "2. The container is not running - verify its status", - "3. The service is not included in your monitoring configuration", - ].join("\n"), - ); - } - - setHistoricalData(data); - setMetrics(data[data.length - 1]); - setError(null); - } catch (err) { - setError( - err instanceof Error - ? err.message - : "Failed to fetch metrics, Please check your monitoring Instance is Configured correctly.", - ); - } finally { - setIsLoading(false); - } - }; + const { + data, + isLoading, + error: queryError, + } = api.admin.getContainerMetrics.useQuery( + { + url: baseUrl, + token, + dataPoints, + appName, + }, + { + refetchInterval: + dataPoints === "all" ? undefined : Number.parseInt(refreshInterval), + enabled: !!appName, + }, + ); useEffect(() => { - fetchMetrics(); + if (!data) return; - if (dataPoints === "all") { - return; - } - - const interval = setInterval(() => { - fetchMetrics(); - }, Number(refreshInterval)); - - return () => clearInterval(interval); - }, [dataPoints, appName, token, refreshInterval]); + // @ts-ignore + setHistoricalData(data); + // @ts-ignore + setMetrics(data[data.length - 1]); + }, [data]); if (isLoading) { return ( @@ -157,7 +110,7 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => { ); } - if (error) { + if (queryError) { return (
@@ -166,7 +119,9 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => { {appName}

- {error} + {queryError instanceof Error + ? queryError.message + : "Failed to fetch metrics, Please check your monitoring Instance is Configured correctly."}

URL: {baseUrl}

@@ -238,11 +193,11 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => {

Memory Usage

- {metrics.Memory.percentage}% + {metrics?.Memory?.percentage}%

- {metrics.Memory.used} {metrics.Memory.unit} / {metrics.Memory.total}{" "} - {metrics.Memory.unit} + {metrics?.Memory?.used} {metrics?.Memory?.unit} /{" "} + {metrics?.Memory?.total} {metrics?.Memory?.unit}

@@ -252,8 +207,8 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => {

Network I/O

- {metrics.Network.input} {metrics.Network.inputUnit} /{" "} - {metrics.Network.output} {metrics.Network.outputUnit} + {metrics?.Network?.input} {metrics?.Network?.inputUnit} /{" "} + {metrics?.Network?.output} {metrics?.Network?.outputUnit}

@@ -263,8 +218,8 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => {

Block I/O

- {metrics.BlockIO.read} {metrics.BlockIO.readUnit} /{" "} - {metrics.BlockIO.write} {metrics.BlockIO.writeUnit} + {metrics?.BlockIO?.read} {metrics?.BlockIO?.readUnit} /{" "} + {metrics?.BlockIO?.write} {metrics?.BlockIO?.writeUnit}

diff --git a/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx b/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx index 90148dfa..096df998 100644 --- a/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx +++ b/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx @@ -12,6 +12,7 @@ import { CPUChart } from "./cpu-chart"; import { DiskChart } from "./disk-chart"; import { MemoryChart } from "./memory-chart"; import { NetworkChart } from "./network-chart"; +import { api } from "@/utils/api"; const REFRESH_INTERVALS = { "5000": "5 Seconds", @@ -64,76 +65,56 @@ export const ShowPaidMonitoring = ({ }: Props) => { const [historicalData, setHistoricalData] = useState([]); const [metrics, setMetrics] = useState({} as SystemMetrics); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(null); const [dataPoints, setDataPoints] = useState("50"); const [refreshInterval, setRefreshInterval] = useState("5000"); - const fetchMetrics = async () => { - try { - const url = new URL(BASE_URL); - url.searchParams.append("limit", dataPoints); - const response = await fetch(url.toString(), { - headers: { - Authorization: `Bearer ${token}`, - }, - }); + const { + data, + isLoading, + error: queryError, + } = api.admin.getServerMetrics.useQuery( + { + url: BASE_URL, + token, + dataPoints, + }, + { + refetchInterval: + dataPoints === "all" ? undefined : Number.parseInt(refreshInterval), + enabled: true, + }, + ); - if (!response.ok) { - throw new Error( - `Error ${response.status}: ${response.statusText}. Ensure the container is running and this service is included in the monitoring configuration.`, - ); - } + useEffect(() => { + if (!data) return; - const data = await response.json(); - if (!Array.isArray(data) || data.length === 0) { - throw new Error( - [ - "No monitoring data available. This could be because:", - "", - "1. You don't have setup the monitoring service, you can do in web server section.", - "2. If you already have setup the monitoring service, wait a few minutes and refresh the page.", - ].join("\n"), - ); - } + const formattedData = data.map((metric: SystemMetrics) => ({ + timestamp: metric.timestamp, + cpu: Number.parseFloat(metric.cpu), + cpuModel: metric.cpuModel, + cpuCores: metric.cpuCores, + cpuPhysicalCores: metric.cpuPhysicalCores, + cpuSpeed: metric.cpuSpeed, + os: metric.os, + distro: metric.distro, + kernel: metric.kernel, + arch: metric.arch, + memUsed: Number.parseFloat(metric.memUsed), + memUsedGB: Number.parseFloat(metric.memUsedGB), + memTotal: Number.parseFloat(metric.memTotal), + networkIn: Number.parseFloat(metric.networkIn), + networkOut: Number.parseFloat(metric.networkOut), + diskUsed: Number.parseFloat(metric.diskUsed), + totalDisk: Number.parseFloat(metric.totalDisk), + uptime: metric.uptime, + })); - const formattedData = data.map((metric: SystemMetrics) => ({ - timestamp: metric.timestamp, - cpu: Number.parseFloat(metric.cpu), - cpuModel: metric.cpuModel, - cpuCores: metric.cpuCores, - cpuPhysicalCores: metric.cpuPhysicalCores, - cpuSpeed: metric.cpuSpeed, - os: metric.os, - distro: metric.distro, - kernel: metric.kernel, - arch: metric.arch, - memUsed: Number.parseFloat(metric.memUsed), - memUsedGB: Number.parseFloat(metric.memUsedGB), - memTotal: Number.parseFloat(metric.memTotal), - networkIn: Number.parseFloat(metric.networkIn), - networkOut: Number.parseFloat(metric.networkOut), - diskUsed: Number.parseFloat(metric.diskUsed), - totalDisk: Number.parseFloat(metric.totalDisk), - uptime: metric.uptime, - })); - - // @ts-ignore - setHistoricalData(formattedData); - // @ts-ignore - setMetrics(formattedData[formattedData.length - 1] || {}); - setError(null); - } catch (err) { - setError( - err instanceof Error - ? err.message - : "Failed to fetch metrics, Please check your monitoring Instance is Configured correctly.", - ); - } finally { - setIsLoading(false); - } - }; + // @ts-ignore + setHistoricalData(formattedData); + // @ts-ignore + setMetrics(formattedData[formattedData.length - 1] || {}); + }, [data]); const formatUptime = (seconds: number): string => { const days = Math.floor(seconds / (24 * 60 * 60)); @@ -143,20 +124,6 @@ export const ShowPaidMonitoring = ({ return `${days}d ${hours}h ${minutes}m`; }; - useEffect(() => { - fetchMetrics(); - - if (dataPoints === "all") { - return; - } - - const interval = setInterval(() => { - fetchMetrics(); - }, Number(refreshInterval)); - - return () => clearInterval(interval); - }, [dataPoints, token, refreshInterval]); - if (isLoading) { return (
@@ -165,7 +132,7 @@ export const ShowPaidMonitoring = ({ ); } - if (error) { + if (queryError) { return (
@@ -173,7 +140,9 @@ export const ShowPaidMonitoring = ({ Error fetching metrics{" "}

- {error} + {queryError instanceof Error + ? queryError.message + : "Failed to fetch metrics, Please check your monitoring Instance is Configured correctly."}

URL: {BASE_URL}

diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx index 781854f8..9d3ffe4f 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx @@ -399,6 +399,8 @@ export async function getServerSideProps( applicationId: params?.applicationId, }); + await helpers.settings.isCloud.prefetch(); + return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx index b9ed1d8c..c6840214 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx @@ -394,7 +394,7 @@ export async function getServerSideProps( await helpers.compose.one.fetch({ composeId: params?.composeId, }); - + await helpers.settings.isCloud.prefetch(); return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx index d441b08c..a2ee9051 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx @@ -343,7 +343,7 @@ export async function getServerSideProps( await helpers.mariadb.one.fetch({ mariadbId: params?.mariadbId, }); - + await helpers.settings.isCloud.prefetch(); return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx index 7fdb1e77..4f3947c2 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx @@ -345,7 +345,7 @@ export async function getServerSideProps( await helpers.mongo.one.fetch({ mongoId: params?.mongoId, }); - + await helpers.settings.isCloud.prefetch(); return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx index ba4efecc..baf7e6f8 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx @@ -350,7 +350,7 @@ export async function getServerSideProps( await helpers.mysql.one.fetch({ mysqlId: params?.mysqlId, }); - + await helpers.settings.isCloud.prefetch(); return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx index 047d1c57..e3fd8b44 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/postgres/[postgresId].tsx @@ -346,7 +346,7 @@ export async function getServerSideProps( await helpers.postgres.one.fetch({ postgresId: params?.postgresId, }); - + await helpers.settings.isCloud.prefetch(); return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx index 1b041640..3421e759 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/redis/[redisId].tsx @@ -337,7 +337,7 @@ export async function getServerSideProps( await helpers.redis.one.fetch({ redisId: params?.redisId, }); - + await helpers.settings.isCloud.prefetch(); return { props: { trpcState: helpers.dehydrate(), diff --git a/apps/dokploy/server/api/routers/admin.ts b/apps/dokploy/server/api/routers/admin.ts index f10bc759..ab1cd8e8 100644 --- a/apps/dokploy/server/api/routers/admin.ts +++ b/apps/dokploy/server/api/routers/admin.ts @@ -28,6 +28,7 @@ import { protectedProcedure, publicProcedure, } from "../trpc"; +import { z } from "zod"; export const adminRouter = createTRPCRouter({ one: adminProcedure.query(async ({ ctx }) => { @@ -169,4 +170,121 @@ export const adminRouter = createTRPCRouter({ metricsConfig: admin?.metricsConfig, }; }), + + getServerMetrics: protectedProcedure + .input( + z.object({ + url: z.string(), + token: z.string(), + dataPoints: z.string(), + }), + ) + .query(async ({ ctx, input }) => { + try { + const url = new URL(input.url); + url.searchParams.append("limit", input.dataPoints); + const response = await fetch(url.toString(), { + headers: { + Authorization: `Bearer ${input.token}`, + }, + }); + if (!response.ok) { + throw new Error( + `Error ${response.status}: ${response.statusText}. Ensure the container is running and this service is included in the monitoring configuration.`, + ); + } + + const data = await response.json(); + if (!Array.isArray(data) || data.length === 0) { + throw new Error( + [ + "No monitoring data available. This could be because:", + "", + "1. You don't have setup the monitoring service, you can do in web server section.", + "2. If you already have setup the monitoring service, wait a few minutes and refresh the page.", + ].join("\n"), + ); + } + return data as { + cpu: string; + cpuModel: string; + cpuCores: number; + cpuPhysicalCores: number; + cpuSpeed: number; + os: string; + distro: string; + kernel: string; + arch: string; + memUsed: string; + memUsedGB: string; + memTotal: string; + uptime: number; + diskUsed: string; + totalDisk: string; + networkIn: string; + networkOut: string; + timestamp: string; + }[]; + } catch (error) { + throw error; + } + }), + getContainerMetrics: protectedProcedure + .input( + z.object({ + url: z.string(), + token: z.string(), + appName: z.string(), + dataPoints: z.string(), + }), + ) + .query(async ({ ctx, input }) => { + try { + if (!input.appName) { + throw new Error( + [ + "No Application Selected:", + "", + "Make Sure to select an application to monitor.", + ].join("\n"), + ); + } + const url = new URL(`${input.url}/metrics/containers`); + url.searchParams.append("limit", input.dataPoints); + url.searchParams.append("appName", input.appName); + const response = await fetch(url.toString(), { + headers: { + Authorization: `Bearer ${input.token}`, + }, + }); + if (!response.ok) { + throw new Error( + `Error ${response.status}: ${response.statusText}. Please verify that the application "${input.appName}" is running and this service is included in the monitoring configuration.`, + ); + } + + const data = await response.json(); + if (!Array.isArray(data) || data.length === 0) { + throw new Error( + [ + `No monitoring data available for "${input.appName}". This could be because:`, + "", + "1. The container was recently started - wait a few minutes for data to be collected", + "2. The container is not running - verify its status", + "3. The service is not included in your monitoring configuration", + ].join("\n"), + ); + } + return data as { + containerId: string; + containerName: string; + containerImage: string; + containerLabels: string; + containerCommand: string; + containerCreated: string; + }[]; + } catch (error) { + throw error; + } + }), }); From d1610855bbd878a73768c2b03a15f760eaed410a Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:32:45 -0600 Subject: [PATCH 2/6] refactor: lint --- .../paid/container/show-paid-container-monitoring.tsx | 2 +- .../dashboard/monitoring/paid/servers/show-paid-monitoring.tsx | 2 +- apps/dokploy/server/api/routers/admin.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx b/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx index 194bf720..f45c7382 100644 --- a/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx +++ b/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx @@ -6,13 +6,13 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { api } from "@/utils/api"; import { Cpu, HardDrive, Loader2, MemoryStick, Network } from "lucide-react"; import { useEffect, useState } from "react"; import { ContainerBlockChart } from "./container-block-chart"; import { ContainerCPUChart } from "./container-cpu-chart"; import { ContainerMemoryChart } from "./container-memory-chart"; import { ContainerNetworkChart } from "./container-network-chart"; -import { api } from "@/utils/api"; const REFRESH_INTERVALS = { "5000": "5 Seconds", diff --git a/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx b/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx index 096df998..8f09ab12 100644 --- a/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx +++ b/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx @@ -5,6 +5,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { api } from "@/utils/api"; import { Clock, Cpu, HardDrive, Loader2, MemoryStick } from "lucide-react"; import type React from "react"; import { useEffect, useState } from "react"; @@ -12,7 +13,6 @@ import { CPUChart } from "./cpu-chart"; import { DiskChart } from "./disk-chart"; import { MemoryChart } from "./memory-chart"; import { NetworkChart } from "./network-chart"; -import { api } from "@/utils/api"; const REFRESH_INTERVALS = { "5000": "5 Seconds", diff --git a/apps/dokploy/server/api/routers/admin.ts b/apps/dokploy/server/api/routers/admin.ts index ab1cd8e8..31612fe0 100644 --- a/apps/dokploy/server/api/routers/admin.ts +++ b/apps/dokploy/server/api/routers/admin.ts @@ -22,13 +22,13 @@ import { } from "@dokploy/server"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; +import { z } from "zod"; import { adminProcedure, createTRPCRouter, protectedProcedure, publicProcedure, } from "../trpc"; -import { z } from "zod"; export const adminRouter = createTRPCRouter({ one: adminProcedure.query(async ({ ctx }) => { From f638f49ab6240db1658f18f16c9a76f177e9f6fe Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:33:52 -0600 Subject: [PATCH 3/6] refactor: use dokploy/monitoring tag image --- .github/workflows/deploy.yml | 2 +- packages/server/src/setup/monitoring-setup.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f5826da4..86bf0628 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -98,5 +98,5 @@ jobs: file: ./Dockerfile.monitoring push: true tags: | - siumauricio/monitoring:${{ github.ref_name == 'main' && 'latest' || 'canary' }} + dokploy/monitoring:${{ github.ref_name == 'main' && 'latest' || 'canary' }} platforms: linux/amd64 diff --git a/packages/server/src/setup/monitoring-setup.ts b/packages/server/src/setup/monitoring-setup.ts index e7cd941d..bf50cdb9 100644 --- a/packages/server/src/setup/monitoring-setup.ts +++ b/packages/server/src/setup/monitoring-setup.ts @@ -9,7 +9,7 @@ export const setupMonitoring = async (serverId: string) => { const server = await findServerById(serverId); const containerName = "mauricio-monitoring"; - const imageName = "siumauricio/monitoring:canary"; + const imageName = "dokploy/monitoring:canary"; const settings: ContainerCreateOptions = { name: containerName, @@ -74,7 +74,7 @@ export const setupWebMonitoring = async (adminId: string) => { const admin = await findAdminById(adminId); const containerName = "mauricio-monitoring"; - const imageName = "siumauricio/monitoring:canary"; + const imageName = "dokploy/monitoring:canary"; const settings: ContainerCreateOptions = { name: containerName, From f9b4035c203e2d288b315e6bc63b2b694bc34af5 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:41:07 -0600 Subject: [PATCH 4/6] refactor: use canary in development or canary tags --- packages/server/src/services/docker.ts | 6 ++++- packages/server/src/setup/monitoring-setup.ts | 23 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/server/src/services/docker.ts b/packages/server/src/services/docker.ts index b7a5c440..597c03fa 100644 --- a/packages/server/src/services/docker.ts +++ b/packages/server/src/services/docker.ts @@ -58,7 +58,11 @@ export const getContainers = async (serverId?: string | null) => { serverId, }; }) - .filter((container) => !container.name.includes("dokploy")); + .filter( + (container) => + !container.name.includes("dokploy") || + container.name.includes("dokploy-monitoring"), + ); return containers; } catch (error) { diff --git a/packages/server/src/setup/monitoring-setup.ts b/packages/server/src/setup/monitoring-setup.ts index bf50cdb9..1a22142f 100644 --- a/packages/server/src/setup/monitoring-setup.ts +++ b/packages/server/src/setup/monitoring-setup.ts @@ -4,12 +4,20 @@ import { findAdminById } from "../services/admin"; import { pullImage, pullRemoteImage } from "../utils/docker/utils"; import { execAsync, execAsyncRemote } from "../utils/process/execAsync"; import { getRemoteDocker } from "../utils/servers/remote-docker"; +import { getDokployImageTag } from "../services/settings"; export const setupMonitoring = async (serverId: string) => { 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" + ) { + imageName = "dokploy/monitoring:canary"; + } const settings: ContainerCreateOptions = { name: containerName, @@ -73,8 +81,15 @@ export const setupMonitoring = async (serverId: string) => { export const setupWebMonitoring = async (adminId: string) => { const admin = await findAdminById(adminId); - 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" + ) { + imageName = "dokploy/monitoring:canary"; + } const settings: ContainerCreateOptions = { name: containerName, From d1aaeb9a7b6f77379c243319444ef62200f85912 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:43:28 -0600 Subject: [PATCH 5/6] refactor: adjust logic --- packages/server/src/setup/monitoring-setup.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/server/src/setup/monitoring-setup.ts b/packages/server/src/setup/monitoring-setup.ts index 1a22142f..e7b39b0b 100644 --- a/packages/server/src/setup/monitoring-setup.ts +++ b/packages/server/src/setup/monitoring-setup.ts @@ -1,10 +1,11 @@ import { findServerById } from "@dokploy/server/services/server"; import type { ContainerCreateOptions } from "dockerode"; import { findAdminById } from "../services/admin"; +import { getDokployImageTag } from "../services/settings"; import { pullImage, pullRemoteImage } from "../utils/docker/utils"; import { execAsync, execAsyncRemote } from "../utils/process/execAsync"; import { getRemoteDocker } from "../utils/servers/remote-docker"; -import { getDokployImageTag } from "../services/settings"; +import { IS_CLOUD } from "../constants"; export const setupMonitoring = async (serverId: string) => { const server = await findServerById(serverId); @@ -13,8 +14,9 @@ export const setupMonitoring = async (serverId: string) => { let imageName = "dokploy/monitoring:latest"; if ( - getDokployImageTag() !== "latest" || - process.env.NODE_ENV === "development" + (getDokployImageTag() !== "latest" || + process.env.NODE_ENV === "development") && + !IS_CLOUD ) { imageName = "dokploy/monitoring:canary"; } @@ -85,8 +87,9 @@ export const setupWebMonitoring = async (adminId: string) => { let imageName = "dokploy/monitoring:latest"; if ( - getDokployImageTag() !== "latest" || - process.env.NODE_ENV === "development" + (getDokployImageTag() !== "latest" || + process.env.NODE_ENV === "development") && + !IS_CLOUD ) { imageName = "dokploy/monitoring:canary"; } From 51851567db3c5d952153046fece28250a0ec6034 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:49:30 -0600 Subject: [PATCH 6/6] refactor: update name --- .../show-paid-container-monitoring.tsx | 91 ++++++++++--------- .../paid/servers/show-paid-monitoring.tsx | 91 ++++++++++--------- packages/server/src/setup/monitoring-setup.ts | 2 +- 3 files changed, 97 insertions(+), 87 deletions(-) diff --git a/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx b/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx index f45c7382..3636a391 100644 --- a/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx +++ b/apps/dokploy/components/dashboard/monitoring/paid/container/show-paid-container-monitoring.tsx @@ -131,54 +131,59 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => { return ( <> -
+

Container Monitoring

-
- Data points: - - - Refresh interval: - - +
+
+ Data points: + +
+ +
+ + Refresh interval: + + +
{/* Stats Cards */} -
+
@@ -236,13 +241,13 @@ export const ContainerPaidMonitoring = ({ appName, baseUrl, token }: Props) => {

Name

-

{metrics.Name}

+

{metrics.Name}

{/* Charts Grid */} -
+
diff --git a/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx b/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx index 8f09ab12..043b5c62 100644 --- a/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx +++ b/apps/dokploy/components/dashboard/monitoring/paid/servers/show-paid-monitoring.tsx @@ -151,53 +151,58 @@ export const ShowPaidMonitoring = ({ } return ( -
-
+
+

System Monitoring

-
- Data points: - - - Refresh interval: - - +
+
+ Data points: + +
+ +
+ + Refresh interval: + + +
{/* Stats Cards */} -
+
@@ -260,7 +265,7 @@ export const ShowPaidMonitoring = ({
{/* Charts Grid */} -
+
diff --git a/packages/server/src/setup/monitoring-setup.ts b/packages/server/src/setup/monitoring-setup.ts index e7b39b0b..f72b2244 100644 --- a/packages/server/src/setup/monitoring-setup.ts +++ b/packages/server/src/setup/monitoring-setup.ts @@ -1,11 +1,11 @@ import { findServerById } from "@dokploy/server/services/server"; import type { ContainerCreateOptions } from "dockerode"; +import { IS_CLOUD } from "../constants"; import { findAdminById } from "../services/admin"; import { getDokployImageTag } from "../services/settings"; import { pullImage, pullRemoteImage } from "../utils/docker/utils"; import { execAsync, execAsyncRemote } from "../utils/process/execAsync"; import { getRemoteDocker } from "../utils/servers/remote-docker"; -import { IS_CLOUD } from "../constants"; export const setupMonitoring = async (serverId: string) => { const server = await findServerById(serverId);