Files
dokploy/packages/server/src/utils/databases/redis.ts
nurikk 0a401843f8 core: add ulimits configuration for Docker Swarm deployments
Users deploying to Docker Swarm can now configure resource ulimits
(nofile, nproc, etc.) to prevent applications from hitting system
limits that cause crashes or degraded performance.
2026-01-08 21:57:58 +00:00

136 lines
2.9 KiB
TypeScript

import type { InferResultType } from "@dokploy/server/types/with";
import type { CreateServiceOptions } from "dockerode";
import {
calculateResources,
generateBindMounts,
generateConfigContainer,
generateFileMounts,
generateVolumeMounts,
prepareEnvironmentVariables,
} from "../docker/utils";
import { getRemoteDocker } from "../servers/remote-docker";
export type RedisNested = InferResultType<
"redis",
{ mounts: true; environment: { with: { project: true } } }
>;
export const buildRedis = async (redis: RedisNested) => {
const {
appName,
env,
externalPort,
dockerImage,
memoryLimit,
memoryReservation,
databasePassword,
cpuLimit,
cpuReservation,
command,
args,
mounts,
} = redis;
const defaultRedisEnv = `REDIS_PASSWORD="${databasePassword}"${
env ? `\n${env}` : ""
}`;
const {
HealthCheck,
RestartPolicy,
Placement,
Labels,
Mode,
RollbackConfig,
UpdateConfig,
Networks,
StopGracePeriod,
EndpointSpec,
Ulimits,
} = generateConfigContainer(redis);
const resources = calculateResources({
memoryLimit,
memoryReservation,
cpuLimit,
cpuReservation,
});
const envVariables = prepareEnvironmentVariables(
defaultRedisEnv,
redis.environment.project.env,
redis.environment.env,
);
const volumesMount = generateVolumeMounts(mounts);
const bindsMount = generateBindMounts(mounts);
const filesMount = generateFileMounts(appName, redis);
const docker = await getRemoteDocker(redis.serverId);
const settings: CreateServiceOptions = {
Name: appName,
TaskTemplate: {
ContainerSpec: {
HealthCheck,
Image: dockerImage,
Env: envVariables,
Mounts: [...volumesMount, ...bindsMount, ...filesMount],
...(StopGracePeriod !== null &&
StopGracePeriod !== undefined && { StopGracePeriod }),
...(command || args
? {
...(command && {
Command: command.split(" "),
}),
...(args &&
args.length > 0 && {
Args: args,
}),
}
: {
Command: ["/bin/sh"],
Args: ["-c", `redis-server --requirepass ${databasePassword}`],
}),
...(Ulimits && { Ulimits }),
Labels,
},
Networks,
RestartPolicy,
Placement,
Resources: {
...resources,
},
},
Mode,
RollbackConfig,
EndpointSpec: EndpointSpec
? EndpointSpec
: {
Mode: "dnsrr" as const,
Ports: externalPort
? [
{
Protocol: "tcp" as const,
TargetPort: 6379,
PublishedPort: externalPort,
PublishMode: "host" as const,
},
]
: [],
},
UpdateConfig,
};
try {
const service = docker.getService(appName);
const inspect = await service.inspect();
await service.update({
version: Number.parseInt(inspect.Version.Index),
...settings,
TaskTemplate: {
...settings.TaskTemplate,
ForceUpdate: inspect.Spec.TaskTemplate.ForceUpdate + 1,
},
});
} catch {
await docker.createService(settings);
}
};