refactor(deployments): improve build error

This commit is contained in:
Mauricio Siu 2024-09-15 14:48:40 -06:00
parent d2c8632c4f
commit 0d3c978aad
16 changed files with 464 additions and 178 deletions

View File

@ -189,12 +189,14 @@ export const applicationRouter = createTRPCRouter({
redeploy: protectedProcedure
.input(apiFindOneApplication)
.mutation(async ({ input }) => {
const application = await findApplicationById(input.applicationId);
const jobData: DeploymentJob = {
applicationId: input.applicationId,
titleLog: "Rebuild deployment",
descriptionLog: "",
type: "redeploy",
applicationType: "application",
server: !!application.serverId,
};
await myQueue.add(
"deployments",
@ -334,13 +336,14 @@ export const applicationRouter = createTRPCRouter({
deploy: protectedProcedure
.input(apiFindOneApplication)
.mutation(async ({ input, ctx }) => {
// const application = await findApplicationById(input.applicationId);
const application = await findApplicationById(input.applicationId);
const jobData: DeploymentJob = {
applicationId: input.applicationId,
titleLog: "Manual deployment",
descriptionLog: "",
type: "deploy",
applicationType: "application",
server: !!application.serverId,
};
await myQueue.add(
"deployments",
@ -350,10 +353,6 @@ export const applicationRouter = createTRPCRouter({
removeOnFail: true,
},
);
// if (!application.serverId) {
// } else {
// await enqueueDeploymentJob(application.serverId, jobData);
// }
}),
cleanQueues: protectedProcedure

View File

@ -169,14 +169,6 @@ export const composeRouter = createTRPCRouter({
deploy: protectedProcedure
.input(apiFindCompose)
.mutation(async ({ input }) => {
// const jobData: DeploymentJob = {
// composeId: input.composeId,
// titleLog: "Manual deployment",
// type: "deploy",
// applicationType: "compose",
// descriptionLog: "",
// };
const compose = await findComposeById(input.composeId);
const jobData: DeploymentJob = {
composeId: input.composeId,
@ -184,6 +176,7 @@ export const composeRouter = createTRPCRouter({
type: "deploy",
applicationType: "compose",
descriptionLog: "",
server: !!compose.serverId,
};
await myQueue.add(
"deployments",
@ -193,10 +186,6 @@ export const composeRouter = createTRPCRouter({
removeOnFail: true,
},
);
// if (!compose.serverId) {
// } else {
// await enqueueDeploymentJob(compose.serverId, jobData);
// }
}),
redeploy: protectedProcedure
.input(apiFindCompose)

View File

@ -260,10 +260,66 @@ export const rebuildApplication = async ({
description: descriptionLog,
});
try {
if (application.sourceType === "github") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "gitlab") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "bitbucket") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "docker") {
await buildDocker(application, deployment.logPath);
} else if (application.sourceType === "git") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "drop") {
await buildApplication(application, deployment.logPath);
}
await updateDeploymentStatus(deployment.deploymentId, "done");
await updateApplicationStatus(applicationId, "done");
} catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateApplicationStatus(applicationId, "error");
throw error;
}
return true;
};
export const deployRemoteApplication = async ({
applicationId,
titleLog = "Manual deployment",
descriptionLog = "",
}: {
applicationId: string;
titleLog: string;
descriptionLog: string;
}) => {
const application = await findApplicationById(applicationId);
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
const deployment = await createDeployment({
applicationId: applicationId,
title: titleLog,
description: descriptionLog,
});
try {
if (application.serverId) {
let command = "set -e;";
if (application.sourceType === "docker") {
if (application.sourceType === "github") {
command += await getGithubCloneCommand(application, deployment.logPath);
} else if (application.sourceType === "gitlab") {
command += await getGitlabCloneCommand(application, deployment.logPath);
} else if (application.sourceType === "bitbucket") {
command += await getBitbucketCloneCommand(
application,
deployment.logPath,
);
} else if (application.sourceType === "git") {
command += await getCustomGitCloneCommand(
application,
deployment.logPath,
);
} else if (application.sourceType === "docker") {
command += await buildRemoteDocker(application, deployment.logPath);
}
@ -272,20 +328,67 @@ export const rebuildApplication = async ({
}
await execAsyncRemote(application.serverId, command);
await mechanizeDockerContainer(application);
} else {
if (application.sourceType === "github") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "gitlab") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "bitbucket") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "docker") {
await buildDocker(application, deployment.logPath);
} else if (application.sourceType === "git") {
await buildApplication(application, deployment.logPath);
} else if (application.sourceType === "drop") {
await buildApplication(application, deployment.logPath);
}
await updateDeploymentStatus(deployment.deploymentId, "done");
await updateApplicationStatus(applicationId, "done");
await sendBuildSuccessNotifications({
projectName: application.project.name,
applicationName: application.name,
applicationType: "application",
buildLink,
});
} catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateApplicationStatus(applicationId, "error");
await sendBuildErrorNotifications({
projectName: application.project.name,
applicationName: application.name,
applicationType: "application",
// @ts-ignore
errorMessage: error?.message || "Error to build",
buildLink,
});
console.log(
"Error on ",
application.buildType,
"/",
application.sourceType,
error,
);
throw error;
}
return true;
};
export const rebuildRemoteApplication = async ({
applicationId,
titleLog = "Rebuild deployment",
descriptionLog = "",
}: {
applicationId: string;
titleLog: string;
descriptionLog: string;
}) => {
const application = await findApplicationById(applicationId);
const deployment = await createDeployment({
applicationId: applicationId,
title: titleLog,
description: descriptionLog,
});
try {
if (application.serverId) {
if (application.sourceType !== "docker") {
let command = "set -e;";
command += getBuildCommand(application, deployment.logPath);
await execAsyncRemote(application.serverId, command);
}
await mechanizeDockerContainer(application);
}
await updateDeploymentStatus(deployment.deploymentId, "done");
await updateApplicationStatus(applicationId, "done");

View File

@ -210,64 +210,18 @@ export const deployCompose = async ({
});
try {
if (compose.serverId) {
let command = `
set -e;
`;
if (compose.sourceType === "github") {
command += await getGithubCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "gitlab") {
command += await getGitlabCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "bitbucket") {
command += await getBitbucketCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "git") {
command += await getCustomGitCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "raw") {
command += getCreateComposeFileCommand(compose);
}
async function* sequentialSteps() {
yield execAsyncRemote(compose.serverId, command);
yield getBuildComposeCommand(compose, deployment.logPath);
}
const steps = sequentialSteps();
for await (const step of steps) {
step;
}
console.log(" ---- done ----");
} else {
if (compose.sourceType === "github") {
await cloneGithubRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "gitlab") {
await cloneGitlabRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "bitbucket") {
await cloneBitbucketRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "git") {
await cloneGitRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "raw") {
await createComposeFile(compose, deployment.logPath);
}
await buildCompose(compose, deployment.logPath);
if (compose.sourceType === "github") {
await cloneGithubRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "gitlab") {
await cloneGitlabRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "bitbucket") {
await cloneBitbucketRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "git") {
await cloneGitRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "raw") {
await createComposeFile(compose, deployment.logPath);
}
await buildCompose(compose, deployment.logPath);
await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, {
composeStatus: "done",
@ -334,6 +288,132 @@ export const rebuildCompose = async ({
return true;
};
export const deployRemoteCompose = async ({
composeId,
titleLog = "Manual deployment",
descriptionLog = "",
}: {
composeId: string;
titleLog: string;
descriptionLog: string;
}) => {
const compose = await findComposeById(composeId);
const buildLink = `${await getDokployUrl()}/dashboard/project/${compose.projectId}/services/compose/${compose.composeId}?tab=deployments`;
const deployment = await createDeploymentCompose({
composeId: composeId,
title: titleLog,
description: descriptionLog,
});
try {
if (compose.serverId) {
let command = "set -e;";
if (compose.sourceType === "github") {
command += await getGithubCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "gitlab") {
command += await getGitlabCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "bitbucket") {
command += await getBitbucketCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "git") {
command += await getCustomGitCloneCommand(
compose,
deployment.logPath,
true,
);
} else if (compose.sourceType === "raw") {
command += getCreateComposeFileCommand(compose, deployment.logPath);
}
async function* sequentialSteps() {
yield execAsyncRemote(compose.serverId, command);
yield getBuildComposeCommand(compose, deployment.logPath);
}
const steps = sequentialSteps();
for await (const step of steps) {
step;
}
console.log(" ---- done ----");
}
await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, {
composeStatus: "done",
});
await sendBuildSuccessNotifications({
projectName: compose.project.name,
applicationName: compose.name,
applicationType: "compose",
buildLink,
});
} catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, {
composeStatus: "error",
});
await sendBuildErrorNotifications({
projectName: compose.project.name,
applicationName: compose.name,
applicationType: "compose",
// @ts-ignore
errorMessage: error?.message || "Error to build",
buildLink,
});
throw error;
}
};
export const rebuildRemoteCompose = async ({
composeId,
titleLog = "Rebuild deployment",
descriptionLog = "",
}: {
composeId: string;
titleLog: string;
descriptionLog: string;
}) => {
const compose = await findComposeById(composeId);
const deployment = await createDeploymentCompose({
composeId: composeId,
title: titleLog,
description: descriptionLog,
});
try {
if (compose.serverId) {
await getBuildComposeCommand(compose, deployment.logPath);
}
await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, {
composeStatus: "done",
});
} catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, {
composeStatus: "error",
});
throw error;
}
return true;
};
export const removeCompose = async (compose: Compose) => {
try {
const projectPath = join(COMPOSE_PATH, compose.appName);

View File

@ -1,12 +1,16 @@
import { type Job, Worker } from "bullmq";
import {
deployApplication,
deployRemoteApplication,
rebuildApplication,
rebuildRemoteApplication,
updateApplicationStatus,
} from "../api/services/application";
import {
deployCompose,
deployRemoteCompose,
rebuildCompose,
rebuildRemoteCompose,
updateCompose,
} from "../api/services/compose";
import { myQueue, redisConfig } from "./queueSetup";
@ -16,6 +20,7 @@ type DeployJob =
applicationId: string;
titleLog: string;
descriptionLog: string;
server?: boolean;
type: "deploy" | "redeploy";
applicationType: "application";
}
@ -23,6 +28,7 @@ type DeployJob =
composeId: string;
titleLog: string;
descriptionLog: string;
server?: boolean;
type: "deploy" | "redeploy";
applicationType: "compose";
};
@ -35,35 +41,68 @@ export const deploymentWorker = new Worker(
try {
if (job.data.applicationType === "application") {
await updateApplicationStatus(job.data.applicationId, "running");
if (job.data.type === "redeploy") {
await rebuildApplication({
applicationId: job.data.applicationId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
} else if (job.data.type === "deploy") {
await deployApplication({
applicationId: job.data.applicationId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
if (job.data.server) {
if (job.data.type === "redeploy") {
await rebuildRemoteApplication({
applicationId: job.data.applicationId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
} else if (job.data.type === "deploy") {
await deployRemoteApplication({
applicationId: job.data.applicationId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
}
} else {
if (job.data.type === "redeploy") {
await rebuildApplication({
applicationId: job.data.applicationId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
} else if (job.data.type === "deploy") {
await deployApplication({
applicationId: job.data.applicationId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
}
}
} else if (job.data.applicationType === "compose") {
await updateCompose(job.data.composeId, {
composeStatus: "running",
});
if (job.data.type === "deploy") {
await deployCompose({
composeId: job.data.composeId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
} else if (job.data.type === "redeploy") {
await rebuildCompose({
composeId: job.data.composeId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
if (job.data.server) {
if (job.data.type === "redeploy") {
await rebuildRemoteCompose({
composeId: job.data.composeId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
} else if (job.data.type === "deploy") {
await deployRemoteCompose({
composeId: job.data.composeId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
}
} else {
if (job.data.type === "deploy") {
await deployCompose({
composeId: job.data.composeId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
} else if (job.data.type === "redeploy") {
await rebuildCompose({
composeId: job.data.composeId,
titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
});
}
}
}
} catch (error) {

View File

@ -9,6 +9,7 @@ import { COMPOSE_PATH } from "@/server/constants";
import type { InferResultType } from "@/server/types/with";
import boxen from "boxen";
import {
getComposePath,
writeDomainsToCompose,
writeDomainsToComposeRemote,
} from "../docker/domain";
@ -73,12 +74,17 @@ export const getBuildComposeCommand = async (
compose: ComposeNested,
logPath: string,
) => {
const { sourceType, appName, mounts, composeType, domains } = compose;
const { sourceType, appName, mounts, composeType, domains, composePath } =
compose;
const command = createCommand(compose);
const envCommand = getCreateEnvFileCommand(compose);
const projectPath = join(COMPOSE_PATH, compose.appName, "code");
const newCompose = await writeDomainsToComposeRemote(compose, domains);
const newCompose = await writeDomainsToComposeRemote(
compose,
domains,
logPath,
);
const logContent = `
App Name: ${appName}
Build Compose 🐳
@ -107,6 +113,11 @@ Compose Type: ${composeType} ✅`;
${envCommand}
cd "${projectPath}";
if [ ! -f "${composePath}" ]; then
echo "❌ Error: Compose file not found" >> "${logPath}";
exit 1;
fi
docker ${command.split(" ").join(" ")} >> "${logPath}" 2>&1 || { echo "Error: ❌ Docker command failed" >> "${logPath}"; exit 1; }

View File

@ -6,7 +6,7 @@ import {
getDockerContextPath,
} from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
import { createEnvFile } from "./utils";
import { createEnvFile, createEnvFileCommand } from "./utils";
export const buildCustomDocker = async (
application: ApplicationNested,
@ -86,11 +86,27 @@ export const getDockerCommand = (
commandArgs.push("--build-arg", arg);
}
const command = `
/*
Do not generate an environment file when publishDirectory is specified,
as it could be publicly exposed.
*/
let command = "";
if (!publishDirectory) {
command += createEnvFileCommand(dockerFilePath, env);
}
command = `
echo "Building ${appName}" >> ${logPath};
cd ${dockerContextPath} || exit 1;
docker ${commandArgs.join(" ")} >> ${logPath} 2>&1;
echo "Docker build completed." >> ${logPath};
cd ${dockerContextPath} >> ${logPath} 2>> ${logPath} || {
echo "❌ The path ${dockerContextPath} does not exist" >> ${logPath};
exit 1;
}
docker ${commandArgs.join(" ")} >> ${logPath} 2>> ${logPath} || {
echo "❌ Docker build failed" >> ${logPath};
exit 1;
}
echo "✅ Docker build completed." >> ${logPath};
`;
return command;

View File

@ -62,8 +62,11 @@ export const getHerokuCommand = (
const command = `pack ${args.join(" ")}`;
const bashCommand = `
echo "Starting heroku build..." >> ${logPath};
${command} >> ${logPath} 2>&1;
echo "Heroku build completed." >> ${logPath};
${command} >> ${logPath} 2>> ${logPath} || {
echo "❌ Heroku build failed" >> ${logPath};
exit 1;
}
echo "✅ Heroku build completed." >> ${logPath};
`;
return bashCommand;

View File

@ -16,7 +16,7 @@ import { buildCustomDocker, getDockerCommand } from "./docker-file";
import { buildHeroku, getHerokuCommand } from "./heroku";
import { buildNixpacks, getNixpacksCommand } from "./nixpacks";
import { buildPaketo, getPaketoCommand } from "./paketo";
import { buildStatic } from "./static";
import { buildStatic, getStaticCommand } from "./static";
import { findServerById } from "@/server/api/services/server";
import { readSSHKey } from "../filesystem/ssh";
import { getRemoteDocker } from "../servers/remote-docker";
@ -81,8 +81,8 @@ export const getBuildCommand = (
return getHerokuCommand(application, logPath);
case "paketo_buildpacks":
return getPaketoCommand(application, logPath);
// case "static":
// return buildStatic(application, writeStream);
case "static":
return getStaticCommand(application, logPath);
case "dockerfile":
return getDockerCommand(application, logPath);
}

View File

@ -1,12 +1,11 @@
import type { WriteStream } from "node:fs";
import path from "node:path";
import { buildStatic } from "@/server/utils/builders/static";
import { buildStatic, getStaticCommand } from "@/server/utils/builders/static";
import { nanoid } from "nanoid";
import type { ApplicationNested } from ".";
import { prepareEnvironmentVariables } from "../docker/utils";
import { getBuildAppDirectory } from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
import { executeCommand } from "../servers/command";
export const buildNixpacks = async (
application: ApplicationNested,
@ -83,47 +82,44 @@ export const getNixpacksCommand = (
const buildContainerId = `${appName}-${nanoid(10)}`;
const envVariables = prepareEnvironmentVariables(env);
try {
const args = ["build", buildAppDirectory, "--name", appName];
const args = ["build", buildAppDirectory, "--name", appName];
for (const env of envVariables) {
args.push("--env", env);
}
for (const env of envVariables) {
args.push("--env", env);
}
if (publishDirectory) {
/* No need for any start command, since we'll use nginx later on */
args.push("--no-error-without-start");
}
console.log("args", args);
const command = `nixpacks ${args.join(" ")}`;
const bashCommand = `
if (publishDirectory) {
/* No need for any start command, since we'll use nginx later on */
args.push("--no-error-without-start");
}
console.log("args", args);
const command = `nixpacks ${args.join(" ")}`;
let bashCommand = `
echo "Starting nixpacks build..." >> ${logPath};
${command} >> ${logPath} 2>&1;
echo "Nixpacks build completed." >> ${logPath};
${command} >> ${logPath} 2>> ${logPath} || {
echo "❌ Nixpacks build failed" >> ${logPath};
exit 1;
}
echo "✅ Nixpacks build completed." >> ${logPath};
`;
/*
Run the container with the image created by nixpacks,
and copy the artifacts on the host filesystem.
Then, remove the container and create a static build.
*/
if (publishDirectory) {
}
// if (publishDirectory) {
// bashCommand += `
// docker create --name ${buildContainerId} ${appName}
// docker cp ${buildContainerId}:/app/${publishDirectory} ${path.join(buildAppDirectory, publishDirectory)}
// docker rm ${buildContainerId}
// buildStatic ${application} ${writeStream}
// `;
// }
return bashCommand;
} catch (e) {
// await spawnAsync("docker", ["rm", buildContainerId], writeToStream);
throw e;
/*
Run the container with the image created by nixpacks,
and copy the artifacts on the host filesystem.
Then, remove the container and create a static build.
*/
if (publishDirectory) {
bashCommand += `
docker create --name ${buildContainerId} ${appName}
docker cp ${buildContainerId}:/app/${publishDirectory} ${path.join(buildAppDirectory, publishDirectory)} >> ${logPath} 2>> ${logPath} || {
docker rm ${buildContainerId}
echo "❌ Copying ${publishDirectory} to ${path.join(buildAppDirectory, publishDirectory)} failed" >> ${logPath};
exit 1;
}
docker rm ${buildContainerId}
${getStaticCommand(application, logPath)}
`;
}
return bashCommand;
};

View File

@ -61,8 +61,11 @@ export const getPaketoCommand = (
const command = `pack ${args.join(" ")}`;
const bashCommand = `
echo "Starting Paketo build..." >> ${logPath};
${command} >> ${logPath} 2>&1;
echo "Paketo build completed." >> ${logPath};
${command} >> ${logPath} 2>> ${logPath} || {
echo "❌ Paketo build failed" >> ${logPath};
exit 1;
}
echo "✅ Paketo build completed." >> ${logPath};
`;
return bashCommand;

View File

@ -1,7 +1,10 @@
import type { WriteStream } from "node:fs";
import { buildCustomDocker } from "@/server/utils/builders/docker-file";
import {
buildCustomDocker,
getDockerCommand,
} from "@/server/utils/builders/docker-file";
import type { ApplicationNested } from ".";
import { createFile } from "../docker/utils";
import { createFile, getCreateFileCommand } from "../docker/utils";
import { getBuildAppDirectory } from "../filesystem/directory";
export const buildStatic = async (
@ -36,3 +39,31 @@ export const buildStatic = async (
throw e;
}
};
export const getStaticCommand = (
application: ApplicationNested,
logPath: string,
) => {
const { publishDirectory } = application;
const buildAppDirectory = getBuildAppDirectory(application);
let command = getCreateFileCommand(
buildAppDirectory,
"Dockerfile",
[
"FROM nginx:alpine",
"WORKDIR /usr/share/nginx/html/",
`COPY ${publishDirectory || "."} .`,
].join("\n"),
);
command += getDockerCommand(
{
...application,
buildType: "dockerfile",
dockerfile: "Dockerfile",
},
logPath,
);
return command;
};

View File

@ -13,7 +13,6 @@ export const createEnvFile = (directory: string, env: string | null) => {
export const createEnvFileCommand = (directory: string, env: string | null) => {
const envFilePath = join(dirname(directory), ".env");
// let command = ``
if (!existsSync(dirname(envFilePath))) {
mkdirSync(dirname(envFilePath), { recursive: true });
}

View File

@ -96,7 +96,14 @@ export const loadDockerComposeRemote = async (
if (!compose.serverId) {
return null;
}
const { stdout } = await execAsyncRemote(compose.serverId, `cat ${path}`);
const { stdout, stderr } = await execAsyncRemote(
compose.serverId,
`cat ${path}`,
);
if (stderr) {
return null;
}
if (!stdout) return null;
const parsedConfig = load(stdout) as ComposeSpecification;
return parsedConfig;
@ -135,21 +142,25 @@ export const writeDomainsToCompose = async (
export const writeDomainsToComposeRemote = async (
compose: Compose,
domains: Domain[],
logPath: string,
) => {
if (!domains.length) {
return "";
}
const composeConverted = await addDomainToCompose(compose, domains);
const path = getComposePath(compose);
try {
const composeConverted = await addDomainToCompose(compose, domains);
const path = getComposePath(compose);
if (compose.serverId) {
const composeString = dump(composeConverted, { lineWidth: 1000 });
const encodedContent = encodeBase64(composeString);
return `echo "${encodedContent}" | base64 -d > "${path}";`;
}
} catch (error) {
throw error;
return `
echo "❌ Has occured an error: ${error?.message || error}" >> ${logPath};
exit 1;
`;
}
};
// (node:59875) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. Use emitter.setMaxListeners() to increase limit

View File

@ -59,24 +59,26 @@ export const buildRemoteDocker = async (
throw new Error("Docker image not found");
}
let command = `
echo "Building ${sourceType}" >> ${logPath};
echo "Pulling ${dockerImage}" >> ${logPath};
`;
if (username && password) {
command += `
if ! docker login --username ${username} --password ${password} https://index.docker.io/v1/ >> ${logPath} 2>&1; then
echo "Error logging in to Docker Hub" >> ${logPath};
echo "❌ Login failed" >> ${logPath};
exit 1;
fi
`;
}
command += `
echo "Pulling ${dockerImage}" >> ${logPath};
docker pull ${dockerImage} >> ${logPath} 2>&1;
`;
docker pull ${dockerImage} >> ${logPath} 2>> ${logPath} || {
echo "❌ Pulling image failed" >> ${logPath};
exit 1;
}
echo "✅ Pulling image completed." >> ${logPath};
`;
return command;
} catch (error) {
throw error;

View File

@ -29,7 +29,10 @@ export const createComposeFile = async (compose: Compose, logPath: string) => {
}
};
export const getCreateComposeFileCommand = (compose: Compose) => {
export const getCreateComposeFileCommand = (
compose: Compose,
logPath: string,
) => {
const { appName, composeFile } = compose;
const outputPath = join(COMPOSE_PATH, appName, "code");
const filePath = join(outputPath, "docker-compose.yml");
@ -38,6 +41,7 @@ export const getCreateComposeFileCommand = (compose: Compose) => {
rm -rf ${outputPath};
mkdir -p ${outputPath};
echo "${encodedContent}" | base64 -d > "${filePath}";
echo "File 'docker-compose.yml' created: ✅" >> ${logPath};
`;
return bashCommand;
};