211 lines · 5.1 KB · TypeScript
RawDownload
import { findServerById } from "@dokploy/server/services/server";import { getWebServerSettings } from "@dokploy/server/services/web-server-settings";import type { CreateServiceOptions } from "dockerode";import { IS_CLOUD } from "../constants";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"; const getMonitoringImage = () => {	let imageName = "dokploy/monitoring:latest"; 	if (		(getDokployImageTag() !== "latest" ||			process.env.NODE_ENV === "development") &&		!IS_CLOUD	) {		imageName = "dokploy/monitoring:canary";	} 	return imageName;}; // Swarm tasks are dokploy-monitoring.<slot>.<id>, so this only matches the// pre-v0.30.0 standalone container. A cleanup failure must not block the deploy.const removeLegacyContainer = async (	docker: Awaited<ReturnType<typeof getRemoteDocker>>,	serviceName: string,) => {	try {		await docker.getContainer(serviceName).remove({ force: true });		console.log("Removed legacy monitoring container ✅");	} catch (error: any) {		if (error?.statusCode !== 404) {			console.warn(				`Could not remove legacy monitoring container: ${error?.message ?? error}`,			);		}	}}; const deployMonitoringService = async (	docker: Awaited<ReturnType<typeof getRemoteDocker>>,	serviceName: string,	settings: CreateServiceOptions,) => {	await removeLegacyContainer(docker, serviceName); 	try {		const service = docker.getService(serviceName);		const inspect = await service.inspect();		await service.update({			version: Number.parseInt(inspect.Version.Index),			...settings,			TaskTemplate: {				...settings.TaskTemplate,				ForceUpdate: (inspect.Spec.TaskTemplate.ForceUpdate ?? 0) + 1,			},		});		console.log("Monitoring Updated ✅");	} catch (error: any) {		if (error?.statusCode && error.statusCode !== 404) {			throw error;		}		await docker.createService(settings);		console.log("Monitoring Started ✅");	}}; export const setupMonitoring = async (serverId: string) => {	const server = await findServerById(serverId); 	const serviceName = "dokploy-monitoring";	const imageName = getMonitoringImage(); 	const settings: CreateServiceOptions = {		Name: serviceName,		TaskTemplate: {			ContainerSpec: {				Image: imageName,				Env: [`METRICS_CONFIG=${JSON.stringify(server?.metricsConfig)}`],				Mounts: [					{						Type: "bind",						Source: "/var/run/docker.sock",						Target: "/var/run/docker.sock",						ReadOnly: true,					},					{						Type: "bind",						Source: "/sys",						Target: "/host/sys",						ReadOnly: true,					},					{						Type: "bind",						Source: "/etc/os-release",						Target: "/etc/os-release",						ReadOnly: true,					},					{						Type: "bind",						Source: "/proc",						Target: "/host/proc",						ReadOnly: true,					},					{						Type: "bind",						Source: "/etc/dokploy/monitoring/monitoring.db",						Target: "/app/monitoring.db",					},				],			},			Networks: [{ Target: "host" }],			Placement: {				Constraints: ["node.role==manager"],			},		},		Mode: {			Replicated: {				Replicas: 1,			},		},	}; 	const docker = await getRemoteDocker(serverId); 	await execAsyncRemote(		serverId,		"mkdir -p /etc/dokploy/monitoring && touch /etc/dokploy/monitoring/monitoring.db",	);	await pullRemoteImage(imageName, serverId);	await deployMonitoringService(docker, serviceName, settings);}; export const setupWebMonitoring = async () => {	const webServerSettings = await getWebServerSettings(); 	const serviceName = "dokploy-monitoring";	const imageName = getMonitoringImage();	const port = webServerSettings?.metricsConfig?.server?.port; 	const settings: CreateServiceOptions = {		Name: serviceName,		TaskTemplate: {			ContainerSpec: {				Image: imageName,				Env: [					`METRICS_CONFIG=${JSON.stringify(webServerSettings?.metricsConfig)}`,				],				Mounts: [					{						Type: "bind",						Source: "/var/run/docker.sock",						Target: "/var/run/docker.sock",						ReadOnly: true,					},					{						Type: "bind",						Source: "/sys",						Target: "/host/sys",						ReadOnly: true,					},					{						Type: "bind",						Source: "/etc/os-release",						Target: "/etc/os-release",						ReadOnly: true,					},					{						Type: "bind",						Source: "/proc",						Target: "/host/proc",						ReadOnly: true,					},					{						Type: "bind",						Source: "/etc/dokploy/monitoring/monitoring.db",						Target: "/app/monitoring.db",					},				],			},			Placement: {				Constraints: ["node.role==manager"],			},		},		Mode: {			Replicated: {				Replicas: 1,			},		},		EndpointSpec: {			Ports: [				{					TargetPort: port,					PublishedPort: port,					Protocol: "tcp",					PublishMode: "host",				},			],		},	}; 	const docker = await getRemoteDocker(); 	await execAsync(		"mkdir -p /etc/dokploy/monitoring && touch /etc/dokploy/monitoring/monitoring.db",	);	await pullImage(imageName);	await deployMonitoringService(docker, serviceName, settings);};