mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor(manage-traefik-ports): remove publishMode from port management and update related logic
This commit is contained in:
parent
4c5bc541d6
commit
160742c2cf
@ -19,13 +19,6 @@ import {
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { api } from "@/utils/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { ArrowRightLeft, Plus, Trash2 } from "lucide-react";
|
||||
@ -44,7 +37,6 @@ interface Props {
|
||||
const PortSchema = z.object({
|
||||
targetPort: z.number().min(1, "Target port is required"),
|
||||
publishedPort: z.number().min(1, "Published port is required"),
|
||||
publishMode: z.enum(["ingress", "host"]),
|
||||
});
|
||||
|
||||
const TraefikPortsSchema = z.object({
|
||||
@ -88,7 +80,7 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
|
||||
}, [currentPorts, form]);
|
||||
|
||||
const handleAddPort = () => {
|
||||
append({ targetPort: 0, publishedPort: 0, publishMode: "host" });
|
||||
append({ targetPort: 0, publishedPort: 0 });
|
||||
};
|
||||
|
||||
const onSubmit = async (data: TraefikPortsForm) => {
|
||||
@ -154,7 +146,7 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
|
||||
<div className="grid gap-4">
|
||||
{fields.map((field, index) => (
|
||||
<Card key={field.id}>
|
||||
<CardContent className="grid grid-cols-[1fr_1fr_1.5fr_auto] gap-4 p-4 transparent">
|
||||
<CardContent className="grid grid-cols-[1fr_1fr_auto] gap-4 p-4 transparent">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`ports.${index}.targetPort`}
|
||||
@ -207,39 +199,6 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`ports.${index}.publishMode`}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="text-sm font-medium text-muted-foreground">
|
||||
{t(
|
||||
"settings.server.webServer.traefik.publishMode",
|
||||
)}
|
||||
</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger className="dark:bg-black">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="host">
|
||||
Host Mode
|
||||
</SelectItem>
|
||||
<SelectItem value="ingress">
|
||||
Ingress Mode
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex items-end">
|
||||
<Button
|
||||
onClick={() => remove(index)}
|
||||
@ -263,30 +222,23 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
|
||||
<span className="text-sm">
|
||||
<strong>
|
||||
Each port mapping defines how external traffic reaches
|
||||
your containers.
|
||||
your containers through Traefik.
|
||||
</strong>
|
||||
<ul className="pt-2">
|
||||
<li>
|
||||
<strong>Host Mode:</strong> Directly binds the port
|
||||
to the host machine.
|
||||
<ul className="p-2 list-inside list-disc">
|
||||
<li>
|
||||
Best for single-node deployments or when you
|
||||
need guaranteed port availability.
|
||||
</li>
|
||||
</ul>
|
||||
<strong>Target Port:</strong> The port inside your
|
||||
container that the service is listening on.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Ingress Mode:</strong> Routes through Docker
|
||||
Swarm's load balancer.
|
||||
<ul className="p-2 list-inside list-disc">
|
||||
<li>
|
||||
Recommended for multi-node deployments and
|
||||
better scalability.
|
||||
</li>
|
||||
</ul>
|
||||
<strong>Published Port:</strong> The port on your
|
||||
host machine that will be mapped to the target port.
|
||||
</li>
|
||||
</ul>
|
||||
<p className="mt-2">
|
||||
All ports are bound directly to the host machine,
|
||||
allowing Traefik to handle incoming traffic and route
|
||||
it appropriately to your services.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</AlertBlock>
|
||||
|
@ -97,14 +97,20 @@ export const settingsRouter = createTRPCRouter({
|
||||
toggleDashboard: adminProcedure
|
||||
.input(apiEnableDashboard)
|
||||
.mutation(async ({ input }) => {
|
||||
const ports = (await getTraefikPorts(input.serverId)).filter(
|
||||
(port) =>
|
||||
port.targetPort !== 80 &&
|
||||
port.targetPort !== 443 &&
|
||||
port.targetPort !== 8080,
|
||||
);
|
||||
await initializeTraefik({
|
||||
additionalPorts: ports,
|
||||
enableDashboard: input.enableDashboard,
|
||||
serverId: input.serverId,
|
||||
force: true,
|
||||
});
|
||||
return true;
|
||||
}),
|
||||
|
||||
cleanUnusedImages: adminProcedure
|
||||
.input(apiServerSchema)
|
||||
.mutation(async ({ input }) => {
|
||||
@ -749,7 +755,6 @@ export const settingsRouter = createTRPCRouter({
|
||||
z.object({
|
||||
targetPort: z.number(),
|
||||
publishedPort: z.number(),
|
||||
publishMode: z.enum(["ingress", "host"]).default("host"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@ -782,59 +787,7 @@ export const settingsRouter = createTRPCRouter({
|
||||
getTraefikPorts: adminProcedure
|
||||
.input(apiServerSchema)
|
||||
.query(async ({ input }) => {
|
||||
const command = `docker container inspect --format='{{json .NetworkSettings.Ports}}' dokploy-traefik`;
|
||||
|
||||
try {
|
||||
let stdout = "";
|
||||
if (input?.serverId) {
|
||||
const result = await execAsyncRemote(input.serverId, command);
|
||||
stdout = result.stdout;
|
||||
} else if (!IS_CLOUD) {
|
||||
const result = await execAsync(command);
|
||||
stdout = result.stdout;
|
||||
}
|
||||
|
||||
const portsMap = JSON.parse(stdout.trim());
|
||||
const additionalPorts: Array<{
|
||||
targetPort: number;
|
||||
publishedPort: number;
|
||||
publishMode: "host" | "ingress";
|
||||
}> = [];
|
||||
|
||||
// Convert the Docker container port format to our expected format
|
||||
for (const [containerPort, bindings] of Object.entries(portsMap)) {
|
||||
if (!bindings) continue;
|
||||
|
||||
const [port = ""] = containerPort.split("/");
|
||||
if (!port) continue;
|
||||
|
||||
const targetPortNum = Number.parseInt(port, 10);
|
||||
if (Number.isNaN(targetPortNum)) continue;
|
||||
|
||||
// Skip default ports
|
||||
if ([80, 443, 8080].includes(targetPortNum)) continue;
|
||||
|
||||
for (const binding of bindings as Array<{ HostPort: string }>) {
|
||||
if (!binding.HostPort) continue;
|
||||
const publishedPort = Number.parseInt(binding.HostPort, 10);
|
||||
if (Number.isNaN(publishedPort)) continue;
|
||||
|
||||
additionalPorts.push({
|
||||
targetPort: targetPortNum,
|
||||
publishedPort,
|
||||
publishMode: "host", // Docker standalone uses host mode by default
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return additionalPorts;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Failed to get Traefik ports",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
return await getTraefikPorts(input?.serverId);
|
||||
}),
|
||||
updateLogCleanup: adminProcedure
|
||||
.input(
|
||||
@ -853,3 +806,56 @@ export const settingsRouter = createTRPCRouter({
|
||||
return getLogCleanupStatus();
|
||||
}),
|
||||
});
|
||||
|
||||
export const getTraefikPorts = async (serverId?: string) => {
|
||||
const command = `docker container inspect --format='{{json .NetworkSettings.Ports}}' dokploy-traefik`;
|
||||
try {
|
||||
let stdout = "";
|
||||
if (serverId) {
|
||||
const result = await execAsyncRemote(serverId, command);
|
||||
stdout = result.stdout;
|
||||
} else if (!IS_CLOUD) {
|
||||
const result = await execAsync(command);
|
||||
stdout = result.stdout;
|
||||
}
|
||||
|
||||
const portsMap = JSON.parse(stdout.trim());
|
||||
const additionalPorts: Array<{
|
||||
targetPort: number;
|
||||
publishedPort: number;
|
||||
}> = [];
|
||||
|
||||
// Convert the Docker container port format to our expected format
|
||||
for (const [containerPort, bindings] of Object.entries(portsMap)) {
|
||||
if (!bindings) continue;
|
||||
|
||||
const [port = ""] = containerPort.split("/");
|
||||
if (!port) continue;
|
||||
|
||||
const targetPortNum = Number.parseInt(port, 10);
|
||||
if (Number.isNaN(targetPortNum)) continue;
|
||||
|
||||
// Skip default ports
|
||||
if ([80, 443].includes(targetPortNum)) continue;
|
||||
|
||||
for (const binding of bindings as Array<{ HostPort: string }>) {
|
||||
if (!binding.HostPort) continue;
|
||||
const publishedPort = Number.parseInt(binding.HostPort, 10);
|
||||
if (Number.isNaN(publishedPort)) continue;
|
||||
|
||||
additionalPorts.push({
|
||||
targetPort: targetPortNum,
|
||||
publishedPort,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return additionalPorts;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Failed to get Traefik ports",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -22,7 +22,6 @@ interface TraefikOptions {
|
||||
additionalPorts?: {
|
||||
targetPort: number;
|
||||
publishedPort: number;
|
||||
publishMode?: "ingress" | "host";
|
||||
}[];
|
||||
force?: boolean;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user