diff --git a/apps/dokploy/components/dashboard/swarm/applications/show-applications.tsx b/apps/dokploy/components/dashboard/swarm/applications/show-applications.tsx index df764225d..41d7b113b 100644 --- a/apps/dokploy/components/dashboard/swarm/applications/show-applications.tsx +++ b/apps/dokploy/components/dashboard/swarm/applications/show-applications.tsx @@ -10,26 +10,13 @@ import { import { api } from "@/utils/api"; import { Layers, Loader2 } from "lucide-react"; import React from "react"; -import { columns } from "./columns"; +import { type ApplicationList, columns } from "./columns"; import { DataTable } from "./data-table"; interface Props { serverId?: string; } -interface ApplicationList { - ID: string; - Image: string; - Mode: string; - Name: string; - Ports: string; - Replicas: string; - CurrentState: string; - DesiredState: string; - Error: string; - Node: string; -} - export const ShowNodeApplications = ({ serverId }: Props) => { const { data: NodeApps, isLoading: NodeAppsLoading } = api.swarm.getNodeApps.useQuery({ serverId }); diff --git a/apps/dokploy/server/api/routers/application.ts b/apps/dokploy/server/api/routers/application.ts index 2902c8eda..b03211c45 100644 --- a/apps/dokploy/server/api/routers/application.ts +++ b/apps/dokploy/server/api/routers/application.ts @@ -555,9 +555,9 @@ export const applicationRouter = createTRPCRouter({ }); } - updateApplication(input.applicationId as string, { + await updateApplication(input.applicationId as string, { sourceType: "drop", - dropBuildPath: input.dropBuildPath, + dropBuildPath: input.dropBuildPath || "", }); await unzipDrop(zipFile, app); diff --git a/packages/server/src/utils/builders/drop.ts b/packages/server/src/utils/builders/drop.ts index 420cd7aa1..396c52d96 100644 --- a/packages/server/src/utils/builders/drop.ts +++ b/packages/server/src/utils/builders/drop.ts @@ -27,7 +27,9 @@ export const unzipDrop = async (zipFile: File, application: Application) => { const buffer = Buffer.from(arrayBuffer); const zip = new AdmZip(buffer); - const zipEntries = zip.getEntries(); + const zipEntries = zip + .getEntries() + .filter((entry) => !entry.entryName.startsWith("__MACOSX")); const rootEntries = zipEntries.filter( (entry) => @@ -59,14 +61,22 @@ export const unzipDrop = async (zipFile: File, application: Application) => { if (!filePath) continue; - const fullPath = path.join(outputPath, filePath); + const fullPath = path.join(outputPath, filePath).replace(/\\/g, "/"); if (application.serverId) { - if (entry.isDirectory) { - await execAsyncRemote(application.serverId, `mkdir -p ${fullPath}`); - } else { + if (!entry.isDirectory) { if (sftp === null) throw new Error("No SFTP connection available"); - await uploadFileToServer(sftp, entry.getData(), fullPath); + try { + const dirPath = path.dirname(fullPath); + await execAsyncRemote( + application.serverId, + `mkdir -p "${dirPath}"`, + ); + await uploadFileToServer(sftp, entry.getData(), fullPath); + } catch (err) { + console.error(`Error uploading file ${fullPath}:`, err); + throw err; + } } } else { if (entry.isDirectory) { @@ -103,7 +113,6 @@ const getSFTPConnection = async (serverId: string): Promise => { port: server.port, username: server.username, privateKey: server.sshKey?.privateKey, - timeout: 99999, }); }); }; @@ -115,7 +124,10 @@ const uploadFileToServer = ( ): Promise => { return new Promise((resolve, reject) => { sftp.writeFile(remotePath, data, (err) => { - if (err) return reject(err); + if (err) { + console.error(`SFTP write error for ${remotePath}:`, err); + return reject(err); + } resolve(); }); });