From 94786c738bb255378a581e591c798aa780341239 Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:27:00 +0100 Subject: [PATCH 1/8] feat: added env support for dokploy --- .../services/compose/[composeId].tsx | 10 +--- packages/server/src/utils/builders/compose.ts | 48 ++++++++++++++++++- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx index 60ddfeab..bcac11ed 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx @@ -185,18 +185,12 @@ const Service = (
General - {data?.composeType === "docker-compose" && ( - Environment - )} + Environment {!data?.serverId && ( Monitoring )} diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 7d3ce0ec..c2924897 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -2,12 +2,14 @@ import { createWriteStream, existsSync, mkdirSync, + readFileSync, 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 dotenv from "dotenv"; import { writeDomainsToCompose, writeDomainsToComposeRemote, @@ -28,6 +30,7 @@ export const buildCompose = async (compose: ComposeNested, logPath: string) => { const command = createCommand(compose); await writeDomainsToCompose(compose, domains); createEnvFile(compose); + processComposeFile(compose); const logContent = ` App Name: ${appName} @@ -84,6 +87,7 @@ export const getBuildComposeCommand = async ( const command = createCommand(compose); const envCommand = getCreateEnvFileCommand(compose); const projectPath = join(COMPOSE_PATH, compose.appName, "code"); + const processComposeFileCommand = getProcessComposeFileCommand(compose); const newCompose = await writeDomainsToComposeRemote( compose, @@ -119,6 +123,8 @@ Compose Type: ${composeType} ✅`; cd "${projectPath}"; + ${processComposeFileCommand} + docker ${command.split(" ").join(" ")} >> "${logPath}" 2>&1 || { echo "Error: ❌ Docker command failed" >> "${logPath}"; exit 1; } echo "Docker Compose Deployed: ✅" >> "${logPath}" @@ -145,7 +151,7 @@ export const createCommand = (compose: ComposeNested) => { const { composeType, appName, sourceType } = compose; const path = - sourceType === "raw" ? "docker-compose.yml" : compose.composePath; + sourceType === "raw" ? "docker-compose.processed.yml" : compose.composePath; let command = ""; if (composeType === "docker-compose") { @@ -188,6 +194,46 @@ const createEnvFile = (compose: ComposeNested) => { writeFileSync(envFilePath, envFileContent); }; +export const processComposeFile = (compose: ComposeNested) => { + const { COMPOSE_PATH } = paths(); + const { env, appName, sourceType, composeType } = compose; + + if (composeType === "stack") { + const inputPath = + sourceType === "raw" ? "docker-compose.yml" : compose.composePath; + const composeInputFilePath = + join(COMPOSE_PATH, appName, "code", inputPath) || + join(COMPOSE_PATH, appName, "code", "docker-compose.yml"); + + const outputPath = "docker-compose.processed.yml"; + const composeOutputFilePath = + join(COMPOSE_PATH, appName, "code", outputPath) || + join(COMPOSE_PATH, appName, "code", "docker-compose.processed.yml"); + + const envContent = prepareEnvironmentVariables(env || "").join("\n"); + const envVariables = dotenv.parse(envContent); + + let templateContent = readFileSync(composeInputFilePath, "utf8"); + + templateContent = templateContent.replace( + /\$\{([^}]+)\}/g, + (_, varName) => { + return envVariables[varName] || ""; + }, + ); + + writeFileSync(composeOutputFilePath, templateContent); + } +}; + +export const getProcessComposeFileCommand = (compose: ComposeNested) => { + const { composeType } = compose; + if (composeType === "stack") { + return "set -a; source .env; set +a; envsubst < docker-compose.yml > docker-compose.processed.yml"; + } + return "cp docker-compose.yml docker-compose.processed.yml"; +}; + export const getCreateEnvFileCommand = (compose: ComposeNested) => { const { COMPOSE_PATH } = paths(true); const { env, composePath, appName } = compose; From cb02deb837065438cc6de1f431d9297485b1279a Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:15:12 +0100 Subject: [PATCH 2/8] fix(builder): fixed docker-compose issue --- packages/server/src/utils/builders/compose.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index c2924897..fd9824eb 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -198,32 +198,32 @@ export const processComposeFile = (compose: ComposeNested) => { const { COMPOSE_PATH } = paths(); const { env, appName, sourceType, composeType } = compose; - if (composeType === "stack") { - const inputPath = - sourceType === "raw" ? "docker-compose.yml" : compose.composePath; - const composeInputFilePath = - join(COMPOSE_PATH, appName, "code", inputPath) || - join(COMPOSE_PATH, appName, "code", "docker-compose.yml"); + const inputPath = + sourceType === "raw" ? "docker-compose.yml" : compose.composePath; + const composeInputFilePath = + join(COMPOSE_PATH, appName, "code", inputPath) || + join(COMPOSE_PATH, appName, "code", "docker-compose.yml"); - const outputPath = "docker-compose.processed.yml"; - const composeOutputFilePath = - join(COMPOSE_PATH, appName, "code", outputPath) || - join(COMPOSE_PATH, appName, "code", "docker-compose.processed.yml"); + const outputPath = "docker-compose.processed.yml"; + const composeOutputFilePath = + join(COMPOSE_PATH, appName, "code", outputPath) || + join(COMPOSE_PATH, appName, "code", "docker-compose.processed.yml"); + let templateContent = readFileSync(composeInputFilePath, "utf8"); + + if (composeType === "stack") { const envContent = prepareEnvironmentVariables(env || "").join("\n"); const envVariables = dotenv.parse(envContent); - let templateContent = readFileSync(composeInputFilePath, "utf8"); - templateContent = templateContent.replace( /\$\{([^}]+)\}/g, (_, varName) => { return envVariables[varName] || ""; }, ); - - writeFileSync(composeOutputFilePath, templateContent); } + + writeFileSync(composeOutputFilePath, templateContent); }; export const getProcessComposeFileCommand = (compose: ComposeNested) => { From dc1e12d6ed19ae1ec9d2e7b69b97d6a35464bd8b Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:35:42 +0100 Subject: [PATCH 3/8] feat(compose): added stop functionality for stack --- .../components/dashboard/compose/general/actions.tsx | 2 +- packages/server/src/services/compose.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/dokploy/components/dashboard/compose/general/actions.tsx b/apps/dokploy/components/dashboard/compose/general/actions.tsx index 365e37f5..37f8ffa8 100644 --- a/apps/dokploy/components/dashboard/compose/general/actions.tsx +++ b/apps/dokploy/components/dashboard/compose/general/actions.tsx @@ -71,7 +71,7 @@ export const ComposeActions = ({ composeId }: Props) => { Autodeploy {data?.autoDeploy && } - {data?.composeType === "docker-compose" && ( + {["running", "done"].includes(data?.composeStatus || "") && ( )} diff --git a/packages/server/src/services/compose.ts b/packages/server/src/services/compose.ts index 61d7e5fc..7382fa99 100644 --- a/packages/server/src/services/compose.ts +++ b/packages/server/src/services/compose.ts @@ -476,6 +476,17 @@ export const stopCompose = async (composeId: string) => { } } + if (compose.composeType === "stack") { + if (compose.serverId) { + await execAsyncRemote( + compose.serverId, + `docker stack rm ${compose.appName}`, + ); + } else { + await execAsync(`docker stack rm ${compose.appName}`); + } + } + await updateCompose(composeId, { composeStatus: "idle", }); From 06081627e85fec85198f9bc7c17ae1b0239251b0 Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Sat, 2 Nov 2024 00:35:38 +0100 Subject: [PATCH 4/8] refactor: used docker stack config --- packages/server/src/utils/builders/compose.ts | 54 ++++++++----------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index fd9824eb..8d521d61 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -15,7 +15,7 @@ import { writeDomainsToComposeRemote, } from "../docker/domain"; import { encodeBase64, prepareEnvironmentVariables } from "../docker/utils"; -import { execAsyncRemote } from "../process/execAsync"; +import { execAsync, execAsyncRemote } from "../process/execAsync"; import { spawnAsync } from "../process/spawnAsync"; export type ComposeNested = InferResultType< @@ -30,7 +30,7 @@ export const buildCompose = async (compose: ComposeNested, logPath: string) => { const command = createCommand(compose); await writeDomainsToCompose(compose, domains); createEnvFile(compose); - processComposeFile(compose); + await processComposeFile(compose); const logContent = ` App Name: ${appName} @@ -194,44 +194,34 @@ const createEnvFile = (compose: ComposeNested) => { writeFileSync(envFilePath, envFileContent); }; -export const processComposeFile = (compose: ComposeNested) => { +export const processComposeFile = async (compose: ComposeNested) => { const { COMPOSE_PATH } = paths(); - const { env, appName, sourceType, composeType } = compose; - - const inputPath = - sourceType === "raw" ? "docker-compose.yml" : compose.composePath; - const composeInputFilePath = - join(COMPOSE_PATH, appName, "code", inputPath) || - join(COMPOSE_PATH, appName, "code", "docker-compose.yml"); - - const outputPath = "docker-compose.processed.yml"; - const composeOutputFilePath = - join(COMPOSE_PATH, appName, "code", outputPath) || - join(COMPOSE_PATH, appName, "code", "docker-compose.processed.yml"); - - let templateContent = readFileSync(composeInputFilePath, "utf8"); - - if (composeType === "stack") { - const envContent = prepareEnvironmentVariables(env || "").join("\n"); - const envVariables = dotenv.parse(envContent); - - templateContent = templateContent.replace( - /\$\{([^}]+)\}/g, - (_, varName) => { - return envVariables[varName] || ""; - }, - ); + let command = getProcessComposeFileCommand(compose); + + if (compose.serverId) { + command = `cd ${join(COMPOSE_PATH, compose.appName, "code")} && ${command}`; + await execAsyncRemote(compose.serverId, command); + } else { + await execAsync(command, { + cwd: join(COMPOSE_PATH, compose.appName, "code"), + }); } - - writeFileSync(composeOutputFilePath, templateContent); }; export const getProcessComposeFileCommand = (compose: ComposeNested) => { const { composeType } = compose; + + let command = ""; + if (composeType === "stack") { - return "set -a; source .env; set +a; envsubst < docker-compose.yml > docker-compose.processed.yml"; + command = `export $(grep -v '^#' .env | xargs) && docker stack config -c docker-compose.yml > docker-compose.processed.yml`; } - return "cp docker-compose.yml docker-compose.processed.yml"; + + if (composeType === "docker-compose") { + command = "cp docker-compose.yml docker-compose.processed.yml"; + } + + return command; }; export const getCreateEnvFileCommand = (compose: ComposeNested) => { From 9c355bcfb7426fc31b0f0b57d46989f96256c0c2 Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Sat, 2 Nov 2024 12:42:53 +0100 Subject: [PATCH 5/8] refactor(builder): removed unused and redundant code --- packages/server/src/utils/builders/compose.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 8d521d61..dd48e0c2 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -2,14 +2,12 @@ import { createWriteStream, existsSync, mkdirSync, - readFileSync, 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 dotenv from "dotenv"; import { writeDomainsToCompose, writeDomainsToComposeRemote, @@ -196,10 +194,9 @@ const createEnvFile = (compose: ComposeNested) => { export const processComposeFile = async (compose: ComposeNested) => { const { COMPOSE_PATH } = paths(); - let command = getProcessComposeFileCommand(compose); + const command = getProcessComposeFileCommand(compose); if (compose.serverId) { - command = `cd ${join(COMPOSE_PATH, compose.appName, "code")} && ${command}`; await execAsyncRemote(compose.serverId, command); } else { await execAsync(command, { From 06cbd1fce1a96692917e7c6b88b87155174e77d7 Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Sun, 3 Nov 2024 15:26:54 +0100 Subject: [PATCH 6/8] refactor(bundler): removed redundant code --- packages/server/src/utils/builders/compose.ts | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index dd48e0c2..514d7bd8 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -148,8 +148,17 @@ const sanitizeCommand = (command: string) => { export const createCommand = (compose: ComposeNested) => { const { composeType, appName, sourceType } = compose; - const path = - sourceType === "raw" ? "docker-compose.processed.yml" : compose.composePath; + let path = ""; + + if (sourceType !== "raw") { + path = compose.composePath; + } else { + path = + composeType === "stack" + ? "docker-compose.processed.yml" + : "docker-compose.yml"; + } + let command = ""; if (composeType === "docker-compose") { @@ -196,13 +205,9 @@ export const processComposeFile = async (compose: ComposeNested) => { const { COMPOSE_PATH } = paths(); const command = getProcessComposeFileCommand(compose); - if (compose.serverId) { - await execAsyncRemote(compose.serverId, command); - } else { - await execAsync(command, { - cwd: join(COMPOSE_PATH, compose.appName, "code"), - }); - } + await execAsync(command, { + cwd: join(COMPOSE_PATH, compose.appName, "code"), + }); }; export const getProcessComposeFileCommand = (compose: ComposeNested) => { @@ -214,10 +219,6 @@ export const getProcessComposeFileCommand = (compose: ComposeNested) => { command = `export $(grep -v '^#' .env | xargs) && docker stack config -c docker-compose.yml > docker-compose.processed.yml`; } - if (composeType === "docker-compose") { - command = "cp docker-compose.yml docker-compose.processed.yml"; - } - return command; }; From f772fec407d937b92812d092ac00001cb7744a44 Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:02:46 +0100 Subject: [PATCH 7/8] fix(bundler): docker-compose bug --- packages/server/src/utils/builders/compose.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 514d7bd8..8941f4e1 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -150,15 +150,17 @@ export const createCommand = (compose: ComposeNested) => { let path = ""; - if (sourceType !== "raw") { - path = compose.composePath; - } else { + if (sourceType === "raw") { path = composeType === "stack" ? "docker-compose.processed.yml" : "docker-compose.yml"; + } else { + path = compose.composePath; } + console.log(path); + let command = ""; if (composeType === "docker-compose") { @@ -203,11 +205,12 @@ const createEnvFile = (compose: ComposeNested) => { export const processComposeFile = async (compose: ComposeNested) => { const { COMPOSE_PATH } = paths(); - const command = getProcessComposeFileCommand(compose); - - await execAsync(command, { - cwd: join(COMPOSE_PATH, compose.appName, "code"), - }); + if (compose.composeType === "stack") { + const command = getProcessComposeFileCommand(compose); + await execAsync(command, { + cwd: join(COMPOSE_PATH, compose.appName, "code"), + }); + } }; export const getProcessComposeFileCommand = (compose: ComposeNested) => { From dafed3096f80c282e1033c2c6e51393db1fdd16f Mon Sep 17 00:00:00 2001 From: xenonwellz <59710311+xenonwellz@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:47:58 +0100 Subject: [PATCH 8/8] refactor(builder): removed path log --- packages/server/src/utils/builders/compose.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 8941f4e1..38d94ab1 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -159,8 +159,6 @@ export const createCommand = (compose: ComposeNested) => { path = compose.composePath; } - console.log(path); - let command = ""; if (composeType === "docker-compose") {