From f0f34df13c787a93f60184497ab03e8ae48c2f43 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 22 Sep 2024 13:57:13 -0600 Subject: [PATCH] refactor(multi-server): improve alerts and add instructions to ssh keys --- .../cluster/modify-swarm-settings.tsx | 6 + .../dashboard/docker/show/show-containers.tsx | 165 ++++----- .../file-system/show-traefik-system.tsx | 17 +- .../dashboard/monitoring/docker/show.tsx | 2 - .../servers/actions/show-server-actions.tsx | 12 +- .../settings/servers/setup-server.tsx | 313 +++++++++++++----- .../settings/servers/show-servers.tsx | 33 +- .../dashboard/settings/users/show-users.tsx | 8 +- apps/dokploy/server/api/routers/settings.ts | 18 +- apps/dokploy/server/api/services/compose.ts | 5 - apps/dokploy/server/api/services/docker.ts | 6 +- .../server/wss/docker-container-logs.ts | 2 - apps/dokploy/server/wss/listen-deployment.ts | 2 - 13 files changed, 382 insertions(+), 207 deletions(-) diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx index fd91703b2..6750527d2 100644 --- a/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx @@ -278,6 +278,12 @@ export const AddSwarmSettings = ({ applicationId }: Props) => { {isError && {error?.message}} +
+ + Changing settings such as placements may cause the logs/monitoring + to be unavailable. + +
{ const { data, isLoading } = api.docker.getContainers.useQuery({ serverId, }); + const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [], @@ -109,83 +110,99 @@ export const ShowContainers = ({ serverId }: Props) => {
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ))} + {isLoading ? ( +
+ + Loading... + +
+ ) : data?.length === 0 ? ( +
+ + No results. + +
+ ) : ( +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} - )) - ) : ( - - - {isLoading ? ( -
- - Loading... - -
- ) : ( - <>No results. - )} -
-
- )} - -
+ ))} + + + {table?.getRowModel()?.rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) : ( + + + {isLoading ? ( +
+ + Loading... + +
+ ) : ( + <>No results. + )} +
+
+ )} +
+ + )}
-
-
- - + {data && data?.length > 0 && ( +
+
+ + +
-
+ )}
); diff --git a/apps/dokploy/components/dashboard/file-system/show-traefik-system.tsx b/apps/dokploy/components/dashboard/file-system/show-traefik-system.tsx index 7812e05de..0aaf9990b 100644 --- a/apps/dokploy/components/dashboard/file-system/show-traefik-system.tsx +++ b/apps/dokploy/components/dashboard/file-system/show-traefik-system.tsx @@ -17,14 +17,23 @@ export const ShowTraefikSystem = ({ serverId }: Props) => { isLoading, error, isError, - } = api.settings.readDirectories.useQuery({ - serverId, - }); + } = api.settings.readDirectories.useQuery( + { + serverId, + }, + { + retry: 2, + }, + ); return (
- {isError && {error?.message}} + {isError && ( + + {error?.message} + + )} {isLoading && (
diff --git a/apps/dokploy/components/dashboard/monitoring/docker/show.tsx b/apps/dokploy/components/dashboard/monitoring/docker/show.tsx index 8ed6d0b1e..365615ced 100644 --- a/apps/dokploy/components/dashboard/monitoring/docker/show.tsx +++ b/apps/dokploy/components/dashboard/monitoring/docker/show.tsx @@ -150,8 +150,6 @@ export const DockerMonitoring = ({ }); }, [data]); - console.log(currentData); - useEffect(() => { const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; const wsUrl = `${protocol}//${window.location.host}/listen-docker-stats-monitoring?appName=${appName}&appType=${appType}`; diff --git a/apps/dokploy/components/dashboard/settings/servers/actions/show-server-actions.tsx b/apps/dokploy/components/dashboard/settings/servers/actions/show-server-actions.tsx index 680e543e0..1f7f2d146 100644 --- a/apps/dokploy/components/dashboard/settings/servers/actions/show-server-actions.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/actions/show-server-actions.tsx @@ -1,5 +1,11 @@ import { CardDescription, CardTitle } from "@/components/ui/card"; -import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; import { useState } from "react"; import { ShowStorageActions } from "./show-storage-actions"; @@ -23,8 +29,8 @@ export const ShowServerActions = ({ serverId }: Props) => {
- Web server settings - Reload or clean the web server. + Web server settings + Reload or clean the web server.
diff --git a/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx b/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx index 61530f011..790fe925e 100644 --- a/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx @@ -18,11 +18,21 @@ import { } from "@/components/ui/dialog"; import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; import { api } from "@/utils/api"; -import { useUrl } from "@/utils/hooks/use-url"; -import { RocketIcon, ServerIcon } from "lucide-react"; +import { + CopyIcon, + ExternalLinkIcon, + RocketIcon, + ServerIcon, +} from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import { ShowDeployment } from "../../application/deployments/show-deployment"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { CodeEditor } from "@/components/shared/code-editor"; +import copy from "copy-to-clipboard"; +import Link from "next/link"; +import { Separator } from "@/components/ui/separator"; +import { AlertBlock } from "@/components/shared/alert-block"; interface Props { serverId: string; @@ -49,6 +59,8 @@ export const SetupServer = ({ serverId }: Props) => { const { mutateAsync, isLoading } = api.server.setup.useMutation(); + console.log(server?.sshKey); + return ( @@ -70,100 +82,219 @@ export const SetupServer = ({ serverId }: Props) => {

+ {!server?.sshKeyId ? ( +
+ + Please add a SSH Key to your server before setting up the server. + you can assign a SSH Key to your server in Edit Server. + +
+ ) : ( +
+ + + SSH Keys + Deployments + + +
+

+ You have two options to add SSH Keys to your server: +

-
- -
- - -
-
- Deployments - - See all the 5 Server Setup - -
- { - await mutateAsync({ - serverId: server?.serverId || "", - }) - .then(async () => { - refetch(); - toast.success("Server setup successfully"); - }) - .catch(() => { - toast.error("Error configuring server"); - }); - }} - > - - -
-
- - {server?.deployments?.length === 0 ? ( -
- - - No deployments found - -
- ) : ( -
- {deployments?.map((deployment) => ( -
+
  • + 1. Add the public SSH Key when you create a server in your + preffered provider (Hostinger, Digital Ocean, Hetzner, + etc){" "} +
  • +
  • 2. Add The SSH Key to Server Manually
  • + +
    +
    +
    + Copy Public Key ({server?.sshKey?.name}) + -
    -
    - ))} + + +
    - )} +
    - setActiveLog(null)} - logPath={activeLog} - /> +
    + + Automatic process + + + View Tutorial + +
    +
    + + Manual process + +
      +
    • + 1. Login to your server{" "} + + ssh {server?.username}@{server?.ipAddress} + + +
    • +
    • + 2. When you are logged in run the following command +
      + > ~/.ssh/authorized_keys`} + readOnly + className="font-mono opacity-60" + /> + +
      +
    • +
    • + 3. You're done, you can test the connection by entering + to the terminal or by setting up the server tab. +
    • +
    +
    +
    + + + +
    + + +
    +
    + + Deployments + + + See all the 5 Server Setup + +
    + { + await mutateAsync({ + serverId: server?.serverId || "", + }) + .then(async () => { + refetch(); + toast.success("Server setup successfully"); + }) + .catch(() => { + toast.error("Error configuring server"); + }); + }} + > + + +
    +
    + + {server?.deployments?.length === 0 ? ( +
    + + + No deployments found + +
    + ) : ( +
    + {deployments?.map((deployment) => ( +
    +
    + + {deployment.status} + + + + + {deployment.title} + + {deployment.description && ( + + {deployment.description} + + )} +
    +
    +
    + +
    + + +
    +
    + ))} +
    + )} + + setActiveLog(null)} + logPath={activeLog} + /> +
    +
    +
    - -
    - -
    +
    +
    +
    + )}
    ); diff --git a/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx b/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx index 5b78065f5..ae4923b48 100644 --- a/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx @@ -131,13 +131,18 @@ export const ShowServers = () => { Actions - - Enter the terminal - + {server.sshKeyId && ( + + Enter the terminal + + )} + - + {server.sshKeyId && ( + + )} { - - Extra + {server.sshKeyId && ( + <> + + Extra - - + + + + )} diff --git a/apps/dokploy/components/dashboard/settings/users/show-users.tsx b/apps/dokploy/components/dashboard/settings/users/show-users.tsx index cad28487c..7795b42d4 100644 --- a/apps/dokploy/components/dashboard/settings/users/show-users.tsx +++ b/apps/dokploy/components/dashboard/settings/users/show-users.tsx @@ -41,8 +41,8 @@ export const ShowUsers = () => { }, []); return ( -
    - +
    +
    Users @@ -55,9 +55,9 @@ export const ShowUsers = () => {
    )}
    - + {data?.length === 0 ? ( -
    +
    To create a user, you need to add: diff --git a/apps/dokploy/server/api/routers/settings.ts b/apps/dokploy/server/api/routers/settings.ts index 1c70601aa..ff6ed68ff 100644 --- a/apps/dokploy/server/api/routers/settings.ts +++ b/apps/dokploy/server/api/routers/settings.ts @@ -276,16 +276,20 @@ export const settingsRouter = createTRPCRouter({ readDirectories: protectedProcedure .input(apiServerSchema) .query(async ({ ctx, input }) => { - if (ctx.user.rol === "user") { - const canAccess = await canAccessToTraefikFiles(ctx.user.authId); + try { + if (ctx.user.rol === "user") { + const canAccess = await canAccessToTraefikFiles(ctx.user.authId); - if (!canAccess) { - throw new TRPCError({ code: "UNAUTHORIZED" }); + if (!canAccess) { + throw new TRPCError({ code: "UNAUTHORIZED" }); + } } + const { MAIN_TRAEFIK_PATH } = paths(!!input?.serverId); + const result = await readDirectory(MAIN_TRAEFIK_PATH, input?.serverId); + return result || []; + } catch (error) { + throw error; } - const { MAIN_TRAEFIK_PATH } = paths(!!input?.serverId); - const result = await readDirectory(MAIN_TRAEFIK_PATH, input?.serverId); - return result || []; }), updateTraefikFile: protectedProcedure diff --git a/apps/dokploy/server/api/services/compose.ts b/apps/dokploy/server/api/services/compose.ts index 1ac00893d..13c728f5f 100644 --- a/apps/dokploy/server/api/services/compose.ts +++ b/apps/dokploy/server/api/services/compose.ts @@ -337,8 +337,6 @@ export const deployRemoteCompose = async ({ await execAsyncRemote(compose.serverId, command); await getBuildComposeCommand(compose, deployment.logPath); - - console.log(" ---- done ----"); } await updateDeploymentStatus(deployment.deploymentId, "done"); @@ -443,9 +441,6 @@ export const stopCompose = async (composeId: string) => { try { const { COMPOSE_PATH } = paths(!!compose.serverId); if (compose.composeType === "docker-compose") { - console.log( - `cd ${join(COMPOSE_PATH, compose.appName)} && docker compose -p ${compose.appName} stop`, - ); if (compose.serverId) { await execAsyncRemote( compose.serverId, diff --git a/apps/dokploy/server/api/services/docker.ts b/apps/dokploy/server/api/services/docker.ts index 0accb84ae..d611a11d1 100644 --- a/apps/dokploy/server/api/services/docker.ts +++ b/apps/dokploy/server/api/services/docker.ts @@ -58,7 +58,11 @@ export const getContainers = async (serverId?: string | null) => { .filter((container) => !container.name.includes("dokploy")); return containers; - } catch (error) {} + } catch (error) { + console.error(error); + + return []; + } }; export const getConfig = async ( diff --git a/apps/dokploy/server/wss/docker-container-logs.ts b/apps/dokploy/server/wss/docker-container-logs.ts index 5ab677652..a55951c56 100644 --- a/apps/dokploy/server/wss/docker-container-logs.ts +++ b/apps/dokploy/server/wss/docker-container-logs.ts @@ -72,11 +72,9 @@ export const setupDockerContainerLogsWebSocketServer = ( }) .on("data", (data: string) => { ws.send(data.toString()); - // console.log(`OUTPUT: ${data.toString()}`); }) .stderr.on("data", (data) => { ws.send(data.toString()); - // console.error(`STDERR: ${data.toString()}`); }); }); }) diff --git a/apps/dokploy/server/wss/listen-deployment.ts b/apps/dokploy/server/wss/listen-deployment.ts index e32e1b682..1e38bcdf7 100644 --- a/apps/dokploy/server/wss/listen-deployment.ts +++ b/apps/dokploy/server/wss/listen-deployment.ts @@ -71,11 +71,9 @@ export const setupDeploymentLogsWebSocketServer = ( }) .on("data", (data: string) => { ws.send(data.toString()); - // console.log(`OUTPUT: ${data.toString()}`); }) .stderr.on("data", (data) => { ws.send(data.toString()); - // console.error(`STDERR: ${data.toString()}`); }); }); })