mirror of
https://github.com/andwati/dokploy.git
synced 2026-10-18 03:02:56 +00:00
Merge pull request #5005 from Dokploy/fix/postgres-image-mountpath-warning
fix: warn on postgres image change when the implied data directory mismatches the mounted volume
(cherry picked from commit f08c53c9b7)
[skip ci]
This commit is contained in:
committed by
Dokploy Bot
parent
79af8da827
commit
b1795e1d3c
@@ -4,6 +4,7 @@ import { useEffect } from "react";
|
|||||||
import { useFieldArray, useForm } from "react-hook-form";
|
import { useFieldArray, useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import {
|
import {
|
||||||
@@ -18,6 +19,19 @@ import { Input } from "@/components/ui/input";
|
|||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import type { ServiceType } from "../../application/advanced/show-resources";
|
import type { ServiceType } from "../../application/advanced/show-resources";
|
||||||
|
|
||||||
|
const getPostgresMountPath = (dockerImage: string): string => {
|
||||||
|
const versionMatch = dockerImage.match(/postgres:(\d+)/);
|
||||||
|
if (versionMatch?.[1]) {
|
||||||
|
const version = Number.parseInt(versionMatch[1], 10);
|
||||||
|
if (version >= 18) {
|
||||||
|
return `/var/lib/postgresql/${version}/docker`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "/var/lib/postgresql/data";
|
||||||
|
};
|
||||||
|
|
||||||
|
const POSTGRES_DATA_PATH_REGEX = /^\/var\/lib\/postgresql(\/|$)/;
|
||||||
|
|
||||||
const addDockerImage = z.object({
|
const addDockerImage = z.object({
|
||||||
dockerImage: z.string().min(1, "Docker image is required"),
|
dockerImage: z.string().min(1, "Docker image is required"),
|
||||||
command: z.string(),
|
command: z.string(),
|
||||||
@@ -91,6 +105,27 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
|
|||||||
}
|
}
|
||||||
}, [data, form]);
|
}, [data, form]);
|
||||||
|
|
||||||
|
const dockerImage = form.watch("dockerImage");
|
||||||
|
|
||||||
|
const mountPathWarning = (() => {
|
||||||
|
if (type !== "postgres" || !dockerImage) return null;
|
||||||
|
const mounts = data && "mounts" in data ? data.mounts : [];
|
||||||
|
const dataMounts = mounts.filter(
|
||||||
|
(mount) =>
|
||||||
|
mount.type === "volume" &&
|
||||||
|
POSTGRES_DATA_PATH_REGEX.test(mount.mountPath),
|
||||||
|
);
|
||||||
|
if (dataMounts.length === 0) return null;
|
||||||
|
const expectedPath = getPostgresMountPath(dockerImage);
|
||||||
|
if (dataMounts.some((mount) => mount.mountPath === expectedPath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
expectedPath,
|
||||||
|
currentPath: dataMounts.map((mount) => mount.mountPath).join(", "),
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
const onSubmit = async (formData: AddDockerImage) => {
|
const onSubmit = async (formData: AddDockerImage) => {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
mongoId: id || "",
|
mongoId: id || "",
|
||||||
@@ -139,6 +174,18 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{mountPathWarning && (
|
||||||
|
<AlertBlock type="warning">
|
||||||
|
This image expects its data directory under{" "}
|
||||||
|
<code>{mountPathWarning.expectedPath}</code>, but the
|
||||||
|
volume of this database is mounted at{" "}
|
||||||
|
<code>{mountPathWarning.currentPath}</code>. Changing the
|
||||||
|
image does not migrate existing data — Postgres may
|
||||||
|
crash-loop or start with an empty database. Adjust the
|
||||||
|
volume mount path in the Volumes section or keep a
|
||||||
|
compatible image before saving.
|
||||||
|
</AlertBlock>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
Reference in New Issue
Block a user