fix: warn when the postgres image implies a data directory that mismatches the mounted volume

This commit is contained in:
Mauricio Siu
2026-08-07 01:34:15 -06:00
parent bcab5b059f
commit 6a10923a50
@@ -4,6 +4,7 @@ import { useEffect } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
@@ -18,6 +19,19 @@ import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
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({
dockerImage: z.string().min(1, "Docker image is required"),
command: z.string(),
@@ -91,6 +105,22 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
}
}, [data, form]);
const dockerImage = form.watch("dockerImage");
const mountPathWarning = (() => {
if (type !== "postgres" || !dockerImage) return null;
const mounts = (data as any)?.mounts ?? [];
const dataMount = mounts.find(
(mount: { type: string; mountPath: string }) =>
mount.type === "volume" &&
POSTGRES_DATA_PATH_REGEX.test(mount.mountPath),
);
if (!dataMount) return null;
const expectedPath = getPostgresMountPath(dockerImage);
if (expectedPath === dataMount.mountPath) return null;
return { expectedPath, currentPath: dataMount.mountPath };
})();
const onSubmit = async (formData: AddDockerImage) => {
await mutateAsync({
mongoId: id || "",
@@ -139,6 +169,18 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
</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>
<FormField
control={form.control}