mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-18 13:45:23 +02:00
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.
137 lines
3.0 KiB
TypeScript
137 lines
3.0 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 MysqlNested = InferResultType<
|
|
"mysql",
|
|
{ mounts: true; environment: { with: { project: true } } }
|
|
>;
|
|
|
|
export const buildMysql = async (mysql: MysqlNested) => {
|
|
const {
|
|
appName,
|
|
env,
|
|
externalPort,
|
|
dockerImage,
|
|
memoryLimit,
|
|
memoryReservation,
|
|
databaseName,
|
|
databaseUser,
|
|
databasePassword,
|
|
databaseRootPassword,
|
|
cpuLimit,
|
|
cpuReservation,
|
|
command,
|
|
args,
|
|
mounts,
|
|
} = mysql;
|
|
|
|
const defaultMysqlEnv =
|
|
databaseUser !== "root"
|
|
? `MYSQL_USER="${databaseUser}"\nMYSQL_DATABASE="${databaseName}"\nMYSQL_PASSWORD="${databasePassword}"\nMYSQL_ROOT_PASSWORD="${databaseRootPassword}"${
|
|
env ? `\n${env}` : ""
|
|
}`
|
|
: `MYSQL_DATABASE="${databaseName}"\nMYSQL_ROOT_PASSWORD="${databaseRootPassword}"${
|
|
env ? `\n${env}` : ""
|
|
}`;
|
|
|
|
const {
|
|
HealthCheck,
|
|
RestartPolicy,
|
|
Placement,
|
|
Labels,
|
|
Mode,
|
|
RollbackConfig,
|
|
UpdateConfig,
|
|
Networks,
|
|
StopGracePeriod,
|
|
EndpointSpec,
|
|
Ulimits,
|
|
} = generateConfigContainer(mysql);
|
|
const resources = calculateResources({
|
|
memoryLimit,
|
|
memoryReservation,
|
|
cpuLimit,
|
|
cpuReservation,
|
|
});
|
|
const envVariables = prepareEnvironmentVariables(
|
|
defaultMysqlEnv,
|
|
mysql.environment.project.env,
|
|
mysql.environment.env,
|
|
);
|
|
const volumesMount = generateVolumeMounts(mounts);
|
|
const bindsMount = generateBindMounts(mounts);
|
|
const filesMount = generateFileMounts(appName, mysql);
|
|
|
|
const docker = await getRemoteDocker(mysql.serverId);
|
|
|
|
const settings: CreateServiceOptions = {
|
|
Name: appName,
|
|
TaskTemplate: {
|
|
ContainerSpec: {
|
|
HealthCheck,
|
|
Image: dockerImage,
|
|
Env: envVariables,
|
|
Mounts: [...volumesMount, ...bindsMount, ...filesMount],
|
|
...(StopGracePeriod !== null &&
|
|
StopGracePeriod !== undefined && { StopGracePeriod }),
|
|
...(command && {
|
|
Command: command.split(" "),
|
|
}),
|
|
...(args &&
|
|
args.length > 0 && {
|
|
Args: args,
|
|
}),
|
|
...(Ulimits && { Ulimits }),
|
|
Labels,
|
|
},
|
|
Networks,
|
|
RestartPolicy,
|
|
Placement,
|
|
Resources: {
|
|
...resources,
|
|
},
|
|
},
|
|
Mode,
|
|
RollbackConfig,
|
|
EndpointSpec: EndpointSpec
|
|
? EndpointSpec
|
|
: {
|
|
Mode: "dnsrr" as const,
|
|
Ports: externalPort
|
|
? [
|
|
{
|
|
Protocol: "tcp" as const,
|
|
TargetPort: 3306,
|
|
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);
|
|
}
|
|
};
|