Merge pull request #5066 from Souvik-Cyclic/fix/docker-terminal-clipboard-5065

fix: add clipboard addon to docker container terminal
This commit is contained in:
Narciso E. Núñez Arias
2026-08-12 16:33:02 -04:00
committed by GitHub
3 changed files with 13 additions and 15 deletions
@@ -3,9 +3,9 @@ import type { Domain } from "@dokploy/server/services/domain";
import { addDomainToCompose } from "@dokploy/server/utils/docker/domain";
import { beforeEach, describe, expect, it, vi } from "vitest";
// addDomainToCompose reads the compose file from disk through loadDockerCompose
// (existsSync + readFileSync). Mock node:fs so the function runs its real
// label-generation logic against an in-memory compose spec.
// With sourceType "raw", addDomainToCompose parses compose.composeFile
// directly instead of reading from disk, so baseCompose exposes it as a
// getter that always reflects the current composeYaml for each test case.
const baseComposeYaml = `
services:
frigate:
@@ -13,15 +13,6 @@ services:
`;
let composeYaml = baseComposeYaml;
vi.mock("node:fs", async (importOriginal) => {
const actual = await importOriginal<typeof import("node:fs")>();
return {
...actual,
existsSync: vi.fn(() => true),
readFileSync: vi.fn(() => composeYaml),
};
});
const baseCompose = {
appName: "test-app",
composeType: "docker-compose",
@@ -31,6 +22,9 @@ const baseCompose = {
isolatedDeployment: false,
randomize: false,
suffix: "",
get composeFile() {
return composeYaml;
},
} as unknown as Compose;
const baseDomain: Domain = {
@@ -3,6 +3,7 @@ import React, { useEffect, useRef } from "react";
import { FitAddon } from "xterm-addon-fit";
import "@xterm/xterm/css/xterm.css";
import { AttachAddon } from "@xterm/addon-attach";
import { ClipboardAddon } from "@xterm/addon-clipboard";
import { useTheme } from "next-themes";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { fixMacOsAltKeys } from "@/lib/terminal-keyboard";
@@ -46,6 +47,8 @@ export const DockerTerminal: React.FC<Props> = ({
const ws = new WebSocket(wsUrl);
const addonAttach = new AttachAddon(ws);
const clipboardAddon = new ClipboardAddon();
term.loadAddon(clipboardAddon);
fixMacOsAltKeys(term);
// @ts-ignore
term.open(termRef.current);
@@ -55,6 +58,7 @@ export const DockerTerminal: React.FC<Props> = ({
addonFit.fit();
return () => {
ws.readyState === WebSocket.OPEN && ws.close();
term.dispose();
};
}, [containerId, activeWay, id]);
@@ -70,9 +70,9 @@ export const ToggleDockerCleanup = ({ serverId }: Props) => {
<TooltipContent side="top" className="max-w-sm">
<p>
Runs a full Docker cleanup daily, pruning stopped containers,
unused images, build cache, and system resources. This
may remove images built for Compose services that run on-demand
(backup runners, cron jobs, one-off tasks).
unused images, build cache, and system resources. This may remove
images built for Compose services that run on-demand (backup
runners, cron jobs, one-off tasks).
</p>
<p className="mt-1">
For custom cleanup strategies, use{" "}