Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import {
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";

import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api";

Expand All @@ -40,6 +42,7 @@ interface Props {
// Schema for Isolated Deployment
const isolatedSchema = z.object({
isolatedDeployment: z.boolean().optional(),
isolatedNetworkMtu: z.number().int().min(68).max(9000).nullable().optional(),
});

type IsolatedSchema = z.infer<typeof isolatedSchema>;
Expand All @@ -63,6 +66,7 @@ export const IsolatedDeploymentTab = ({ composeId }: Props) => {
const form = useForm<IsolatedSchema>({
defaultValues: {
isolatedDeployment: false,
isolatedNetworkMtu: null,
},
resolver: zodResolver(isolatedSchema),
});
Expand All @@ -71,6 +75,7 @@ export const IsolatedDeploymentTab = ({ composeId }: Props) => {
if (data) {
form.reset({
isolatedDeployment: data?.isolatedDeployment || false,
isolatedNetworkMtu: data?.isolatedNetworkMtu ?? null,
});
}
}, [form, form.reset, form.formState.isSubmitSuccessful, data]);
Expand All @@ -79,6 +84,7 @@ export const IsolatedDeploymentTab = ({ composeId }: Props) => {
await updateCompose({
composeId,
isolatedDeployment: formData?.isolatedDeployment || false,
isolatedNetworkMtu: formData?.isolatedNetworkMtu ?? null,
})
.then(async (_data) => {
await refetch();
Expand Down Expand Up @@ -180,6 +186,41 @@ export const IsolatedDeploymentTab = ({ composeId }: Props) => {
/>
</div>

{form.watch("isolatedDeployment") && (
<div>
<FormField
control={form.control}
name="isolatedNetworkMtu"
render={({ field }) => (
<FormItem className="mt-4 rounded-lg border p-3 shadow-sm">
<div className="space-y-0.5">
<FormLabel>
Network MTU (optional)
</FormLabel>
<FormDescription>
Set a custom MTU for the isolated network. Leave empty for Docker default (1500). Use 1350 for environments behind VPN/overlay networks.
</FormDescription>
</div>
<FormControl>
<Input
type="number"
min={68}
max={9000}
placeholder="1500"
value={field.value ?? ""}
onChange={(e) => {
const val = e.target.value;
field.onChange(val === "" ? null : Number(val));
}}
/>
</FormControl>
<FormMessage />
</FormItem>
Comment thread
Hobby-Student marked this conversation as resolved.
)}
/>
</div>
)}

<div className="flex flex-col lg:flex-row gap-4 w-full items-end justify-end">
<Button
form="isolated-deployment-form"
Expand Down
1 change: 1 addition & 0 deletions apps/dokploy/drizzle/0165_add_isolated_network_mtu.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE "compose" ADD COLUMN "isolatedNetworkMtu" integer;
7 changes: 7 additions & 0 deletions apps/dokploy/drizzle/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,13 @@
"when": 1775369858244,
"tag": "0164_slippery_sasquatch",
"breakpoints": true
},
{
"idx": 165,
"version": "7",
"when": 1774490000000,
"tag": "0165_add_isolated_network_mtu",
"breakpoints": true
}
]
}
1 change: 1 addition & 0 deletions packages/server/src/db/schema/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const compose = pgTable("compose", {
suffix: text("suffix").notNull().default(""),
randomize: boolean("randomize").notNull().default(false),
isolatedDeployment: boolean("isolatedDeployment").notNull().default(false),
isolatedNetworkMtu: integer("isolatedNetworkMtu"),
// Keep this for backward compatibility since we will not add the prefix anymore to volumes
isolatedDeploymentsVolume: boolean("isolatedDeploymentsVolume")
.notNull()
Expand Down
7 changes: 6 additions & 1 deletion packages/server/src/utils/builders/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ Compose Type: ${composeType} ✅`;

cd "${projectPath}";

${compose.isolatedDeployment ? `docker network inspect ${compose.appName} >/dev/null 2>&1 || docker network create ${compose.composeType === "stack" ? "--driver overlay" : ""} --attachable ${compose.appName}` : ""}
${compose.isolatedDeployment ? `
if docker network inspect ${compose.appName} >/dev/null 2>&1; then
${compose.composeType !== "stack" && compose.isolatedNetworkMtu ? `CURRENT_MTU=$(docker network inspect ${compose.appName} --format '{{index .Options "com.docker.network.driver.mtu"}}'); if [ "$CURRENT_MTU" != "${compose.isolatedNetworkMtu}" ]; then echo "Info: Network ${compose.appName} has MTU $CURRENT_MTU but configured MTU is ${compose.isolatedNetworkMtu}. The network must be recreated for the new MTU to take effect."; fi` : "true"}
else
docker network create ${compose.composeType === "stack" ? "--driver overlay" : ""} --attachable ${compose.composeType !== "stack" && compose.isolatedNetworkMtu ? `--opt com.docker.network.driver.mtu=${compose.isolatedNetworkMtu}` : ""} ${compose.appName}
fi` : ""}
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` : ""}

Expand Down