Refactor compose utilities: remove unused functions and streamline the buildCompose logic for improved maintainability. Update domain handling by retaining only the necessary remote function, enhancing clarity in the codebase.

This commit is contained in:
Mauricio Siu
2025-11-09 03:42:43 -06:00
parent 668aaf9a91
commit f718ab334e
3 changed files with 2 additions and 168 deletions

View File

@@ -1,100 +1,18 @@
import {
createWriteStream,
existsSync,
mkdirSync,
writeFileSync,
} from "node:fs";
import { dirname, join } from "node:path";
import { paths } from "@dokploy/server/constants";
import type { InferResultType } from "@dokploy/server/types/with";
import boxen from "boxen";
import {
writeDomainsToCompose,
writeDomainsToComposeRemote,
} from "../docker/domain";
import { writeDomainsToComposeRemote } from "../docker/domain";
import {
encodeBase64,
getEnviromentVariablesObject,
prepareEnvironmentVariables,
} from "../docker/utils";
import { execAsync } from "../process/execAsync";
import { spawnAsync } from "../process/spawnAsync";
export type ComposeNested = InferResultType<
"compose",
{ environment: { with: { project: true } }; mounts: true; domains: true }
>;
export const buildCompose = async (compose: ComposeNested, logPath: string) => {
const writeStream = createWriteStream(logPath, { flags: "a" });
const { sourceType, appName, mounts, composeType, domains } = compose;
try {
const { COMPOSE_PATH } = paths();
const command = createCommand(compose);
await writeDomainsToCompose(compose, domains);
createEnvFile(compose);
if (compose.isolatedDeployment) {
await execAsync(
`docker network inspect ${compose.appName} >/dev/null 2>&1 || docker network create ${composeType === "stack" ? "--driver overlay" : ""} --attachable ${compose.appName}`,
);
}
const logContent = `
App Name: ${appName}
Build Compose 🐳
Detected: ${mounts.length} mounts 📂
Command: docker ${command}
Source Type: docker ${sourceType}
Compose Type: ${composeType}`;
const logBox = boxen(logContent, {
padding: {
left: 1,
right: 1,
bottom: 1,
},
width: 80,
borderStyle: "double",
});
writeStream.write(`\n${logBox}\n`);
const projectPath = join(COMPOSE_PATH, compose.appName, "code");
await spawnAsync(
"docker",
[...command.split(" ")],
(data) => {
if (writeStream.writable) {
writeStream.write(data.toString());
}
},
{
cwd: projectPath,
env: {
NODE_ENV: process.env.NODE_ENV,
PATH: process.env.PATH,
...(composeType === "stack" && {
...getEnviromentVariablesObject(
compose.env,
compose.environment.project.env,
),
}),
},
},
);
if (compose.isolatedDeployment) {
await execAsync(
`docker network connect ${compose.appName} $(docker ps --filter "name=dokploy-traefik" -q) >/dev/null 2>&1`,
).catch(() => {});
}
writeStream.write("Docker Compose Deployed: ✅");
} catch (error) {
writeStream.write(`Error ❌ ${(error as Error).message}`);
throw error;
} finally {
writeStream.end();
}
};
export const getBuildComposeCommand = async (compose: ComposeNested) => {
const { COMPOSE_PATH } = paths(!!compose.serverId);
@@ -179,36 +97,6 @@ export const createCommand = (compose: ComposeNested) => {
return command;
};
const createEnvFile = (compose: ComposeNested) => {
const { COMPOSE_PATH } = paths();
const { env, composePath, appName } = compose;
const composeFilePath =
join(COMPOSE_PATH, appName, "code", composePath) ||
join(COMPOSE_PATH, appName, "code", "docker-compose.yml");
const envFilePath = join(dirname(composeFilePath), ".env");
let envContent = `APP_NAME=${appName}\n`;
envContent += env || "";
if (!envContent.includes("DOCKER_CONFIG")) {
envContent += "\nDOCKER_CONFIG=/root/.docker";
}
if (compose.randomize) {
envContent += `\nCOMPOSE_PREFIX=${compose.suffix}`;
}
const envFileContent = prepareEnvironmentVariables(
envContent,
compose.environment.project.env,
compose.environment.env,
).join("\n");
if (!existsSync(dirname(envFilePath))) {
mkdirSync(dirname(envFilePath), { recursive: true });
}
writeFileSync(envFilePath, envFileContent);
};
export const getCreateEnvFileCommand = (compose: ComposeNested) => {
const { COMPOSE_PATH } = paths(!!compose.serverId);
const { env, composePath, appName } = compose;

View File

@@ -1,5 +1,4 @@
import fs, { existsSync, readFileSync } from "node:fs";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { paths } from "@dokploy/server/constants";
import type { Compose } from "@dokploy/server/services/compose";
@@ -103,24 +102,6 @@ export const readComposeFile = async (compose: Compose) => {
return null;
};
export const writeDomainsToCompose = async (
compose: Compose,
domains: Domain[],
) => {
if (!domains.length) {
return;
}
const composeConverted = await addDomainToCompose(compose, domains);
const path = getComposePath(compose);
const composeString = stringify(composeConverted, { lineWidth: 1000 });
try {
await writeFile(path, composeString, "utf8");
} catch (error) {
throw error;
}
};
export const writeDomainsToComposeRemote = async (
compose: Compose,
domains: Domain[],

View File

@@ -1,13 +1,10 @@
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { paths } from "@dokploy/server/constants";
import type { Compose } from "@dokploy/server/services/compose";
import { encodeBase64 } from "../docker/utils";
import { recreateDirectory } from "../filesystem/directory";
import { execAsyncRemote } from "../process/execAsync";
export const getCreateComposeFileCommand = (compose: Compose) => {
const { COMPOSE_PATH } = paths(true);
const { COMPOSE_PATH } = paths(!!compose.serverId);
const { appName, composeFile } = compose;
const outputPath = join(COMPOSE_PATH, appName, "code");
const filePath = join(outputPath, "docker-compose.yml");
@@ -20,35 +17,3 @@ export const getCreateComposeFileCommand = (compose: Compose) => {
`;
return bashCommand;
};
export const createComposeFileRaw = async (compose: Compose) => {
const { COMPOSE_PATH } = paths();
const { appName, composeFile } = compose;
const outputPath = join(COMPOSE_PATH, appName, "code");
const filePath = join(outputPath, "docker-compose.yml");
try {
await recreateDirectory(outputPath);
await writeFile(filePath, composeFile);
} catch (error) {
throw error;
}
};
export const createComposeFileRawRemote = async (compose: Compose) => {
const { COMPOSE_PATH } = paths(true);
const { appName, composeFile, serverId } = compose;
const outputPath = join(COMPOSE_PATH, appName, "code");
const filePath = join(outputPath, "docker-compose.yml");
try {
const encodedContent = encodeBase64(composeFile);
const command = `
rm -rf ${outputPath};
mkdir -p ${outputPath};
echo "${encodedContent}" | base64 -d > "${filePath}";
`;
await execAsyncRemote(serverId, command);
} catch (error) {
throw error;
}
};