Skip to content
Open
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 @@ -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 {
Expand All @@ -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(),
Expand Down Expand Up @@ -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),
);
Comment on lines +112 to +117

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Ambiguous data-volume selection

When a Postgres service has another volume under /var/lib/postgresql before its persisted data volume, find selects that unrelated mount for comparison, causing the warning to report the wrong current path or disappear when the unrelated path matches the image expectation.

Knowledge Base Used: Managed Databases

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 || "",
Expand Down Expand Up @@ -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}
Expand Down
Loading