Files
dokploy/packages/server/src/utils/builders/index.ts
Mauricio Siu 8ab6d6b282 chore: clean up unused variables and improve error handling across codebase
This commit focuses on removing unused variables, adding placeholder error handling, and generally tidying up various files across the Dokploy application. Changes include:

- Removing unused imports and variables
- Adding placeholder error handling in catch blocks
- Cleaning up commented-out code
- Removing deprecated utility files
- Improving type safety and code consistency
2025-02-22 20:35:21 -06:00

240 lines
5.8 KiB
TypeScript

import { createWriteStream } from "node:fs";
import { join } from "node:path";
import type { InferResultType } from "@dokploy/server/types/with";
import type { CreateServiceOptions } from "dockerode";
import { uploadImage, uploadImageRemoteCommand } from "../cluster/upload";
import {
calculateResources,
generateBindMounts,
generateConfigContainer,
generateFileMounts,
generateVolumeMounts,
prepareEnvironmentVariables,
} from "../docker/utils";
import { getRemoteDocker } from "../servers/remote-docker";
import { buildCustomDocker, getDockerCommand } from "./docker-file";
import { buildHeroku, getHerokuCommand } from "./heroku";
import { buildNixpacks, getNixpacksCommand } from "./nixpacks";
import { buildPaketo, getPaketoCommand } from "./paketo";
import { buildStatic, getStaticCommand } from "./static";
// NIXPACKS codeDirectory = where is the path of the code directory
// HEROKU codeDirectory = where is the path of the code directory
// PAKETO codeDirectory = where is the path of the code directory
// DOCKERFILE codeDirectory = where is the exact path of the (Dockerfile)
export type ApplicationNested = InferResultType<
"applications",
{
mounts: true;
security: true;
redirects: true;
ports: true;
registry: true;
project: true;
}
>;
export const buildApplication = async (
application: ApplicationNested,
logPath: string,
) => {
const writeStream = createWriteStream(logPath, { flags: "a" });
const { buildType, sourceType } = application;
try {
writeStream.write(
`\nBuild ${buildType}: ✅\nSource Type: ${sourceType}: ✅\n`,
);
console.log(`Build ${buildType}: ✅`);
if (buildType === "nixpacks") {
await buildNixpacks(application, writeStream);
} else if (buildType === "heroku_buildpacks") {
await buildHeroku(application, writeStream);
} else if (buildType === "paketo_buildpacks") {
await buildPaketo(application, writeStream);
} else if (buildType === "dockerfile") {
await buildCustomDocker(application, writeStream);
} else if (buildType === "static") {
await buildStatic(application, writeStream);
}
if (application.registryId) {
await uploadImage(application, writeStream);
}
await mechanizeDockerContainer(application);
writeStream.write("Docker Deployed: ✅");
} catch (error) {
if (error instanceof Error) {
writeStream.write(`Error ❌\n${error?.message}`);
} else {
writeStream.write("Error ❌");
}
throw error;
} finally {
writeStream.end();
}
};
export const getBuildCommand = (
application: ApplicationNested,
logPath: string,
) => {
let command = "";
const { buildType, registry } = application;
switch (buildType) {
case "nixpacks":
command = getNixpacksCommand(application, logPath);
break;
case "heroku_buildpacks":
command = getHerokuCommand(application, logPath);
break;
case "paketo_buildpacks":
command = getPaketoCommand(application, logPath);
break;
case "static":
command = getStaticCommand(application, logPath);
break;
case "dockerfile":
command = getDockerCommand(application, logPath);
break;
}
if (registry) {
command += uploadImageRemoteCommand(application, logPath);
}
return command;
};
export const mechanizeDockerContainer = async (
application: ApplicationNested,
) => {
const {
appName,
env,
mounts,
cpuLimit,
memoryLimit,
memoryReservation,
cpuReservation,
command,
ports,
} = application;
const resources = calculateResources({
memoryLimit,
memoryReservation,
cpuLimit,
cpuReservation,
});
const volumesMount = generateVolumeMounts(mounts);
const {
HealthCheck,
RestartPolicy,
Placement,
Labels,
Mode,
RollbackConfig,
UpdateConfig,
Networks,
} = generateConfigContainer(application);
const bindsMount = generateBindMounts(mounts);
const filesMount = generateFileMounts(appName, application);
const envVariables = prepareEnvironmentVariables(
env,
application.project.env,
);
const image = getImageName(application);
const authConfig = getAuthConfig(application);
const docker = await getRemoteDocker(application.serverId);
const settings: CreateServiceOptions = {
authconfig: authConfig,
Name: appName,
TaskTemplate: {
ContainerSpec: {
HealthCheck,
Image: image,
Env: envVariables,
Mounts: [...volumesMount, ...bindsMount, ...filesMount],
...(command
? {
Command: ["/bin/sh"],
Args: ["-c", command],
}
: {}),
Labels,
},
Networks,
RestartPolicy,
Placement,
Resources: {
...resources,
},
},
Mode,
RollbackConfig,
EndpointSpec: {
Ports: ports.map((port) => ({
Protocol: port.protocol,
TargetPort: port.targetPort,
PublishedPort: port.publishedPort,
})),
},
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 (_error) {
await docker.createService(settings);
}
};
const getImageName = (application: ApplicationNested) => {
const { appName, sourceType, dockerImage, registry } = application;
if (sourceType === "docker") {
return dockerImage || "ERROR-NO-IMAGE-PROVIDED";
}
if (registry) {
return join(registry.registryUrl, registry.imagePrefix || "", appName);
}
return `${appName}:latest`;
};
const getAuthConfig = (application: ApplicationNested) => {
const { registry, username, password, sourceType, registryUrl } = application;
if (sourceType === "docker") {
if (username && password) {
return {
password,
username,
serveraddress: registryUrl || "",
};
}
} else if (registry) {
return {
password: registry.password,
username: registry.username,
serveraddress: registry.registryUrl,
};
}
return undefined;
};