mirror of
https://github.com/andwati/dokploy.git
synced 2026-10-19 11:42:55 +00:00
212 lines
5.1 KiB
TypeScript
212 lines
5.1 KiB
TypeScript
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);
|
|
};
|