From 815b8136fa0f8e803c43e66ed0002952515d54c3 Mon Sep 17 00:00:00 2001 From: Tam Nguyen Date: Mon, 30 Mar 2026 08:59:14 +1100 Subject: [PATCH] fix: further typos --- .../compose/network/network-root.test.ts | 2 +- .../compose/network/network-service.test.ts | 212 +++--- ...m.test.ts => service-volumes-from.test.ts} | 0 .../__test__/env/stack-environment.test.ts | 198 ++--- .../advanced/redirects/handle-redirect.tsx | 2 +- ...ow-enviroment.tsx => show-environment.tsx} | 0 .../dashboard/application/logs/show.tsx | 4 +- .../dashboard/compose/logs/show-stack.tsx | 4 +- .../database/backups/restore-backup.tsx | 6 +- .../dashboard/docker/logs/terminal-line.tsx | 2 +- .../docker/show/{colums.tsx => columns.tsx} | 0 .../dashboard/docker/show/show-containers.tsx | 2 +- .../settings/servers/setup-server.tsx | 2 +- .../settings/servers/show-servers.tsx | 4 +- ...scription.tsx => welcome-subscription.tsx} | 2 +- apps/dokploy/components/ui/file-tree.tsx | 12 +- .../pages/api/deploy/[refreshToken].ts | 12 +- .../api/deploy/compose/[refreshToken].ts | 6 +- apps/dokploy/pages/api/stripe/webhook.ts | 12 +- .../services/compose/[composeId].tsx | 2 +- .../services/libsql/[libsqlId].tsx | 2 +- .../services/mariadb/[mariadbId].tsx | 2 +- .../services/mongo/[mongoId].tsx | 2 +- .../services/mysql/[mysqlId].tsx | 2 +- .../services/postgres/[postgresId].tsx | 2 +- .../services/redis/[redisId].tsx | 2 +- .../dokploy/server/api/routers/destination.ts | 4 +- packages/server/src/index.ts | 2 +- packages/server/src/services/deployment.ts | 12 +- packages/server/src/services/destination.ts | 2 +- packages/server/src/services/settings.ts | 4 +- packages/server/src/services/user.ts | 678 +++++++++--------- packages/server/src/setup/setup.ts | 8 +- packages/server/src/utils/builders/compose.ts | 152 ++-- .../server/src/utils/builders/docker-file.ts | 134 ++-- packages/server/src/utils/docker/utils.ts | 2 +- ...l-deployments.ts => cancel-deployments.ts} | 0 37 files changed, 747 insertions(+), 747 deletions(-) rename apps/dokploy/__test__/compose/service/{sevice-volumes-from.test.ts => service-volumes-from.test.ts} (100%) rename apps/dokploy/components/dashboard/application/environment/{show-enviroment.tsx => show-environment.tsx} (100%) rename apps/dokploy/components/dashboard/docker/show/{colums.tsx => columns.tsx} (100%) rename apps/dokploy/components/dashboard/settings/servers/welcome-stripe/{welcome-suscription.tsx => welcome-subscription.tsx} (99%) rename packages/server/src/utils/startup/{cancell-deployments.ts => cancel-deployments.ts} (100%) diff --git a/apps/dokploy/__test__/compose/network/network-root.test.ts b/apps/dokploy/__test__/compose/network/network-root.test.ts index 0d3c841d4..1a6817913 100644 --- a/apps/dokploy/__test__/compose/network/network-root.test.ts +++ b/apps/dokploy/__test__/compose/network/network-root.test.ts @@ -292,7 +292,7 @@ networks: dokploy-network: `; -test("It shoudn't add suffix to dokploy-network", () => { +test("It shouldn't add suffix to dokploy-network", () => { const composeData = parse(composeFile7) as ComposeSpecification; const suffix = generateRandomHash(); diff --git a/apps/dokploy/__test__/compose/network/network-service.test.ts b/apps/dokploy/__test__/compose/network/network-service.test.ts index e07fa1546..91eb5da4e 100644 --- a/apps/dokploy/__test__/compose/network/network-service.test.ts +++ b/apps/dokploy/__test__/compose/network/network-service.test.ts @@ -1,7 +1,7 @@ import type { ComposeSpecification } from "@dokploy/server"; import { - addSuffixToServiceNetworks, - generateRandomHash, + addSuffixToServiceNetworks, + generateRandomHash, } from "@dokploy/server"; import { expect, test } from "vitest"; import { parse } from "yaml"; @@ -23,30 +23,30 @@ services: `; test("Add suffix to networks in services", () => { - const composeData = parse(composeFile) as ComposeSpecification; + const composeData = parse(composeFile) as ComposeSpecification; - const suffix = generateRandomHash(); + const suffix = generateRandomHash(); - if (!composeData?.services) { - return; - } - const services = addSuffixToServiceNetworks(composeData.services, suffix); - const actualComposeData = { ...composeData, services }; + if (!composeData?.services) { + return; + } + const services = addSuffixToServiceNetworks(composeData.services, suffix); + const actualComposeData = { ...composeData, services }; - expect(actualComposeData?.services?.web?.networks).toContain( - `frontend-${suffix}`, - ); + expect(actualComposeData?.services?.web?.networks).toContain( + `frontend-${suffix}`, + ); - expect(actualComposeData?.services?.api?.networks).toContain( - `backend-${suffix}`, - ); + expect(actualComposeData?.services?.api?.networks).toContain( + `backend-${suffix}`, + ); - const apiNetworks = actualComposeData?.services?.api?.networks; + const apiNetworks = actualComposeData?.services?.api?.networks; - expect(apiNetworks).toBeDefined(); - expect(actualComposeData?.services?.api?.networks).toContain( - `backend-${suffix}`, - ); + expect(apiNetworks).toBeDefined(); + expect(actualComposeData?.services?.api?.networks).toContain( + `backend-${suffix}`, + ); }); // Caso 2: Objeto con aliases @@ -67,29 +67,29 @@ networks: `; test("Add suffix to networks in services with aliases", () => { - const composeData = parse(composeFile2) as ComposeSpecification; + const composeData = parse(composeFile2) as ComposeSpecification; - const suffix = generateRandomHash(); + const suffix = generateRandomHash(); - if (!composeData?.services) { - return; - } - const services = addSuffixToServiceNetworks(composeData.services, suffix); - const actualComposeData = { ...composeData, services }; + if (!composeData?.services) { + return; + } + const services = addSuffixToServiceNetworks(composeData.services, suffix); + const actualComposeData = { ...composeData, services }; - expect(actualComposeData.services?.api?.networks).toHaveProperty( - `frontend-${suffix}`, - ); + expect(actualComposeData.services?.api?.networks).toHaveProperty( + `frontend-${suffix}`, + ); - const networkConfig = actualComposeData?.services?.api?.networks as { - [key: string]: { aliases?: string[] }; - }; - expect(networkConfig[`frontend-${suffix}`]).toBeDefined(); - expect(networkConfig[`frontend-${suffix}`]?.aliases).toContain("api"); + const networkConfig = actualComposeData?.services?.api?.networks as { + [key: string]: { aliases?: string[] }; + }; + expect(networkConfig[`frontend-${suffix}`]).toBeDefined(); + expect(networkConfig[`frontend-${suffix}`]?.aliases).toContain("api"); - expect(actualComposeData.services?.api?.networks).not.toHaveProperty( - "frontend-ash", - ); + expect(actualComposeData.services?.api?.networks).not.toHaveProperty( + "frontend-ash", + ); }); const composeFile3 = ` @@ -107,19 +107,19 @@ networks: `; test("Add suffix to networks in services (Object with simple networks)", () => { - const composeData = parse(composeFile3) as ComposeSpecification; + const composeData = parse(composeFile3) as ComposeSpecification; - const suffix = generateRandomHash(); + const suffix = generateRandomHash(); - if (!composeData?.services) { - return; - } - const services = addSuffixToServiceNetworks(composeData.services, suffix); - const actualComposeData = { ...composeData, services }; + if (!composeData?.services) { + return; + } + const services = addSuffixToServiceNetworks(composeData.services, suffix); + const actualComposeData = { ...composeData, services }; - expect(actualComposeData.services?.redis?.networks).toHaveProperty( - `backend-${suffix}`, - ); + expect(actualComposeData.services?.redis?.networks).toHaveProperty( + `backend-${suffix}`, + ); }); const composeFileCombined = ` @@ -153,36 +153,36 @@ networks: `; test("Add suffix to networks in services (combined case)", () => { - const composeData = parse(composeFileCombined) as ComposeSpecification; + const composeData = parse(composeFileCombined) as ComposeSpecification; - const suffix = generateRandomHash(); + const suffix = generateRandomHash(); - if (!composeData?.services) { - return; - } - const services = addSuffixToServiceNetworks(composeData.services, suffix); - const actualComposeData = { ...composeData, services }; + if (!composeData?.services) { + return; + } + const services = addSuffixToServiceNetworks(composeData.services, suffix); + const actualComposeData = { ...composeData, services }; - // Caso 1: ListOfStrings - expect(actualComposeData.services?.web?.networks).toContain( - `frontend-${suffix}`, - ); - expect(actualComposeData.services?.web?.networks).toContain( - `backend-${suffix}`, - ); + // Caso 1: ListOfStrings + expect(actualComposeData.services?.web?.networks).toContain( + `frontend-${suffix}`, + ); + expect(actualComposeData.services?.web?.networks).toContain( + `backend-${suffix}`, + ); - // Caso 2: Objeto con aliases - const apiNetworks = actualComposeData.services?.api?.networks as { - [key: string]: unknown; - }; - expect(apiNetworks).toHaveProperty(`frontend-${suffix}`); - expect(apiNetworks[`frontend-${suffix}`]).toBeDefined(); - expect(apiNetworks).not.toHaveProperty("frontend"); + // Caso 2: Objeto con aliases + const apiNetworks = actualComposeData.services?.api?.networks as { + [key: string]: unknown; + }; + expect(apiNetworks).toHaveProperty(`frontend-${suffix}`); + expect(apiNetworks[`frontend-${suffix}`]).toBeDefined(); + expect(apiNetworks).not.toHaveProperty("frontend"); - // Caso 3: Objeto con redes simples - const redisNetworks = actualComposeData.services?.redis?.networks; - expect(redisNetworks).toHaveProperty(`backend-${suffix}`); - expect(redisNetworks).not.toHaveProperty("backend"); + // Caso 3: Objeto con redes simples + const redisNetworks = actualComposeData.services?.redis?.networks; + expect(redisNetworks).toHaveProperty(`backend-${suffix}`); + expect(redisNetworks).not.toHaveProperty("backend"); }); const composeFile7 = ` @@ -195,19 +195,19 @@ services: - dokploy-network `; -test("It shoudn't add suffix to dokploy-network in services", () => { - const composeData = parse(composeFile7) as ComposeSpecification; +test("It shouldn't add suffix to dokploy-network in services", () => { + const composeData = parse(composeFile7) as ComposeSpecification; - const suffix = generateRandomHash(); + const suffix = generateRandomHash(); - if (!composeData?.services) { - return; - } - const networks = addSuffixToServiceNetworks(composeData.services, suffix); - const service = networks.web; + if (!composeData?.services) { + return; + } + const networks = addSuffixToServiceNetworks(composeData.services, suffix); + const service = networks.web; - expect(service).toBeDefined(); - expect(service?.networks).toContain("dokploy-network"); + expect(service).toBeDefined(); + expect(service?.networks).toContain("dokploy-network"); }); const composeFile8 = ` @@ -241,35 +241,35 @@ services: dokploy-network: aliases: - apid - + `; -test("It shoudn't add suffix to dokploy-network in services multiples cases", () => { - const composeData = parse(composeFile8) as ComposeSpecification; +test("It shouldn't add suffix to dokploy-network in services multiples cases", () => { + const composeData = parse(composeFile8) as ComposeSpecification; - const suffix = generateRandomHash(); + const suffix = generateRandomHash(); - if (!composeData?.services) { - return; - } - const networks = addSuffixToServiceNetworks(composeData.services, suffix); - const service = networks.web; - const api = networks.api; - const redis = networks.redis; - const db = networks.db; + if (!composeData?.services) { + return; + } + const networks = addSuffixToServiceNetworks(composeData.services, suffix); + const service = networks.web; + const api = networks.api; + const redis = networks.redis; + const db = networks.db; - const dbNetworks = db?.networks as { - [key: string]: unknown; - }; + const dbNetworks = db?.networks as { + [key: string]: unknown; + }; - const apiNetworks = api?.networks as { - [key: string]: unknown; - }; + const apiNetworks = api?.networks as { + [key: string]: unknown; + }; - expect(service).toBeDefined(); - expect(service?.networks).toContain("dokploy-network"); + expect(service).toBeDefined(); + expect(service?.networks).toContain("dokploy-network"); - expect(redis?.networks).toHaveProperty("dokploy-network"); - expect(dbNetworks["dokploy-network"]).toBeDefined(); - expect(apiNetworks["dokploy-network"]).toBeDefined(); + expect(redis?.networks).toHaveProperty("dokploy-network"); + expect(dbNetworks["dokploy-network"]).toBeDefined(); + expect(apiNetworks["dokploy-network"]).toBeDefined(); }); diff --git a/apps/dokploy/__test__/compose/service/sevice-volumes-from.test.ts b/apps/dokploy/__test__/compose/service/service-volumes-from.test.ts similarity index 100% rename from apps/dokploy/__test__/compose/service/sevice-volumes-from.test.ts rename to apps/dokploy/__test__/compose/service/service-volumes-from.test.ts diff --git a/apps/dokploy/__test__/env/stack-environment.test.ts b/apps/dokploy/__test__/env/stack-environment.test.ts index 13f5adb53..cde7be9db 100644 --- a/apps/dokploy/__test__/env/stack-environment.test.ts +++ b/apps/dokploy/__test__/env/stack-environment.test.ts @@ -1,4 +1,4 @@ -import { getEnviromentVariablesObject } from "@dokploy/server/index"; +import { getEnvironmentVariablesObject } from "@dokploy/server/index"; import { describe, expect, it } from "vitest"; const projectEnv = ` @@ -15,29 +15,29 @@ DATABASE_NAME=dev_database SECRET_KEY=env-secret-123 `; -describe("getEnviromentVariablesObject with environment variables (Stack compose)", () => { - it("resolves environment variables correctly for Stack compose", () => { - const serviceEnv = ` +describe("getEnvironmentVariablesObject with environment variables (Stack compose)", () => { + it("resolves environment variables correctly for Stack compose", () => { + const serviceEnv = ` FOO=\${{environment.NODE_ENV}} BAR=\${{environment.API_URL}} BAZ=test `; - const result = getEnviromentVariablesObject( - serviceEnv, - projectEnv, - environmentEnv, - ); + const result = getEnvironmentVariablesObject( + serviceEnv, + projectEnv, + environmentEnv, + ); - expect(result).toEqual({ - FOO: "development", - BAR: "https://api.dev.example.com", - BAZ: "test", - }); - }); + expect(result).toEqual({ + FOO: "development", + BAR: "https://api.dev.example.com", + BAZ: "test", + }); + }); - it("resolves both project and environment variables for Stack compose", () => { - const serviceEnv = ` + it("resolves both project and environment variables for Stack compose", () => { + const serviceEnv = ` ENVIRONMENT=\${{project.ENVIRONMENT}} NODE_ENV=\${{environment.NODE_ENV}} API_URL=\${{environment.API_URL}} @@ -45,140 +45,140 @@ DATABASE_URL=\${{project.DATABASE_URL}} SERVICE_PORT=4000 `; - const result = getEnviromentVariablesObject( - serviceEnv, - projectEnv, - environmentEnv, - ); + const result = getEnvironmentVariablesObject( + serviceEnv, + projectEnv, + environmentEnv, + ); - expect(result).toEqual({ - ENVIRONMENT: "staging", - NODE_ENV: "development", - API_URL: "https://api.dev.example.com", - DATABASE_URL: "postgres://postgres:postgres@localhost:5432/project_db", - SERVICE_PORT: "4000", - }); - }); + expect(result).toEqual({ + ENVIRONMENT: "staging", + NODE_ENV: "development", + API_URL: "https://api.dev.example.com", + DATABASE_URL: "postgres://postgres:postgres@localhost:5432/project_db", + SERVICE_PORT: "4000", + }); + }); - it("handles multiple environment references in single value for Stack compose", () => { - const multiRefEnv = ` + it("handles multiple environment references in single value for Stack compose", () => { + const multiRefEnv = ` HOST=localhost PORT=5432 USERNAME=postgres PASSWORD=secret123 `; - const serviceEnv = ` + const serviceEnv = ` DATABASE_URL=postgresql://\${{environment.USERNAME}}:\${{environment.PASSWORD}}@\${{environment.HOST}}:\${{environment.PORT}}/mydb `; - const result = getEnviromentVariablesObject(serviceEnv, "", multiRefEnv); + const result = getEnvironmentVariablesObject(serviceEnv, "", multiRefEnv); - expect(result).toEqual({ - DATABASE_URL: "postgresql://postgres:secret123@localhost:5432/mydb", - }); - }); + expect(result).toEqual({ + DATABASE_URL: "postgresql://postgres:secret123@localhost:5432/mydb", + }); + }); - it("throws error for undefined environment variables in Stack compose", () => { - const serviceWithUndefined = ` + it("throws error for undefined environment variables in Stack compose", () => { + const serviceWithUndefined = ` UNDEFINED_VAR=\${{environment.UNDEFINED_VAR}} `; - expect(() => - getEnviromentVariablesObject(serviceWithUndefined, "", environmentEnv), - ).toThrow("Invalid environment variable: environment.UNDEFINED_VAR"); - }); + expect(() => + getEnvironmentVariablesObject(serviceWithUndefined, "", environmentEnv), + ).toThrow("Invalid environment variable: environment.UNDEFINED_VAR"); + }); - it("allows service variables to override environment variables in Stack compose", () => { - const serviceOverrideEnv = ` + it("allows service variables to override environment variables in Stack compose", () => { + const serviceOverrideEnv = ` NODE_ENV=production API_URL=\${{environment.API_URL}} `; - const result = getEnviromentVariablesObject( - serviceOverrideEnv, - "", - environmentEnv, - ); + const result = getEnvironmentVariablesObject( + serviceOverrideEnv, + "", + environmentEnv, + ); - expect(result).toEqual({ - NODE_ENV: "production", - API_URL: "https://api.dev.example.com", - }); - }); + expect(result).toEqual({ + NODE_ENV: "production", + API_URL: "https://api.dev.example.com", + }); + }); - it("resolves complex references with project, environment, and service variables for Stack compose", () => { - const complexServiceEnv = ` + it("resolves complex references with project, environment, and service variables for Stack compose", () => { + const complexServiceEnv = ` FULL_DATABASE_URL=\${{project.DATABASE_URL}}/\${{environment.DATABASE_NAME}} API_ENDPOINT=\${{environment.API_URL}}/\${{project.ENVIRONMENT}}/api SERVICE_NAME=my-service COMPLEX_VAR=\${{SERVICE_NAME}}-\${{environment.NODE_ENV}}-\${{project.ENVIRONMENT}} `; - const result = getEnviromentVariablesObject( - complexServiceEnv, - projectEnv, - environmentEnv, - ); + const result = getEnvironmentVariablesObject( + complexServiceEnv, + projectEnv, + environmentEnv, + ); - expect(result).toEqual({ - FULL_DATABASE_URL: - "postgres://postgres:postgres@localhost:5432/project_db/dev_database", - API_ENDPOINT: "https://api.dev.example.com/staging/api", - SERVICE_NAME: "my-service", - COMPLEX_VAR: "my-service-development-staging", - }); - }); + expect(result).toEqual({ + FULL_DATABASE_URL: + "postgres://postgres:postgres@localhost:5432/project_db/dev_database", + API_ENDPOINT: "https://api.dev.example.com/staging/api", + SERVICE_NAME: "my-service", + COMPLEX_VAR: "my-service-development-staging", + }); + }); - it("maintains precedence: service > environment > project in Stack compose", () => { - const conflictingProjectEnv = ` + it("maintains precedence: service > environment > project in Stack compose", () => { + const conflictingProjectEnv = ` NODE_ENV=production-project API_URL=https://project.api.com DATABASE_NAME=project_db `; - const conflictingEnvironmentEnv = ` + const conflictingEnvironmentEnv = ` NODE_ENV=development-environment API_URL=https://environment.api.com DATABASE_NAME=env_db `; - const serviceWithConflicts = ` + const serviceWithConflicts = ` NODE_ENV=service-override PROJECT_ENV=\${{project.NODE_ENV}} ENV_VAR=\${{environment.API_URL}} DB_NAME=\${{environment.DATABASE_NAME}} `; - const result = getEnviromentVariablesObject( - serviceWithConflicts, - conflictingProjectEnv, - conflictingEnvironmentEnv, - ); + const result = getEnvironmentVariablesObject( + serviceWithConflicts, + conflictingProjectEnv, + conflictingEnvironmentEnv, + ); - expect(result).toEqual({ - NODE_ENV: "service-override", - PROJECT_ENV: "production-project", - ENV_VAR: "https://environment.api.com", - DB_NAME: "env_db", - }); - }); + expect(result).toEqual({ + NODE_ENV: "service-override", + PROJECT_ENV: "production-project", + ENV_VAR: "https://environment.api.com", + DB_NAME: "env_db", + }); + }); - it("handles empty environment variables in Stack compose", () => { - const serviceWithEmpty = ` + it("handles empty environment variables in Stack compose", () => { + const serviceWithEmpty = ` SERVICE_VAR=test PROJECT_VAR=\${{project.ENVIRONMENT}} `; - const result = getEnviromentVariablesObject( - serviceWithEmpty, - projectEnv, - "", - ); + const result = getEnvironmentVariablesObject( + serviceWithEmpty, + projectEnv, + "", + ); - expect(result).toEqual({ - SERVICE_VAR: "test", - PROJECT_VAR: "staging", - }); - }); + expect(result).toEqual({ + SERVICE_VAR: "test", + PROJECT_VAR: "staging", + }); + }); }); diff --git a/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx b/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx index 172c042f1..603a6d6c8 100644 --- a/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx @@ -149,7 +149,7 @@ export const HandleRedirect = ({ const onDialogToggle = (open: boolean) => { setIsOpen(open); - // commented for the moment because not reseting the form if accidentally closed the dialog can be considered as a feature instead of a bug + // commented for the moment because not resetting the form if accidentally closed the dialog can be considered as a feature instead of a bug // setPresetSelected(""); // form.reset(); }; diff --git a/apps/dokploy/components/dashboard/application/environment/show-enviroment.tsx b/apps/dokploy/components/dashboard/application/environment/show-environment.tsx similarity index 100% rename from apps/dokploy/components/dashboard/application/environment/show-enviroment.tsx rename to apps/dokploy/components/dashboard/application/environment/show-environment.tsx diff --git a/apps/dokploy/components/dashboard/application/logs/show.tsx b/apps/dokploy/components/dashboard/application/logs/show.tsx index cbb6bce09..06b257766 100644 --- a/apps/dokploy/components/dashboard/application/logs/show.tsx +++ b/apps/dokploy/components/dashboard/application/logs/show.tsx @@ -91,7 +91,7 @@ export const ShowDockerLogs = ({ appName, serverId }: Props) => { }, [option, services, containers]); const isLoading = option === "native" ? containersLoading : servicesLoading; - const containersLenght = + const containersLength = option === "native" ? containers?.length : services?.length; return ( @@ -167,7 +167,7 @@ export const ShowDockerLogs = ({ appName, serverId }: Props) => { )} - Containers ({containersLenght}) + Containers ({containersLength}) diff --git a/apps/dokploy/components/dashboard/compose/logs/show-stack.tsx b/apps/dokploy/components/dashboard/compose/logs/show-stack.tsx index 159ab3485..4c3067b15 100644 --- a/apps/dokploy/components/dashboard/compose/logs/show-stack.tsx +++ b/apps/dokploy/components/dashboard/compose/logs/show-stack.tsx @@ -77,7 +77,7 @@ export const ShowDockerLogsStack = ({ appName, serverId }: Props) => { }, [option, services, containers]); const isLoading = option === "native" ? containersLoading : servicesLoading; - const containersLenght = + const containersLength = option === "native" ? containers?.length : services?.length; return ( @@ -152,7 +152,7 @@ export const ShowDockerLogsStack = ({ appName, serverId }: Props) => { )} - Containers ({containersLenght}) + Containers ({containersLength}) diff --git a/apps/dokploy/components/dashboard/database/backups/restore-backup.tsx b/apps/dokploy/components/dashboard/database/backups/restore-backup.tsx index 00647aea7..7b212acb9 100644 --- a/apps/dokploy/components/dashboard/database/backups/restore-backup.tsx +++ b/apps/dokploy/components/dashboard/database/backups/restore-backup.tsx @@ -225,7 +225,7 @@ export const RestoreBackup = ({ resolver: zodResolver(RestoreBackupSchema), }); - const destionationId = form.watch("destinationId"); + const destinationId = form.watch("destinationId"); const currentDatabaseType = form.watch("databaseType"); const metadata = form.watch("metadata"); @@ -240,12 +240,12 @@ export const RestoreBackup = ({ const { data: files = [], isPending } = api.backup.listBackupFiles.useQuery( { - destinationId: destionationId, + destinationId: destinationId, search: debouncedSearchTerm, serverId: serverId ?? "", }, { - enabled: isOpen && !!destionationId, + enabled: isOpen && !!destinationId, }, ); diff --git a/apps/dokploy/components/dashboard/docker/logs/terminal-line.tsx b/apps/dokploy/components/dashboard/docker/logs/terminal-line.tsx index 9d4f47c4a..bed5c6f5d 100644 --- a/apps/dokploy/components/dashboard/docker/logs/terminal-line.tsx +++ b/apps/dokploy/components/dashboard/docker/logs/terminal-line.tsx @@ -103,7 +103,7 @@ export function TerminalLine({ log, noTimestamp, searchTerm }: LogLineProps) { > {" "}
- {/* Icon to expand the log item maybe implement a colapsible later */} + {/* Icon to expand the log item maybe implement a collapsible later */} {/* */} {tooltip(color, rawTimestamp)} {!noTimestamp && ( diff --git a/apps/dokploy/components/dashboard/docker/show/colums.tsx b/apps/dokploy/components/dashboard/docker/show/columns.tsx similarity index 100% rename from apps/dokploy/components/dashboard/docker/show/colums.tsx rename to apps/dokploy/components/dashboard/docker/show/columns.tsx diff --git a/apps/dokploy/components/dashboard/docker/show/show-containers.tsx b/apps/dokploy/components/dashboard/docker/show/show-containers.tsx index 69b0a0da2..8a19566e8 100644 --- a/apps/dokploy/components/dashboard/docker/show/show-containers.tsx +++ b/apps/dokploy/components/dashboard/docker/show/show-containers.tsx @@ -35,7 +35,7 @@ import { TableRow, } from "@/components/ui/table"; import { api, type RouterOutputs } from "@/utils/api"; -import { columns } from "./colums"; +import { columns } from "./columns"; export type Container = NonNullable< RouterOutputs["docker"]["getContainers"] >[0]; diff --git a/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx b/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx index 0d4d3a44f..570955fc8 100644 --- a/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx @@ -161,7 +161,7 @@ export const SetupServer = ({ serverId, asButton = false }: Props) => {
  • 1. Add the public SSH Key when you create a server in your - preffered provider (Hostinger, Digital Ocean, Hetzner, + preferred provider (Hostinger, Digital Ocean, Hetzner, etc){" "}
  • 2. Add The SSH Key to Server Manually
  • diff --git a/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx b/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx index 859098394..7342aafb4 100644 --- a/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx @@ -48,7 +48,7 @@ import { ShowMonitoringModal } from "./show-monitoring-modal"; import { ShowSchedulesModal } from "./show-schedules-modal"; import { ShowSwarmOverviewModal } from "./show-swarm-overview-modal"; import { ShowTraefikFileSystemModal } from "./show-traefik-file-system-modal"; -import { WelcomeSuscription } from "./welcome-stripe/welcome-suscription"; +import { Welcomesubscription } from "./welcome-stripe/welcome-subscription"; export const ShowServers = () => { const router = useRouter(); @@ -63,7 +63,7 @@ export const ShowServers = () => { return (
    - {query?.success && isCloud && } + {query?.success && isCloud && }
    diff --git a/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/welcome-suscription.tsx b/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/welcome-subscription.tsx similarity index 99% rename from apps/dokploy/components/dashboard/settings/servers/welcome-stripe/welcome-suscription.tsx rename to apps/dokploy/components/dashboard/settings/servers/welcome-stripe/welcome-subscription.tsx index 004f79f74..295b53516 100644 --- a/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/welcome-suscription.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/welcome-subscription.tsx @@ -51,7 +51,7 @@ export const { useStepper, steps, Scoped } = defineStepper( { id: "complete", title: "Complete", description: "Checkout complete" }, ); -export const WelcomeSuscription = () => { +export const Welcomesubscription = () => { const [showConfetti, setShowConfetti] = useState(false); const stepper = useStepper(); const [isOpen, setIsOpen] = useState(true); diff --git a/apps/dokploy/components/ui/file-tree.tsx b/apps/dokploy/components/ui/file-tree.tsx index e346bf4a6..c1d5dc335 100644 --- a/apps/dokploy/components/ui/file-tree.tsx +++ b/apps/dokploy/components/ui/file-tree.tsx @@ -19,7 +19,7 @@ interface TreeDataItem { type TreeProps = React.HTMLAttributes & { data: TreeDataItem[] | TreeDataItem; - initialSlelectedItemId?: string; + initialSelectedItemId?: string; onSelectChange?: (item: TreeDataItem | undefined) => void; expandAll?: boolean; folderIcon?: LucideIcon; @@ -30,7 +30,7 @@ const Tree = React.forwardRef( ( { data, - initialSlelectedItemId, + initialSelectedItemId, onSelectChange, expandAll, folderIcon, @@ -42,7 +42,7 @@ const Tree = React.forwardRef( ) => { const [selectedItemId, setSelectedItemId] = React.useState< string | undefined - >(initialSlelectedItemId); + >(initialSelectedItemId); const handleSelectChange = React.useCallback( (item: TreeDataItem | undefined) => { @@ -55,7 +55,7 @@ const Tree = React.forwardRef( ); const expandedItemIds = React.useMemo(() => { - if (!initialSlelectedItemId) { + if (!initialSelectedItemId) { return [] as string[]; } @@ -81,9 +81,9 @@ const Tree = React.forwardRef( } } - walkTreeItems(data, initialSlelectedItemId); + walkTreeItems(data, initialSelectedItemId); return ids; - }, [data, initialSlelectedItemId]); + }, [data, initialSelectedItemId]); const { ref: refRoot } = useResizeObserver(); diff --git a/apps/dokploy/pages/api/deploy/[refreshToken].ts b/apps/dokploy/pages/api/deploy/[refreshToken].ts index 14b45f3d7..1c57731a7 100644 --- a/apps/dokploy/pages/api/deploy/[refreshToken].ts +++ b/apps/dokploy/pages/api/deploy/[refreshToken].ts @@ -196,7 +196,7 @@ export default async function handler( return; } - const commitedPaths = await extractCommitedPaths( + const committedPaths = await extractCommittedPaths( req.body, application.bitbucket, application.bitbucketRepositorySlug || @@ -206,7 +206,7 @@ export default async function handler( const shouldDeployPaths = shouldDeploy( application.watchPaths, - commitedPaths, + committedPaths, ); if (!shouldDeployPaths) { @@ -538,7 +538,7 @@ export const getProviderByHeader = (headers: any) => { return null; }; -export const extractCommitedPaths = async ( +export const extractCommittedPaths = async ( body: any, bitbucket: Bitbucket | null, repository: string, @@ -548,7 +548,7 @@ export const extractCommitedPaths = async ( const commitHashes = changes .map((change: any) => change.new?.target?.hash) .filter(Boolean); - const commitedPaths: string[] = []; + const committedPaths: string[] = []; const username = bitbucket?.bitbucketWorkspaceName || bitbucket?.bitbucketUsername || ""; for (const commit of commitHashes) { @@ -559,7 +559,7 @@ export const extractCommitedPaths = async ( }); const data = await response.json(); for (const value of data.values) { - if (value?.new?.path) commitedPaths.push(value.new.path); + if (value?.new?.path) committedPaths.push(value.new.path); } } catch (error) { console.error( @@ -571,5 +571,5 @@ export const extractCommitedPaths = async ( } } - return commitedPaths; + return committedPaths; }; diff --git a/apps/dokploy/pages/api/deploy/compose/[refreshToken].ts b/apps/dokploy/pages/api/deploy/compose/[refreshToken].ts index da3082bb7..c998e83b9 100644 --- a/apps/dokploy/pages/api/deploy/compose/[refreshToken].ts +++ b/apps/dokploy/pages/api/deploy/compose/[refreshToken].ts @@ -8,7 +8,7 @@ import { myQueue } from "@/server/queues/queueSetup"; import { deploy } from "@/server/utils/deploy"; import { extractBranchName, - extractCommitedPaths, + extractCommittedPaths, extractCommitMessage, extractHash, getProviderByHeader, @@ -97,7 +97,7 @@ export default async function handler( return; } - const commitedPaths = await extractCommitedPaths( + const committedPaths = await extractCommittedPaths( req.body, composeResult.bitbucket, composeResult.bitbucketRepositorySlug || @@ -107,7 +107,7 @@ export default async function handler( const shouldDeployPaths = shouldDeploy( composeResult.watchPaths, - commitedPaths, + committedPaths, ); if (!shouldDeployPaths) { diff --git a/apps/dokploy/pages/api/stripe/webhook.ts b/apps/dokploy/pages/api/stripe/webhook.ts index 60468bd2c..deaa5572c 100644 --- a/apps/dokploy/pages/api/stripe/webhook.ts +++ b/apps/dokploy/pages/api/stripe/webhook.ts @@ -174,27 +174,27 @@ export default async function handler( case "invoice.payment_succeeded": { const newInvoice = event.data.object as Stripe.Invoice; - const suscription = await stripe.subscriptions.retrieve( + const subscription = await stripe.subscriptions.retrieve( newInvoice.subscription as string, ); - if (suscription.status !== "active") { + if (subscription.status !== "active") { console.log( - `Skipping invoice.payment_succeeded for subscription ${suscription.id} with status ${suscription.status}`, + `Skipping invoice.payment_succeeded for subscription ${subscription.id} with status ${subscription.status}`, ); break; } const serversQuantity = getSubscriptionServersQuantity( - suscription?.items?.data ?? [], + subscription?.items?.data ?? [], ); await db .update(user) .set({ serversQuantity }) - .where(eq(user.stripeCustomerId, suscription.customer as string)); + .where(eq(user.stripeCustomerId, subscription.customer as string)); const admin = await findUserByStripeCustomerId( - suscription.customer as string, + subscription.customer as string, ); if (!admin) { diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx index 078bf5b6b..781dd7795 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx @@ -16,7 +16,7 @@ import { ShowImport } from "@/components/dashboard/application/advanced/import/s import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes"; import { ShowDeployments } from "@/components/dashboard/application/deployments/show-deployments"; import { ShowDomains } from "@/components/dashboard/application/domains/show-domains"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowPatches } from "@/components/dashboard/application/patches/show-patches"; import { ShowSchedules } from "@/components/dashboard/application/schedules/show-schedules"; import { ShowVolumeBackups } from "@/components/dashboard/application/volume-backups/show-volume-backups"; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/libsql/[libsqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/libsql/[libsqlId].tsx index 6abb53c2b..c9563ebe6 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/libsql/[libsqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/libsql/[libsqlId].tsx @@ -10,7 +10,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useState } from "react"; import superjson from "superjson"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowDockerLogs } from "@/components/dashboard/application/logs/show"; import { DeleteService } from "@/components/dashboard/compose/delete-service"; import { ShowBackups } from "@/components/dashboard/database/backups/show-backups"; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx index 3e3a7d7de..b54804279 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx @@ -10,7 +10,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useState } from "react"; import superjson from "superjson"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowDockerLogs } from "@/components/dashboard/application/logs/show"; import { DeleteService } from "@/components/dashboard/compose/delete-service"; import { ShowBackups } from "@/components/dashboard/database/backups/show-backups"; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx index ea6483499..402718625 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx @@ -10,7 +10,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useState } from "react"; import superjson from "superjson"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowDockerLogs } from "@/components/dashboard/application/logs/show"; import { DeleteService } from "@/components/dashboard/compose/delete-service"; import { ShowBackups } from "@/components/dashboard/database/backups/show-backups"; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx index ff45c0694..55e1ee6e0 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx @@ -10,7 +10,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useState } from "react"; import superjson from "superjson"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowDockerLogs } from "@/components/dashboard/application/logs/show"; import { DeleteService } from "@/components/dashboard/compose/delete-service"; import { ShowBackups } from "@/components/dashboard/database/backups/show-backups"; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx index 15e91a0bd..f73ce35cb 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx @@ -10,7 +10,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useState } from "react"; import superjson from "superjson"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowDockerLogs } from "@/components/dashboard/application/logs/show"; import { DeleteService } from "@/components/dashboard/compose/delete-service"; import { ShowBackups } from "@/components/dashboard/database/backups/show-backups"; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx index 05a9e0c91..8847ed891 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx @@ -10,7 +10,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import { type ReactElement, useState } from "react"; import superjson from "superjson"; -import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment"; +import { ShowEnvironment } from "@/components/dashboard/application/environment/show-environment"; import { ShowDockerLogs } from "@/components/dashboard/application/logs/show"; import { DeleteService } from "@/components/dashboard/compose/delete-service"; import { ContainerFreeMonitoring } from "@/components/dashboard/monitoring/free/container/show-free-container-monitoring"; diff --git a/apps/dokploy/server/api/routers/destination.ts b/apps/dokploy/server/api/routers/destination.ts index 9f528c16c..cf7395a3f 100644 --- a/apps/dokploy/server/api/routers/destination.ts +++ b/apps/dokploy/server/api/routers/destination.ts @@ -1,5 +1,5 @@ import { - createDestintation, + createDestination, execAsync, execAsyncRemote, findDestinationById, @@ -25,7 +25,7 @@ export const destinationRouter = createTRPCRouter({ .input(apiCreateDestination) .mutation(async ({ input, ctx }) => { try { - const result = await createDestintation( + const result = await createDestination( input, ctx.session.activeOrganizationId, ); diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 22e8872bd..e6fd0ba59 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -121,7 +121,7 @@ export * from "./utils/providers/raw"; export * from "./utils/schedules/index"; export * from "./utils/schedules/utils"; export * from "./utils/servers/remote-docker"; -export * from "./utils/startup/cancell-deployments"; +export * from "./utils/startup/cancel-deployments"; export * from "./utils/tracking/hubspot"; export * from "./utils/traefik/application"; export * from "./utils/traefik/domain"; diff --git a/packages/server/src/services/deployment.ts b/packages/server/src/services/deployment.ts index a9f059465..7b6f0c730 100644 --- a/packages/server/src/services/deployment.ts +++ b/packages/server/src/services/deployment.ts @@ -177,7 +177,7 @@ export const createDeployment = async ( status: "error", logPath: "", description: deployment.description || "", - errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, + errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) @@ -257,7 +257,7 @@ export const createDeploymentPreview = async ( status: "error", logPath: "", description: deployment.description || "", - errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, + errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) @@ -334,7 +334,7 @@ echo "Initializing deployment\n" >> ${logFilePath}; status: "error", logPath: "", description: deployment.description || "", - errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, + errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) @@ -418,7 +418,7 @@ echo "Initializing backup\n" >> ${logFilePath}; status: "error", logPath: "", description: deployment.description || "", - errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, + errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) @@ -493,7 +493,7 @@ export const createDeploymentSchedule = async ( status: "error", logPath: "", description: deployment.description || "", - errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, + errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) @@ -578,7 +578,7 @@ export const createDeploymentVolumeBackup = async ( status: "error", logPath: "", description: deployment.description || "", - errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`, + errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) diff --git a/packages/server/src/services/destination.ts b/packages/server/src/services/destination.ts index fa48d0d15..9cbc9afa3 100644 --- a/packages/server/src/services/destination.ts +++ b/packages/server/src/services/destination.ts @@ -9,7 +9,7 @@ import type { z } from "zod"; export type Destination = typeof destinations.$inferSelect; -export const createDestintation = async ( +export const createDestination = async ( input: z.infer, organizationId: string, ) => { diff --git a/packages/server/src/services/settings.ts b/packages/server/src/services/settings.ts index 07aaf690c..ecfb7f6de 100644 --- a/packages/server/src/services/settings.ts +++ b/packages/server/src/services/settings.ts @@ -383,12 +383,12 @@ export const readPorts = async ( const seenPorts = new Set(); for (const key in parsedResult) { if (Object.hasOwn(parsedResult, key)) { - const containerPortMapppings = parsedResult[key]; + const containerPortMappings = parsedResult[key]; const protocol = key.split("/")[1]; const targetPort = Number.parseInt(key.split("/")[0] ?? "0", 10); // Take only the first mapping to avoid duplicates (IPv4 and IPv6) - const firstMapping = containerPortMapppings[0]; + const firstMapping = containerPortMappings[0]; if (firstMapping) { const publishedPort = Number.parseInt(firstMapping.HostPort, 10); const portKey = `${targetPort}-${publishedPort}-${protocol}`; diff --git a/packages/server/src/services/user.ts b/packages/server/src/services/user.ts index 83287a3be..5e66c6f2c 100644 --- a/packages/server/src/services/user.ts +++ b/packages/server/src/services/user.ts @@ -7,452 +7,452 @@ import { auth } from "../lib/auth"; export type User = typeof user.$inferSelect; export const addNewProject = async ( - userId: string, - projectId: string, - organizationId: string, + userId: string, + projectId: string, + organizationId: string, ) => { - const userR = await findMemberById(userId, organizationId); + const userR = await findMemberById(userId, organizationId); - await db - .update(member) - .set({ - accessedProjects: [...userR.accessedProjects, projectId], - }) - .where( - and(eq(member.id, userR.id), eq(member.organizationId, organizationId)), - ); + await db + .update(member) + .set({ + accessedProjects: [...userR.accessedProjects, projectId], + }) + .where( + and(eq(member.id, userR.id), eq(member.organizationId, organizationId)), + ); }; export const addNewEnvironment = async ( - userId: string, - environmentId: string, - organizationId: string, + userId: string, + environmentId: string, + organizationId: string, ) => { - const userR = await findMemberById(userId, organizationId); + const userR = await findMemberById(userId, organizationId); - await db - .update(member) - .set({ - accessedEnvironments: [...userR.accessedEnvironments, environmentId], - }) - .where( - and(eq(member.id, userR.id), eq(member.organizationId, organizationId)), - ); + await db + .update(member) + .set({ + accessedEnvironments: [...userR.accessedEnvironments, environmentId], + }) + .where( + and(eq(member.id, userR.id), eq(member.organizationId, organizationId)), + ); }; export const addNewService = async ( - userId: string, - serviceId: string, - organizationId: string, + userId: string, + serviceId: string, + organizationId: string, ) => { - const userR = await findMemberById(userId, organizationId); - await db - .update(member) - .set({ - accessedServices: [...userR.accessedServices, serviceId], - }) - .where( - and(eq(member.id, userR.id), eq(member.organizationId, organizationId)), - ); + const userR = await findMemberById(userId, organizationId); + await db + .update(member) + .set({ + accessedServices: [...userR.accessedServices, serviceId], + }) + .where( + and(eq(member.id, userR.id), eq(member.organizationId, organizationId)), + ); }; export const canPerformCreationService = async ( - userId: string, - projectId: string, - organizationId: string, + userId: string, + projectId: string, + organizationId: string, ) => { - const { accessedProjects, canCreateServices } = await findMemberById( - userId, - organizationId, - ); - const haveAccessToProject = accessedProjects.includes(projectId); + const { accessedProjects, canCreateServices } = await findMemberById( + userId, + organizationId, + ); + const haveAccessToProject = accessedProjects.includes(projectId); - if (canCreateServices && haveAccessToProject) { - return true; - } + if (canCreateServices && haveAccessToProject) { + return true; + } - return false; + return false; }; export const canPerformAccessService = async ( - userId: string, - serviceId: string, - organizationId: string, + userId: string, + serviceId: string, + organizationId: string, ) => { - const { accessedServices } = await findMemberById(userId, organizationId); - const haveAccessToService = accessedServices.includes(serviceId); + const { accessedServices } = await findMemberById(userId, organizationId); + const haveAccessToService = accessedServices.includes(serviceId); - if (haveAccessToService) { - return true; - } + if (haveAccessToService) { + return true; + } - return false; + return false; }; -export const canPeformDeleteService = async ( - userId: string, - serviceId: string, - organizationId: string, +export const canPerformDeleteService = async ( + userId: string, + serviceId: string, + organizationId: string, ) => { - const { accessedServices, canDeleteServices } = await findMemberById( - userId, - organizationId, - ); - const haveAccessToService = accessedServices.includes(serviceId); + const { accessedServices, canDeleteServices } = await findMemberById( + userId, + organizationId, + ); + const haveAccessToService = accessedServices.includes(serviceId); - if (canDeleteServices && haveAccessToService) { - return true; - } + if (canDeleteServices && haveAccessToService) { + return true; + } - return false; + return false; }; export const canPerformCreationProject = async ( - userId: string, - organizationId: string, + userId: string, + organizationId: string, ) => { - const { canCreateProjects } = await findMemberById(userId, organizationId); + const { canCreateProjects } = await findMemberById(userId, organizationId); - if (canCreateProjects) { - return true; - } + if (canCreateProjects) { + return true; + } - return false; + return false; }; export const canPerformDeleteProject = async ( - userId: string, - organizationId: string, + userId: string, + organizationId: string, ) => { - const { canDeleteProjects } = await findMemberById(userId, organizationId); + const { canDeleteProjects } = await findMemberById(userId, organizationId); - if (canDeleteProjects) { - return true; - } + if (canDeleteProjects) { + return true; + } - return false; + return false; }; export const canPerformAccessProject = async ( - userId: string, - projectId: string, - organizationId: string, + userId: string, + projectId: string, + organizationId: string, ) => { - const { accessedProjects } = await findMemberById(userId, organizationId); + const { accessedProjects } = await findMemberById(userId, organizationId); - const haveAccessToProject = accessedProjects.includes(projectId); + const haveAccessToProject = accessedProjects.includes(projectId); - if (haveAccessToProject) { - return true; - } - return false; + if (haveAccessToProject) { + return true; + } + return false; }; export const canPerformAccessEnvironment = async ( - userId: string, - environmentId: string, - organizationId: string, + userId: string, + environmentId: string, + organizationId: string, ) => { - const { accessedEnvironments } = await findMemberById(userId, organizationId); - const haveAccessToEnvironment = accessedEnvironments.includes(environmentId); + const { accessedEnvironments } = await findMemberById(userId, organizationId); + const haveAccessToEnvironment = accessedEnvironments.includes(environmentId); - if (haveAccessToEnvironment) { - return true; - } + if (haveAccessToEnvironment) { + return true; + } - return false; + return false; }; export const canPerformDeleteEnvironment = async ( - userId: string, - projectId: string, - organizationId: string, + userId: string, + projectId: string, + organizationId: string, ) => { - const { accessedProjects, canDeleteEnvironments } = await findMemberById( - userId, - organizationId, - ); - const haveAccessToProject = accessedProjects.includes(projectId); + const { accessedProjects, canDeleteEnvironments } = await findMemberById( + userId, + organizationId, + ); + const haveAccessToProject = accessedProjects.includes(projectId); - if (canDeleteEnvironments && haveAccessToProject) { - return true; - } + if (canDeleteEnvironments && haveAccessToProject) { + return true; + } - return false; + return false; }; export const canAccessToTraefikFiles = async ( - userId: string, - organizationId: string, + userId: string, + organizationId: string, ) => { - const { canAccessToTraefikFiles } = await findMemberById( - userId, - organizationId, - ); - return canAccessToTraefikFiles; + const { canAccessToTraefikFiles } = await findMemberById( + userId, + organizationId, + ); + return canAccessToTraefikFiles; }; export const checkServiceAccess = async ( - userId: string, - serviceId: string, - organizationId: string, - action = "access" as "access" | "create" | "delete", + userId: string, + serviceId: string, + organizationId: string, + action = "access" as "access" | "create" | "delete", ) => { - let hasPermission = false; - switch (action) { - case "create": - hasPermission = await canPerformCreationService( - userId, - serviceId, - organizationId, - ); - break; - case "access": - hasPermission = await canPerformAccessService( - userId, - serviceId, - organizationId, - ); - break; - case "delete": - hasPermission = await canPeformDeleteService( - userId, - serviceId, - organizationId, - ); - break; - default: - hasPermission = false; - } - if (!hasPermission) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "Permission denied", - }); - } + let hasPermission = false; + switch (action) { + case "create": + hasPermission = await canPerformCreationService( + userId, + serviceId, + organizationId, + ); + break; + case "access": + hasPermission = await canPerformAccessService( + userId, + serviceId, + organizationId, + ); + break; + case "delete": + hasPermission = await canPerformDeleteService( + userId, + serviceId, + organizationId, + ); + break; + default: + hasPermission = false; + } + if (!hasPermission) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "Permission denied", + }); + } }; export const checkEnvironmentAccess = async ( - userId: string, - environmentId: string, - organizationId: string, - action = "access" as const, + userId: string, + environmentId: string, + organizationId: string, + action = "access" as const, ) => { - let hasPermission = false; - switch (action) { - case "access": - hasPermission = await canPerformAccessEnvironment( - userId, - environmentId, - organizationId, - ); - break; - default: - hasPermission = false; - } - if (!hasPermission) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "Permission denied", - }); - } + let hasPermission = false; + switch (action) { + case "access": + hasPermission = await canPerformAccessEnvironment( + userId, + environmentId, + organizationId, + ); + break; + default: + hasPermission = false; + } + if (!hasPermission) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "Permission denied", + }); + } }; export const checkEnvironmentDeletionPermission = async ( - userId: string, - projectId: string, - organizationId: string, + userId: string, + projectId: string, + organizationId: string, ) => { - const member = await findMemberById(userId, organizationId); + const member = await findMemberById(userId, organizationId); - if (!member) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "User not found in organization", - }); - } + if (!member) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "User not found in organization", + }); + } - if (member.role === "owner" || member.role === "admin") { - return true; - } + if (member.role === "owner" || member.role === "admin") { + return true; + } - if (!member.canDeleteEnvironments) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "You don't have permission to delete environments", - }); - } + if (!member.canDeleteEnvironments) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You don't have permission to delete environments", + }); + } - const hasProjectAccess = member.accessedProjects.includes(projectId); - if (!hasProjectAccess) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "You don't have access to this project", - }); - } + const hasProjectAccess = member.accessedProjects.includes(projectId); + if (!hasProjectAccess) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You don't have access to this project", + }); + } - return true; + return true; }; export const checkProjectAccess = async ( - authId: string, - action: "create" | "delete" | "access", - organizationId: string, - projectId?: string, + authId: string, + action: "create" | "delete" | "access", + organizationId: string, + projectId?: string, ) => { - let hasPermission = false; - switch (action) { - case "access": - hasPermission = await canPerformAccessProject( - authId, - projectId as string, - organizationId, - ); - break; - case "create": - hasPermission = await canPerformCreationProject(authId, organizationId); - break; - case "delete": - hasPermission = await canPerformDeleteProject(authId, organizationId); - break; - default: - hasPermission = false; - } - if (!hasPermission) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "Permission denied", - }); - } + let hasPermission = false; + switch (action) { + case "access": + hasPermission = await canPerformAccessProject( + authId, + projectId as string, + organizationId, + ); + break; + case "create": + hasPermission = await canPerformCreationProject(authId, organizationId); + break; + case "delete": + hasPermission = await canPerformDeleteProject(authId, organizationId); + break; + default: + hasPermission = false; + } + if (!hasPermission) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "Permission denied", + }); + } }; export const checkEnvironmentCreationPermission = async ( - userId: string, - projectId: string, - organizationId: string, + userId: string, + projectId: string, + organizationId: string, ) => { - // Get user's member record - const member = await findMemberById(userId, organizationId); + // Get user's member record + const member = await findMemberById(userId, organizationId); - if (!member) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "User not found in organization", - }); - } + if (!member) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "User not found in organization", + }); + } - // Owners and admins can always create environments - if (member.role === "owner" || member.role === "admin") { - return true; - } + // Owners and admins can always create environments + if (member.role === "owner" || member.role === "admin") { + return true; + } - // Check if user has canCreateEnvironments permission - if (!member.canCreateEnvironments) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "You don't have permission to create environments", - }); - } + // Check if user has canCreateEnvironments permission + if (!member.canCreateEnvironments) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You don't have permission to create environments", + }); + } - // Check if user has access to the project - const hasProjectAccess = member.accessedProjects.includes(projectId); - if (!hasProjectAccess) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "You don't have access to this project", - }); - } + // Check if user has access to the project + const hasProjectAccess = member.accessedProjects.includes(projectId); + if (!hasProjectAccess) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You don't have access to this project", + }); + } - return true; + return true; }; export const findMemberById = async ( - userId: string, - organizationId: string, + userId: string, + organizationId: string, ) => { - const result = await db.query.member.findFirst({ - where: and( - eq(member.userId, userId), - eq(member.organizationId, organizationId), - ), - with: { - user: true, - }, - }); + const result = await db.query.member.findFirst({ + where: and( + eq(member.userId, userId), + eq(member.organizationId, organizationId), + ), + with: { + user: true, + }, + }); - if (!result) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "Permission denied", - }); - } - return result; + if (!result) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "Permission denied", + }); + } + return result; }; export const updateUser = async (userId: string, userData: Partial) => { - // Validate email if it's being updated - if (userData.email !== undefined) { - if (!userData.email || userData.email.trim() === "") { - throw new Error("Email is required and cannot be empty"); - } + // Validate email if it's being updated + if (userData.email !== undefined) { + if (!userData.email || userData.email.trim() === "") { + throw new Error("Email is required and cannot be empty"); + } - // Basic email format validation - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - if (!emailRegex.test(userData.email)) { - throw new Error("Please enter a valid email address"); - } - } + // Basic email format validation + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(userData.email)) { + throw new Error("Please enter a valid email address"); + } + } - const userResult = await db - .update(user) - .set({ - ...userData, - }) - .where(eq(user.id, userId)) - .returning() - .then((res) => res[0]); + const userResult = await db + .update(user) + .set({ + ...userData, + }) + .where(eq(user.id, userId)) + .returning() + .then((res) => res[0]); - return userResult; + return userResult; }; export const createApiKey = async ( - userId: string, - input: { - name: string; - prefix?: string; - expiresIn?: number; - metadata: { - organizationId: string; - }; - rateLimitEnabled?: boolean; - rateLimitTimeWindow?: number; - rateLimitMax?: number; - remaining?: number; - refillAmount?: number; - refillInterval?: number; - }, + userId: string, + input: { + name: string; + prefix?: string; + expiresIn?: number; + metadata: { + organizationId: string; + }; + rateLimitEnabled?: boolean; + rateLimitTimeWindow?: number; + rateLimitMax?: number; + remaining?: number; + refillAmount?: number; + refillInterval?: number; + }, ) => { - const result = await auth.createApiKey({ - body: { - name: input.name, - expiresIn: input.expiresIn, - prefix: input.prefix, - rateLimitEnabled: input.rateLimitEnabled, - rateLimitTimeWindow: input.rateLimitTimeWindow, - rateLimitMax: input.rateLimitMax, - remaining: input.remaining, - refillAmount: input.refillAmount, - refillInterval: input.refillInterval, - userId, - }, - }); + const result = await auth.createApiKey({ + body: { + name: input.name, + expiresIn: input.expiresIn, + prefix: input.prefix, + rateLimitEnabled: input.rateLimitEnabled, + rateLimitTimeWindow: input.rateLimitTimeWindow, + rateLimitMax: input.rateLimitMax, + remaining: input.remaining, + refillAmount: input.refillAmount, + refillInterval: input.refillInterval, + userId, + }, + }); - if (input.metadata) { - await db - .update(apikey) - .set({ metadata: JSON.stringify(input.metadata) }) - .where(eq(apikey.id, result.id)); - } + if (input.metadata) { + await db + .update(apikey) + .set({ metadata: JSON.stringify(input.metadata) }) + .where(eq(apikey.id, result.id)); + } - return result; + return result; }; diff --git a/packages/server/src/setup/setup.ts b/packages/server/src/setup/setup.ts index 4c01bf6cb..5171063d6 100644 --- a/packages/server/src/setup/setup.ts +++ b/packages/server/src/setup/setup.ts @@ -3,13 +3,13 @@ import { docker } from "../constants"; export const initializeSwarm = async () => { const swarmInitialized = await dockerSwarmInitialized(); if (swarmInitialized) { - console.log("Swarm is already initilized"); + console.log("Swarm is already initialized"); } else { await docker.swarmInit({ AdvertiseAddr: "127.0.0.1", ListenAddr: "0.0.0.0", }); - console.log("Swarm was initilized"); + console.log("Swarm was initialized"); } }; @@ -26,14 +26,14 @@ export const dockerSwarmInitialized = async () => { export const initializeNetwork = async () => { const networkInitialized = await dockerNetworkInitialized(); if (networkInitialized) { - console.log("Network is already initilized"); + console.log("Network is already initialized"); } else { docker.createNetwork({ Attachable: true, Name: "dokploy-network", Driver: "overlay", }); - console.log("Network was initilized"); + console.log("Network was initialized"); } }; diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index ca2b8a6b5..32aecbd4c 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -5,26 +5,26 @@ import boxen from "boxen"; import { quote } from "shell-quote"; import { writeDomainsToCompose } from "../docker/domain"; import { - encodeBase64, - getEnviromentVariablesObject, - prepareEnvironmentVariables, + encodeBase64, + getEnvironmentVariablesObject, + prepareEnvironmentVariables, } from "../docker/utils"; export type ComposeNested = InferResultType< - "compose", - { environment: { with: { project: true } }; mounts: true; domains: true } + "compose", + { environment: { with: { project: true } }; mounts: true; domains: true } >; export const getBuildComposeCommand = async (compose: ComposeNested) => { - const { COMPOSE_PATH } = paths(!!compose.serverId); - const { sourceType, appName, mounts, composeType, domains } = compose; - const command = createCommand(compose); - const envCommand = getCreateEnvFileCommand(compose); - const projectPath = join(COMPOSE_PATH, compose.appName, "code"); - const exportEnvCommand = getExportEnvCommand(compose); + const { COMPOSE_PATH } = paths(!!compose.serverId); + const { sourceType, appName, mounts, composeType, domains } = compose; + const command = createCommand(compose); + const envCommand = getCreateEnvFileCommand(compose); + const projectPath = join(COMPOSE_PATH, compose.appName, "code"); + const exportEnvCommand = getExportEnvCommand(compose); - const newCompose = await writeDomainsToCompose(compose, domains); - const logContent = ` + const newCompose = await writeDomainsToCompose(compose, domains); + const logContent = ` App Name: ${appName} Build Compose 🐳 Detected: ${mounts.length} mounts 📂 @@ -32,31 +32,31 @@ 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", - }); + const logBox = boxen(logContent, { + padding: { + left: 1, + right: 1, + bottom: 1, + }, + width: 80, + borderStyle: "double", + }); - const bashCommand = ` + const bashCommand = ` set -e { echo "${logBox}"; - + ${newCompose} - + ${envCommand} - + cd "${projectPath}"; ${compose.isolatedDeployment ? `docker network inspect ${compose.appName} >/dev/null 2>&1 || docker network create ${compose.composeType === "stack" ? "--driver overlay" : ""} --attachable ${compose.appName}` : ""} env -i PATH="$PATH" ${exportEnvCommand} docker ${command.split(" ").join(" ")} 2>&1 || { echo "Error: ❌ Docker command failed"; exit 1; } ${compose.isolatedDeployment ? `docker network connect ${compose.appName} $(docker ps --filter "name=dokploy-traefik" -q) >/dev/null 2>&1` : ""} - + echo "Docker Compose Deployed: ✅"; } || { echo "Error: ❌ Script execution failed"; @@ -64,81 +64,81 @@ Compose Type: ${composeType} ✅`; } `; - return bashCommand; + return bashCommand; }; const sanitizeCommand = (command: string) => { - const sanitizedCommand = command.trim(); + const sanitizedCommand = command.trim(); - const parts = sanitizedCommand.split(/\s+/); + const parts = sanitizedCommand.split(/\s+/); - const restCommand = parts.map((arg) => arg.replace(/^"(.*)"$/, "$1")); + const restCommand = parts.map((arg) => arg.replace(/^"(.*)"$/, "$1")); - return restCommand.join(" "); + return restCommand.join(" "); }; export const createCommand = (compose: ComposeNested) => { - const { composeType, appName, sourceType } = compose; - if (compose.command) { - return `${sanitizeCommand(compose.command)}`; - } + const { composeType, appName, sourceType } = compose; + if (compose.command) { + return `${sanitizeCommand(compose.command)}`; + } - const path = - sourceType === "raw" ? "docker-compose.yml" : compose.composePath; - let command = ""; + const path = + sourceType === "raw" ? "docker-compose.yml" : compose.composePath; + let command = ""; - if (composeType === "docker-compose") { - command = `compose -p ${appName} -f ${path} up -d --build --remove-orphans`; - } else if (composeType === "stack") { - command = `stack deploy -c ${path} ${appName} --prune --with-registry-auth`; - } + if (composeType === "docker-compose") { + command = `compose -p ${appName} -f ${path} up -d --build --remove-orphans`; + } else if (composeType === "stack") { + command = `stack deploy -c ${path} ${appName} --prune --with-registry-auth`; + } - return command; + return command; }; export const getCreateEnvFileCommand = (compose: ComposeNested) => { - const { COMPOSE_PATH } = paths(!!compose.serverId); - const { env, composePath, appName } = compose; - const composeFilePath = - join(COMPOSE_PATH, appName, "code", composePath) || - join(COMPOSE_PATH, appName, "code", "docker-compose.yml"); + const { COMPOSE_PATH } = paths(!!compose.serverId); + 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"); + const envFilePath = join(dirname(composeFilePath), ".env"); - let envContent = `APP_NAME=${appName}\n`; - envContent += env || ""; - if (!envContent.includes("DOCKER_CONFIG")) { - envContent += "\nDOCKER_CONFIG=/root/.docker"; - } + 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}`; - } + if (compose.randomize) { + envContent += `\nCOMPOSE_PREFIX=${compose.suffix}`; + } - const envFileContent = prepareEnvironmentVariables( - envContent, - compose.environment.project.env, - compose.environment.env, - ).join("\n"); + const envFileContent = prepareEnvironmentVariables( + envContent, + compose.environment.project.env, + compose.environment.env, + ).join("\n"); - const encodedContent = encodeBase64(envFileContent); - return ` + const encodedContent = encodeBase64(envFileContent); + return ` touch ${envFilePath}; echo "${encodedContent}" | base64 -d > "${envFilePath}"; `; }; const getExportEnvCommand = (compose: ComposeNested) => { - if (compose.composeType !== "stack") return ""; + if (compose.composeType !== "stack") return ""; - const envVars = getEnviromentVariablesObject( - compose.env, - compose.environment.project.env, - compose.environment.env, - ); - const exports = Object.entries(envVars) - .map(([key, value]) => `${key}=${quote([value])}`) - .join(" "); + const envVars = getEnvironmentVariablesObject( + compose.env, + compose.environment.project.env, + compose.environment.env, + ); + const exports = Object.entries(envVars) + .map(([key, value]) => `${key}=${quote([value])}`) + .join(" "); - return exports ? `${exports}` : ""; + return exports ? `${exports}` : ""; }; diff --git a/packages/server/src/utils/builders/docker-file.ts b/packages/server/src/utils/builders/docker-file.ts index ea53a5bff..f2fedf461 100644 --- a/packages/server/src/utils/builders/docker-file.ts +++ b/packages/server/src/utils/builders/docker-file.ts @@ -1,105 +1,105 @@ import { - getEnviromentVariablesObject, - prepareEnvironmentVariablesForShell, + getEnvironmentVariablesObject, + prepareEnvironmentVariablesForShell, } from "@dokploy/server/utils/docker/utils"; import { quote } from "shell-quote"; import { - getBuildAppDirectory, - getDockerContextPath, + getBuildAppDirectory, + getDockerContextPath, } from "../filesystem/directory"; import type { ApplicationNested } from "."; import { createEnvFileCommand } from "./utils"; export const getDockerCommand = (application: ApplicationNested) => { - const { - appName, - env, - publishDirectory, - buildArgs, - buildSecrets, - dockerBuildStage, - cleanCache, - createEnvFile, - } = application; - const dockerFilePath = getBuildAppDirectory(application); + const { + appName, + env, + publishDirectory, + buildArgs, + buildSecrets, + dockerBuildStage, + cleanCache, + createEnvFile, + } = application; + const dockerFilePath = getBuildAppDirectory(application); - try { - const image = `${appName}`; + try { + const image = `${appName}`; - const defaultContextPath = - dockerFilePath.substring(0, dockerFilePath.lastIndexOf("/") + 1) || "."; + const defaultContextPath = + dockerFilePath.substring(0, dockerFilePath.lastIndexOf("/") + 1) || "."; - const dockerContextPath = - getDockerContextPath(application) || defaultContextPath; + const dockerContextPath = + getDockerContextPath(application) || defaultContextPath; - const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."]; + const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."]; - if (dockerBuildStage) { - commandArgs.push("--target", dockerBuildStage); - } + if (dockerBuildStage) { + commandArgs.push("--target", dockerBuildStage); + } - if (cleanCache) { - commandArgs.push("--no-cache"); - } + if (cleanCache) { + commandArgs.push("--no-cache"); + } - const args = prepareEnvironmentVariablesForShell( - buildArgs, - application.environment.project.env, - application.environment.env, - ); + const args = prepareEnvironmentVariablesForShell( + buildArgs, + application.environment.project.env, + application.environment.env, + ); - for (const arg of args) { - commandArgs.push("--build-arg", arg); - } + for (const arg of args) { + commandArgs.push("--build-arg", arg); + } - const secrets = getEnviromentVariablesObject( - buildSecrets, - application.environment.project.env, - application.environment.env, - ); + const secrets = getEnvironmentVariablesObject( + buildSecrets, + application.environment.project.env, + application.environment.env, + ); - const joinedSecrets = Object.entries(secrets) - .map(([key, value]) => `${key}=${quote([value])}`) - .join(" "); + const joinedSecrets = Object.entries(secrets) + .map(([key, value]) => `${key}=${quote([value])}`) + .join(" "); - /* + /* Do not generate an environment file when publishDirectory is specified, as it could be publicly exposed. Also respect the createEnvFile flag. */ - let command = ""; - if (!publishDirectory && createEnvFile) { - command += createEnvFileCommand( - dockerFilePath, - env, - application.environment.project.env, - application.environment.env, - ); - } + let command = ""; + if (!publishDirectory && createEnvFile) { + command += createEnvFileCommand( + dockerFilePath, + env, + application.environment.project.env, + application.environment.env, + ); + } - for (const key in secrets) { - // Although buildx is smart enough to know we may be referring to an environment variable name, - // we still make sure it doesn't fall back to `type=file`. - // See: https://docs.docker.com/reference/cli/docker/buildx/build/#secret - commandArgs.push("--secret", `type=env,id=${key}`); - } + for (const key in secrets) { + // Although buildx is smart enough to know we may be referring to an environment variable name, + // we still make sure it doesn't fall back to `type=file`. + // See: https://docs.docker.com/reference/cli/docker/buildx/build/#secret + commandArgs.push("--secret", `type=env,id=${key}`); + } - command += ` + command += ` echo "Building ${appName}" ; -cd ${dockerContextPath} || { +cd ${dockerContextPath} || { echo "❌ The path ${dockerContextPath} does not exist" ; exit 1; } -${joinedSecrets} docker ${commandArgs.join(" ")} || { +${joinedSecrets} docker ${commandArgs.join(" ")} || { echo "❌ Docker build failed" ; exit 1; } echo "✅ Docker build completed." ; `; - return command; - } catch (error) { - throw error; - } + return command; + } catch (error) { + throw error; + } }; diff --git a/packages/server/src/utils/docker/utils.ts b/packages/server/src/utils/docker/utils.ts index b2c7e5d7b..dd645cd1b 100644 --- a/packages/server/src/utils/docker/utils.ts +++ b/packages/server/src/utils/docker/utils.ts @@ -434,7 +434,7 @@ export const parseEnvironmentKeyValuePair = ( return [key, valueParts.join("=")]; }; -export const getEnviromentVariablesObject = ( +export const getEnvironmentVariablesObject = ( input: string | null, projectEnv?: string | null, environmentEnv?: string | null, diff --git a/packages/server/src/utils/startup/cancell-deployments.ts b/packages/server/src/utils/startup/cancel-deployments.ts similarity index 100% rename from packages/server/src/utils/startup/cancell-deployments.ts rename to packages/server/src/utils/startup/cancel-deployments.ts