-
Enable Isolated Deployment ({data?.appName})
+
+ Enable Isolated Deployment ({data?.appName})
+
Enable isolated deployment to the compose file.
diff --git a/apps/dokploy/components/dashboard/database/backups/add-backup.tsx b/apps/dokploy/components/dashboard/database/backups/add-backup.tsx
index 219e42184..5b963a4c6 100644
--- a/apps/dokploy/components/dashboard/database/backups/add-backup.tsx
+++ b/apps/dokploy/components/dashboard/database/backups/add-backup.tsx
@@ -286,16 +286,21 @@ export const AddBackup = ({ databaseId, databaseType, refetch }: Props) => {
Keep the latest
-
+
- Optional. If provided, only keeps the latest N backups in the cloud.
+ Optional. If provided, only keeps the latest N backups
+ in the cloud.
);
}}
- />
+ />
{
enabled: backup.enabled || false,
prefix: backup.prefix,
schedule: backup.schedule,
- keepLatestCount: backup.keepLatestCount ? Number(backup.keepLatestCount) : undefined,
+ keepLatestCount: backup.keepLatestCount
+ ? Number(backup.keepLatestCount)
+ : undefined,
});
}
}, [form, form.reset, backup]);
@@ -274,10 +276,15 @@ export const UpdateBackup = ({ backupId, refetch }: Props) => {
Keep the latest
-
+
- Optional. If provided, only keeps the latest N backups in the cloud.
+ Optional. If provided, only keeps the latest N backups
+ in the cloud.
diff --git a/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx b/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx
index 9f5b63c31..c00af42be 100644
--- a/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx
+++ b/apps/dokploy/components/dashboard/mariadb/general/show-external-mariadb-credentials.tsx
@@ -27,145 +27,149 @@ import { toast } from "sonner";
import { z } from "zod";
const DockerProviderSchema = z.object({
- externalPort: z.preprocess((a) => {
- if (a !== null) {
- const parsed = Number.parseInt(z.string().parse(a), 10);
- return Number.isNaN(parsed) ? null : parsed;
- }
- return null;
- }, z.number().gte(0, "Range must be 0 - 65535").lte(65535, "Range must be 0 - 65535").nullable()),
+ externalPort: z.preprocess((a) => {
+ if (a !== null) {
+ const parsed = Number.parseInt(z.string().parse(a), 10);
+ return Number.isNaN(parsed) ? null : parsed;
+ }
+ return null;
+ }, z
+ .number()
+ .gte(0, "Range must be 0 - 65535")
+ .lte(65535, "Range must be 0 - 65535")
+ .nullable()),
});
type DockerProvider = z.infer;
interface Props {
- mariadbId: string;
+ mariadbId: string;
}
export const ShowExternalMariadbCredentials = ({ mariadbId }: Props) => {
- const { data: ip } = api.settings.getIp.useQuery();
- const { data, refetch } = api.mariadb.one.useQuery({ mariadbId });
- const { mutateAsync, isLoading } = api.mariadb.saveExternalPort.useMutation();
- const [connectionUrl, setConnectionUrl] = useState("");
- const getIp = data?.server?.ipAddress || ip;
- const form = useForm({
- defaultValues: {},
- resolver: zodResolver(DockerProviderSchema),
- });
+ const { data: ip } = api.settings.getIp.useQuery();
+ const { data, refetch } = api.mariadb.one.useQuery({ mariadbId });
+ const { mutateAsync, isLoading } = api.mariadb.saveExternalPort.useMutation();
+ const [connectionUrl, setConnectionUrl] = useState("");
+ const getIp = data?.server?.ipAddress || ip;
+ const form = useForm({
+ defaultValues: {},
+ resolver: zodResolver(DockerProviderSchema),
+ });
- useEffect(() => {
- if (data?.externalPort) {
- form.reset({
- externalPort: data.externalPort,
- });
- }
- }, [form.reset, data, form]);
+ useEffect(() => {
+ if (data?.externalPort) {
+ form.reset({
+ externalPort: data.externalPort,
+ });
+ }
+ }, [form.reset, data, form]);
- const onSubmit = async (values: DockerProvider) => {
- await mutateAsync({
- externalPort: values.externalPort,
- mariadbId,
- })
- .then(async () => {
- toast.success("External Port updated");
- await refetch();
- })
- .catch(() => {
- toast.error("Error saving the external port");
- });
- };
+ const onSubmit = async (values: DockerProvider) => {
+ await mutateAsync({
+ externalPort: values.externalPort,
+ mariadbId,
+ })
+ .then(async () => {
+ toast.success("External Port updated");
+ await refetch();
+ })
+ .catch(() => {
+ toast.error("Error saving the external port");
+ });
+ };
- useEffect(() => {
- const buildConnectionUrl = () => {
- const port = form.watch("externalPort") || data?.externalPort;
+ useEffect(() => {
+ const buildConnectionUrl = () => {
+ const port = form.watch("externalPort") || data?.externalPort;
- return `mariadb://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}/${data?.databaseName}`;
- };
+ return `mariadb://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}/${data?.databaseName}`;
+ };
- setConnectionUrl(buildConnectionUrl());
- }, [
- data?.appName,
- data?.externalPort,
- data?.databasePassword,
- form,
- data?.databaseName,
- data?.databaseUser,
- getIp,
- ]);
- return (
- <>
-
-
-
- External Credentials
-
- In order to make the database reachable trought internet is
- required to set a port, make sure the port is not used by another
- application or database
-
-
-
- {!getIp && (
-
- You need to set an IP address in your{" "}
-
- {data?.serverId
- ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
- : "Web Server -> Server -> Update Server IP"}
- {" "}
- to fix the database url connection.
-
- )}
-
+
+
+
+
+ >
+ );
};
diff --git a/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx b/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx
index b5ed9f863..75772bfdf 100644
--- a/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx
+++ b/apps/dokploy/components/dashboard/mongo/general/show-external-mongo-credentials.tsx
@@ -27,144 +27,148 @@ import { toast } from "sonner";
import { z } from "zod";
const DockerProviderSchema = z.object({
- externalPort: z.preprocess((a) => {
- if (a !== null) {
- const parsed = Number.parseInt(z.string().parse(a), 10);
- return Number.isNaN(parsed) ? null : parsed;
- }
- return null;
- }, z.number().gte(0, "Range must be 0 - 65535").lte(65535, "Range must be 0 - 65535").nullable()),
+ externalPort: z.preprocess((a) => {
+ if (a !== null) {
+ const parsed = Number.parseInt(z.string().parse(a), 10);
+ return Number.isNaN(parsed) ? null : parsed;
+ }
+ return null;
+ }, z
+ .number()
+ .gte(0, "Range must be 0 - 65535")
+ .lte(65535, "Range must be 0 - 65535")
+ .nullable()),
});
type DockerProvider = z.infer;
interface Props {
- mongoId: string;
+ mongoId: string;
}
export const ShowExternalMongoCredentials = ({ mongoId }: Props) => {
- const { data: ip } = api.settings.getIp.useQuery();
- const { data, refetch } = api.mongo.one.useQuery({ mongoId });
- const { mutateAsync, isLoading } = api.mongo.saveExternalPort.useMutation();
- const [connectionUrl, setConnectionUrl] = useState("");
- const getIp = data?.server?.ipAddress || ip;
- const form = useForm({
- defaultValues: {},
- resolver: zodResolver(DockerProviderSchema),
- });
+ const { data: ip } = api.settings.getIp.useQuery();
+ const { data, refetch } = api.mongo.one.useQuery({ mongoId });
+ const { mutateAsync, isLoading } = api.mongo.saveExternalPort.useMutation();
+ const [connectionUrl, setConnectionUrl] = useState("");
+ const getIp = data?.server?.ipAddress || ip;
+ const form = useForm({
+ defaultValues: {},
+ resolver: zodResolver(DockerProviderSchema),
+ });
- useEffect(() => {
- if (data?.externalPort) {
- form.reset({
- externalPort: data.externalPort,
- });
- }
- }, [form.reset, data, form]);
+ useEffect(() => {
+ if (data?.externalPort) {
+ form.reset({
+ externalPort: data.externalPort,
+ });
+ }
+ }, [form.reset, data, form]);
- const onSubmit = async (values: DockerProvider) => {
- await mutateAsync({
- externalPort: values.externalPort,
- mongoId,
- })
- .then(async () => {
- toast.success("External Port updated");
- await refetch();
- })
- .catch(() => {
- toast.error("Error saving the external port");
- });
- };
+ const onSubmit = async (values: DockerProvider) => {
+ await mutateAsync({
+ externalPort: values.externalPort,
+ mongoId,
+ })
+ .then(async () => {
+ toast.success("External Port updated");
+ await refetch();
+ })
+ .catch(() => {
+ toast.error("Error saving the external port");
+ });
+ };
- useEffect(() => {
- const buildConnectionUrl = () => {
- const port = form.watch("externalPort") || data?.externalPort;
+ useEffect(() => {
+ const buildConnectionUrl = () => {
+ const port = form.watch("externalPort") || data?.externalPort;
- return `mongodb://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}`;
- };
+ return `mongodb://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}`;
+ };
- setConnectionUrl(buildConnectionUrl());
- }, [
- data?.appName,
- data?.externalPort,
- data?.databasePassword,
- form,
- data?.databaseUser,
- getIp,
- ]);
+ setConnectionUrl(buildConnectionUrl());
+ }, [
+ data?.appName,
+ data?.externalPort,
+ data?.databasePassword,
+ form,
+ data?.databaseUser,
+ getIp,
+ ]);
- return (
- <>
-
-
-
- External Credentials
-
- In order to make the database reachable trought internet is
- required to set a port, make sure the port is not used by another
- application or database
-
-
-
- {!getIp && (
-
- You need to set an IP address in your{" "}
-
- {data?.serverId
- ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
- : "Web Server -> Server -> Update Server IP"}
- {" "}
- to fix the database url connection.
-
- )}
-
-
-
-
- {
- return (
-
- External Port (Internet)
-
-
-
-
-
- );
- }}
- />
-
-
- {!!data?.externalPort && (
-
- )}
+ return (
+ <>
+
+
+
+ External Credentials
+
+ In order to make the database reachable trought internet is
+ required to set a port, make sure the port is not used by another
+ application or database
+
+
+
+ {!getIp && (
+
+ You need to set an IP address in your{" "}
+
+ {data?.serverId
+ ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
+ : "Web Server -> Server -> Update Server IP"}
+ {" "}
+ to fix the database url connection.
+
+ )}
+
+
+
+
+ {
+ return (
+
+ External Port (Internet)
+
+
+
+
+
+ );
+ }}
+ />
+
+
+ {!!data?.externalPort && (
+
+ )}
-
-
- Save
-
-
-
-
-
-
-
- >
- );
+
+
+ Save
+
+
+
+
+
+
+
+ >
+ );
};
diff --git a/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx b/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx
index 2c8ed5f5b..73f99b7d0 100644
--- a/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx
+++ b/apps/dokploy/components/dashboard/mysql/general/show-external-mysql-credentials.tsx
@@ -27,144 +27,148 @@ import { toast } from "sonner";
import { z } from "zod";
const DockerProviderSchema = z.object({
- externalPort: z.preprocess((a) => {
- if (a !== null) {
- const parsed = Number.parseInt(z.string().parse(a), 10);
- return Number.isNaN(parsed) ? null : parsed;
- }
- return null;
- }, z.number().gte(0, "Range must be 0 - 65535").lte(65535, "Range must be 0 - 65535").nullable()),
+ externalPort: z.preprocess((a) => {
+ if (a !== null) {
+ const parsed = Number.parseInt(z.string().parse(a), 10);
+ return Number.isNaN(parsed) ? null : parsed;
+ }
+ return null;
+ }, z
+ .number()
+ .gte(0, "Range must be 0 - 65535")
+ .lte(65535, "Range must be 0 - 65535")
+ .nullable()),
});
type DockerProvider = z.infer;
interface Props {
- mysqlId: string;
+ mysqlId: string;
}
export const ShowExternalMysqlCredentials = ({ mysqlId }: Props) => {
- const { data: ip } = api.settings.getIp.useQuery();
- const { data, refetch } = api.mysql.one.useQuery({ mysqlId });
- const { mutateAsync, isLoading } = api.mysql.saveExternalPort.useMutation();
- const [connectionUrl, setConnectionUrl] = useState("");
- const getIp = data?.server?.ipAddress || ip;
- const form = useForm({
- defaultValues: {},
- resolver: zodResolver(DockerProviderSchema),
- });
+ const { data: ip } = api.settings.getIp.useQuery();
+ const { data, refetch } = api.mysql.one.useQuery({ mysqlId });
+ const { mutateAsync, isLoading } = api.mysql.saveExternalPort.useMutation();
+ const [connectionUrl, setConnectionUrl] = useState("");
+ const getIp = data?.server?.ipAddress || ip;
+ const form = useForm({
+ defaultValues: {},
+ resolver: zodResolver(DockerProviderSchema),
+ });
- useEffect(() => {
- if (data?.externalPort) {
- form.reset({
- externalPort: data.externalPort,
- });
- }
- }, [form.reset, data, form]);
+ useEffect(() => {
+ if (data?.externalPort) {
+ form.reset({
+ externalPort: data.externalPort,
+ });
+ }
+ }, [form.reset, data, form]);
- const onSubmit = async (values: DockerProvider) => {
- await mutateAsync({
- externalPort: values.externalPort,
- mysqlId,
- })
- .then(async () => {
- toast.success("External Port updated");
- await refetch();
- })
- .catch(() => {
- toast.error("Error saving the external port");
- });
- };
+ const onSubmit = async (values: DockerProvider) => {
+ await mutateAsync({
+ externalPort: values.externalPort,
+ mysqlId,
+ })
+ .then(async () => {
+ toast.success("External Port updated");
+ await refetch();
+ })
+ .catch(() => {
+ toast.error("Error saving the external port");
+ });
+ };
- useEffect(() => {
- const buildConnectionUrl = () => {
- const port = form.watch("externalPort") || data?.externalPort;
+ useEffect(() => {
+ const buildConnectionUrl = () => {
+ const port = form.watch("externalPort") || data?.externalPort;
- return `mysql://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}/${data?.databaseName}`;
- };
+ return `mysql://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}/${data?.databaseName}`;
+ };
- setConnectionUrl(buildConnectionUrl());
- }, [
- data?.appName,
- data?.externalPort,
- data?.databasePassword,
- data?.databaseName,
- data?.databaseUser,
- form,
- getIp,
- ]);
- return (
- <>
-
-
-
- External Credentials
-
- In order to make the database reachable trought internet is
- required to set a port, make sure the port is not used by another
- application or database
-
-
-
- {!getIp && (
-
- You need to set an IP address in your{" "}
-
- {data?.serverId
- ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
- : "Web Server -> Server -> Update Server IP"}
- {" "}
- to fix the database url connection.
-
- )}
-
-
-
-
- {
- return (
-
- External Port (Internet)
-
-
-
-
-
- );
- }}
- />
-
-
- {!!data?.externalPort && (
-
- )}
+ setConnectionUrl(buildConnectionUrl());
+ }, [
+ data?.appName,
+ data?.externalPort,
+ data?.databasePassword,
+ data?.databaseName,
+ data?.databaseUser,
+ form,
+ getIp,
+ ]);
+ return (
+ <>
+
+
+
+ External Credentials
+
+ In order to make the database reachable trought internet is
+ required to set a port, make sure the port is not used by another
+ application or database
+
+
+
+ {!getIp && (
+
+ You need to set an IP address in your{" "}
+
+ {data?.serverId
+ ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
+ : "Web Server -> Server -> Update Server IP"}
+ {" "}
+ to fix the database url connection.
+
+ )}
+
+
+
+
+ {
+ return (
+
+ External Port (Internet)
+
+
+
+
+
+ );
+ }}
+ />
+
+
+ {!!data?.externalPort && (
+
+ )}
-
-
- Save
-
-
-
-
-
-
-
- >
- );
+
+
+ Save
+
+
+
+
+
+
+
+ >
+ );
};
diff --git a/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx b/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx
index 0c87a7bcd..444fa0cee 100644
--- a/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx
+++ b/apps/dokploy/components/dashboard/postgres/general/show-external-postgres-credentials.tsx
@@ -27,146 +27,150 @@ import { toast } from "sonner";
import { z } from "zod";
const DockerProviderSchema = z.object({
- externalPort: z.preprocess((a) => {
- if (a !== null) {
- const parsed = Number.parseInt(z.string().parse(a), 10);
- return Number.isNaN(parsed) ? null : parsed;
- }
- return null;
- }, z.number().gte(0, "Range must be 0 - 65535").lte(65535, "Range must be 0 - 65535").nullable()),
+ externalPort: z.preprocess((a) => {
+ if (a !== null) {
+ const parsed = Number.parseInt(z.string().parse(a), 10);
+ return Number.isNaN(parsed) ? null : parsed;
+ }
+ return null;
+ }, z
+ .number()
+ .gte(0, "Range must be 0 - 65535")
+ .lte(65535, "Range must be 0 - 65535")
+ .nullable()),
});
type DockerProvider = z.infer;
interface Props {
- postgresId: string;
+ postgresId: string;
}
export const ShowExternalPostgresCredentials = ({ postgresId }: Props) => {
- const { data: ip } = api.settings.getIp.useQuery();
- const { data, refetch } = api.postgres.one.useQuery({ postgresId });
- const { mutateAsync, isLoading } =
- api.postgres.saveExternalPort.useMutation();
- const getIp = data?.server?.ipAddress || ip;
- const [connectionUrl, setConnectionUrl] = useState("");
+ const { data: ip } = api.settings.getIp.useQuery();
+ const { data, refetch } = api.postgres.one.useQuery({ postgresId });
+ const { mutateAsync, isLoading } =
+ api.postgres.saveExternalPort.useMutation();
+ const getIp = data?.server?.ipAddress || ip;
+ const [connectionUrl, setConnectionUrl] = useState("");
- const form = useForm({
- defaultValues: {},
- resolver: zodResolver(DockerProviderSchema),
- });
+ const form = useForm({
+ defaultValues: {},
+ resolver: zodResolver(DockerProviderSchema),
+ });
- useEffect(() => {
- if (data?.externalPort) {
- form.reset({
- externalPort: data.externalPort,
- });
- }
- }, [form.reset, data, form]);
+ useEffect(() => {
+ if (data?.externalPort) {
+ form.reset({
+ externalPort: data.externalPort,
+ });
+ }
+ }, [form.reset, data, form]);
- const onSubmit = async (values: DockerProvider) => {
- await mutateAsync({
- externalPort: values.externalPort,
- postgresId,
- })
- .then(async () => {
- toast.success("External Port updated");
- await refetch();
- })
- .catch(() => {
- toast.error("Error saving the external port");
- });
- };
+ const onSubmit = async (values: DockerProvider) => {
+ await mutateAsync({
+ externalPort: values.externalPort,
+ postgresId,
+ })
+ .then(async () => {
+ toast.success("External Port updated");
+ await refetch();
+ })
+ .catch(() => {
+ toast.error("Error saving the external port");
+ });
+ };
- useEffect(() => {
- const buildConnectionUrl = () => {
- const port = form.watch("externalPort") || data?.externalPort;
+ useEffect(() => {
+ const buildConnectionUrl = () => {
+ const port = form.watch("externalPort") || data?.externalPort;
- return `postgresql://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}/${data?.databaseName}`;
- };
+ return `postgresql://${data?.databaseUser}:${data?.databasePassword}@${getIp}:${port}/${data?.databaseName}`;
+ };
- setConnectionUrl(buildConnectionUrl());
- }, [
- data?.appName,
- data?.externalPort,
- data?.databasePassword,
- form,
- data?.databaseName,
- getIp,
- ]);
+ setConnectionUrl(buildConnectionUrl());
+ }, [
+ data?.appName,
+ data?.externalPort,
+ data?.databasePassword,
+ form,
+ data?.databaseName,
+ getIp,
+ ]);
- return (
- <>
-
-
-
- External Credentials
-
- In order to make the database reachable trought internet is
- required to set a port, make sure the port is not used by another
- application or database
-
-
-
- {!getIp && (
-
- You need to set an IP address in your{" "}
-
- {data?.serverId
- ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
- : "Web Server -> Server -> Update Server IP"}
- {" "}
- to fix the database url connection.
-
- )}
-
-
-
-
- {
- return (
-
- External Port (Internet)
-
-
-
-
-
- );
- }}
- />
-
-
- {!!data?.externalPort && (
-
- )}
+ return (
+ <>
+
+
+
+ External Credentials
+
+ In order to make the database reachable trought internet is
+ required to set a port, make sure the port is not used by another
+ application or database
+
+
+
+ {!getIp && (
+
+ You need to set an IP address in your{" "}
+
+ {data?.serverId
+ ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
+ : "Web Server -> Server -> Update Server IP"}
+ {" "}
+ to fix the database url connection.
+
+ )}
+
+
+
+
+ {
+ return (
+
+ External Port (Internet)
+
+
+
+
+
+ );
+ }}
+ />
+
+
+ {!!data?.externalPort && (
+
+ )}
-
-
- Save
-
-
-
-
-
-
-
- >
- );
+
+
+ Save
+
+
+
+
+
+
+
+ >
+ );
};
diff --git a/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx b/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx
index cff00a998..545150f87 100644
--- a/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx
+++ b/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx
@@ -5,58 +5,58 @@ import { Label } from "@/components/ui/label";
import { api } from "@/utils/api";
interface Props {
- postgresId: string;
+ postgresId: string;
}
export const ShowInternalPostgresCredentials = ({ postgresId }: Props) => {
- const { data } = api.postgres.one.useQuery({ postgresId });
- return (
- <>
-
-
-
- Internal Credentials
-
-
-
-
- User
-
-
-
- Database Name
-
-
-
-
- Internal Port (Container)
-
-
+ const { data } = api.postgres.one.useQuery({ postgresId });
+ return (
+ <>
+
+
+
+ Internal Credentials
+
+
+
-
-
-
- >
- );
+
+ Internal Connection URL
+
+
+
+
+
+
+ >
+ );
};
// ReplyError: MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-w
diff --git a/apps/dokploy/components/dashboard/postgres/update-postgres.tsx b/apps/dokploy/components/dashboard/postgres/update-postgres.tsx
index 33ed7a60e..f70cd8c90 100644
--- a/apps/dokploy/components/dashboard/postgres/update-postgres.tsx
+++ b/apps/dokploy/components/dashboard/postgres/update-postgres.tsx
@@ -28,139 +28,139 @@ import { toast } from "sonner";
import { z } from "zod";
const updatePostgresSchema = z.object({
- name: z.string().min(1, {
- message: "Name is required",
- }),
- description: z.string().optional(),
+ name: z.string().min(1, {
+ message: "Name is required",
+ }),
+ description: z.string().optional(),
});
type UpdatePostgres = z.infer;
interface Props {
- postgresId: string;
+ postgresId: string;
}
export const UpdatePostgres = ({ postgresId }: Props) => {
- const [isOpen, setIsOpen] = useState(false);
- const utils = api.useUtils();
- const { mutateAsync, error, isError, isLoading } =
- api.postgres.update.useMutation();
- const { data } = api.postgres.one.useQuery(
- {
- postgresId,
- },
- {
- enabled: !!postgresId,
- }
- );
- const form = useForm({
- defaultValues: {
- description: data?.description ?? "",
- name: data?.name ?? "",
- },
- resolver: zodResolver(updatePostgresSchema),
- });
- useEffect(() => {
- if (data) {
- form.reset({
- description: data.description ?? "",
- name: data.name,
- });
- }
- }, [data, form, form.reset]);
+ const [isOpen, setIsOpen] = useState(false);
+ const utils = api.useUtils();
+ const { mutateAsync, error, isError, isLoading } =
+ api.postgres.update.useMutation();
+ const { data } = api.postgres.one.useQuery(
+ {
+ postgresId,
+ },
+ {
+ enabled: !!postgresId,
+ },
+ );
+ const form = useForm({
+ defaultValues: {
+ description: data?.description ?? "",
+ name: data?.name ?? "",
+ },
+ resolver: zodResolver(updatePostgresSchema),
+ });
+ useEffect(() => {
+ if (data) {
+ form.reset({
+ description: data.description ?? "",
+ name: data.name,
+ });
+ }
+ }, [data, form, form.reset]);
- const onSubmit = async (formData: UpdatePostgres) => {
- await mutateAsync({
- name: formData.name,
- postgresId: postgresId,
- description: formData.description || "",
- })
- .then(() => {
- toast.success("Postgres updated successfully");
- utils.postgres.one.invalidate({
- postgresId: postgresId,
- });
- setIsOpen(false);
- })
- .catch(() => {
- toast.error("Error updating Postgres");
- })
- .finally(() => {});
- };
+ const onSubmit = async (formData: UpdatePostgres) => {
+ await mutateAsync({
+ name: formData.name,
+ postgresId: postgresId,
+ description: formData.description || "",
+ })
+ .then(() => {
+ toast.success("Postgres updated successfully");
+ utils.postgres.one.invalidate({
+ postgresId: postgresId,
+ });
+ setIsOpen(false);
+ })
+ .catch(() => {
+ toast.error("Error updating Postgres");
+ })
+ .finally(() => {});
+ };
- return (
-
-
-
-
-
-
-
-
- Modify Postgres
- Update the Postgres data
-
- {isError && {error?.message} }
+ return (
+
+
+
+
+
+
+
+
+ Modify Postgres
+ Update the Postgres data
+
+ {isError && {error?.message} }
-
+
+
+ );
};
diff --git a/apps/dokploy/components/dashboard/projects/show.tsx b/apps/dokploy/components/dashboard/projects/show.tsx
index f55661433..31ba80c8f 100644
--- a/apps/dokploy/components/dashboard/projects/show.tsx
+++ b/apps/dokploy/components/dashboard/projects/show.tsx
@@ -186,7 +186,9 @@ export const ShowProjects = () => {
target="_blank"
href={`${domain.https ? "https" : "http"}://${domain.host}${domain.path}`}
>
- {domain.host}
+
+ {domain.host}
+
@@ -222,7 +224,9 @@ export const ShowProjects = () => {
target="_blank"
href={`${domain.https ? "https" : "http"}://${domain.host}${domain.path}`}
>
- {domain.host}
+
+ {domain.host}
+
diff --git a/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx b/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx
index 75b5478aa..46cb09530 100644
--- a/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx
+++ b/apps/dokploy/components/dashboard/redis/general/show-external-redis-credentials.tsx
@@ -27,138 +27,142 @@ import { toast } from "sonner";
import { z } from "zod";
const DockerProviderSchema = z.object({
- externalPort: z.preprocess((a) => {
- if (a !== null) {
- const parsed = Number.parseInt(z.string().parse(a), 10);
- return Number.isNaN(parsed) ? null : parsed;
- }
- return null;
- }, z.number().gte(0, "Range must be 0 - 65535").lte(65535, "Range must be 0 - 65535").nullable()),
+ externalPort: z.preprocess((a) => {
+ if (a !== null) {
+ const parsed = Number.parseInt(z.string().parse(a), 10);
+ return Number.isNaN(parsed) ? null : parsed;
+ }
+ return null;
+ }, z
+ .number()
+ .gte(0, "Range must be 0 - 65535")
+ .lte(65535, "Range must be 0 - 65535")
+ .nullable()),
});
type DockerProvider = z.infer;
interface Props {
- redisId: string;
+ redisId: string;
}
export const ShowExternalRedisCredentials = ({ redisId }: Props) => {
- const { data: ip } = api.settings.getIp.useQuery();
- const { data, refetch } = api.redis.one.useQuery({ redisId });
- const { mutateAsync, isLoading } = api.redis.saveExternalPort.useMutation();
- const [connectionUrl, setConnectionUrl] = useState("");
- const getIp = data?.server?.ipAddress || ip;
+ const { data: ip } = api.settings.getIp.useQuery();
+ const { data, refetch } = api.redis.one.useQuery({ redisId });
+ const { mutateAsync, isLoading } = api.redis.saveExternalPort.useMutation();
+ const [connectionUrl, setConnectionUrl] = useState("");
+ const getIp = data?.server?.ipAddress || ip;
- const form = useForm({
- defaultValues: {},
- resolver: zodResolver(DockerProviderSchema),
- });
+ const form = useForm({
+ defaultValues: {},
+ resolver: zodResolver(DockerProviderSchema),
+ });
- useEffect(() => {
- if (data?.externalPort) {
- form.reset({
- externalPort: data.externalPort,
- });
- }
- }, [form.reset, data, form]);
+ useEffect(() => {
+ if (data?.externalPort) {
+ form.reset({
+ externalPort: data.externalPort,
+ });
+ }
+ }, [form.reset, data, form]);
- const onSubmit = async (values: DockerProvider) => {
- await mutateAsync({
- externalPort: values.externalPort,
- redisId,
- })
- .then(async () => {
- toast.success("External Port updated");
- await refetch();
- })
- .catch(() => {
- toast.error("Error saving the external port");
- });
- };
+ const onSubmit = async (values: DockerProvider) => {
+ await mutateAsync({
+ externalPort: values.externalPort,
+ redisId,
+ })
+ .then(async () => {
+ toast.success("External Port updated");
+ await refetch();
+ })
+ .catch(() => {
+ toast.error("Error saving the external port");
+ });
+ };
- useEffect(() => {
- const buildConnectionUrl = () => {
- const _hostname = window.location.hostname;
- const port = form.watch("externalPort") || data?.externalPort;
+ useEffect(() => {
+ const buildConnectionUrl = () => {
+ const _hostname = window.location.hostname;
+ const port = form.watch("externalPort") || data?.externalPort;
- return `redis://default:${data?.databasePassword}@${getIp}:${port}`;
- };
+ return `redis://default:${data?.databasePassword}@${getIp}:${port}`;
+ };
- setConnectionUrl(buildConnectionUrl());
- }, [data?.appName, data?.externalPort, data?.databasePassword, form, getIp]);
- return (
- <>
-
-
-
- External Credentials
-
- In order to make the database reachable trought internet is
- required to set a port, make sure the port is not used by another
- application or database
-
-
-
- {!getIp && (
-
- You need to set an IP address in your{" "}
-
- {data?.serverId
- ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
- : "Web Server -> Server -> Update Server IP"}
- {" "}
- to fix the database url connection.
-
- )}
-
-
-
-
- {
- return (
-
- External Port (Internet)
-
-
-
-
-
- );
- }}
- />
-
-
- {!!data?.externalPort && (
-
- )}
+ setConnectionUrl(buildConnectionUrl());
+ }, [data?.appName, data?.externalPort, data?.databasePassword, form, getIp]);
+ return (
+ <>
+
+
+
+ External Credentials
+
+ In order to make the database reachable trought internet is
+ required to set a port, make sure the port is not used by another
+ application or database
+
+
+
+ {!getIp && (
+
+ You need to set an IP address in your{" "}
+
+ {data?.serverId
+ ? "Remote Servers -> Server -> Edit Server -> Update IP Address"
+ : "Web Server -> Server -> Update Server IP"}
+ {" "}
+ to fix the database url connection.
+
+ )}
+
+
+
+
+ {
+ return (
+
+ External Port (Internet)
+
+
+
+
+
+ );
+ }}
+ />
+
+
+ {!!data?.externalPort && (
+
+ )}
-
-
- Save
-
-
-
-
-
-
-
- >
- );
+
+
+ Save
+
+
+
+
+
+
+
+ >
+ );
};
diff --git a/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx b/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx
index d20b7c91a..dd9839e3d 100644
--- a/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx
+++ b/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx
@@ -161,7 +161,11 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
{...field}
onChange={(e) => {
const value = e.target.value;
- field.onChange(value === "" ? undefined : Number(value));
+ field.onChange(
+ value === ""
+ ? undefined
+ : Number(value),
+ );
}}
value={field.value || ""}
className="w-full dark:bg-black"
@@ -189,7 +193,11 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
{...field}
onChange={(e) => {
const value = e.target.value;
- field.onChange(value === "" ? undefined : Number(value));
+ field.onChange(
+ value === ""
+ ? undefined
+ : Number(value),
+ );
}}
value={field.value || ""}
className="w-full dark:bg-black"
diff --git a/apps/dokploy/components/shared/breadcrumb-sidebar.tsx b/apps/dokploy/components/shared/breadcrumb-sidebar.tsx
index 5f6add3ec..f9448733a 100644
--- a/apps/dokploy/components/shared/breadcrumb-sidebar.tsx
+++ b/apps/dokploy/components/shared/breadcrumb-sidebar.tsx
@@ -37,7 +37,9 @@ export const BreadcrumbSidebar = ({ list }: Props) => {
)}
- {_index + 1 < list.length && }
+ {_index + 1 < list.length && (
+
+ )}
))}
diff --git a/apps/dokploy/next.config.mjs b/apps/dokploy/next.config.mjs
index 016bc13df..1ebd4f22a 100644
--- a/apps/dokploy/next.config.mjs
+++ b/apps/dokploy/next.config.mjs
@@ -5,23 +5,23 @@
/** @type {import("next").NextConfig} */
const nextConfig = {
- reactStrictMode: true,
- eslint: {
- ignoreDuringBuilds: true,
- },
- typescript: {
- ignoreBuildErrors: true,
- },
- transpilePackages: ["@dokploy/server"],
- /**
- * If you are using `appDir` then you must comment the below `i18n` config out.
- *
- * @see https://github.com/vercel/next.js/issues/41980
- */
- i18n: {
- locales: ["en"],
- defaultLocale: "en",
- },
+ reactStrictMode: true,
+ eslint: {
+ ignoreDuringBuilds: true,
+ },
+ typescript: {
+ ignoreBuildErrors: true,
+ },
+ transpilePackages: ["@dokploy/server"],
+ /**
+ * If you are using `appDir` then you must comment the below `i18n` config out.
+ *
+ * @see https://github.com/vercel/next.js/issues/41980
+ */
+ i18n: {
+ locales: ["en"],
+ defaultLocale: "en",
+ },
};
export default nextConfig;
From 8b03454a8709198cd34ddea110f009ca861b014e Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:28:50 -0600
Subject: [PATCH 05/12] chore(workflow): update Biome workflow to push changes
to the correct branch
---
.github/workflows/biome.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml
index f3cf0f16b..9e1f21c32 100644
--- a/.github/workflows/biome.yml
+++ b/.github/workflows/biome.yml
@@ -31,8 +31,8 @@ jobs:
- name: Commit changes if needed
run: |
- git config --global user.name 'github-actions[bot]'
- git config --global user.email 'github-actions[bot]@users.noreply.github.com'
- git add .
- git diff --quiet && git diff --staged --quiet || git commit -m "chore: auto-format with Biome"
- git push
+ BRANCH=$(echo "${{ github.head_ref || github.ref_name }}")
+ git add .
+ git diff --quiet && git diff --staged --quiet || git commit -m "chore: auto-format with Biome"
+ git push origin HEAD:$BRANCH
+
From ca42708035acba11f3ed1edff88813858b864669 Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:30:18 -0600
Subject: [PATCH 06/12] chore(workflow): configure git user for automated
commits and enforce push
---
.github/workflows/biome.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml
index 9e1f21c32..b94ed58df 100644
--- a/.github/workflows/biome.yml
+++ b/.github/workflows/biome.yml
@@ -32,7 +32,8 @@ jobs:
- name: Commit changes if needed
run: |
BRANCH=$(echo "${{ github.head_ref || github.ref_name }}")
+ git config --global user.name 'github-actions[bot]'
+ git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add .
git diff --quiet && git diff --staged --quiet || git commit -m "chore: auto-format with Biome"
- git push origin HEAD:$BRANCH
-
+ git push origin HEAD:$BRANCH --force
From 8eb174812da08244d88709031b8a6c29e14fb28a Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:35:50 -0600
Subject: [PATCH 07/12] chore(workflow): replace manual commit step with
AutoFix action for Biome formatting
---
.github/workflows/biome.yml | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml
index b94ed58df..b5a6648f5 100644
--- a/.github/workflows/biome.yml
+++ b/.github/workflows/biome.yml
@@ -29,11 +29,5 @@ jobs:
- name: Run Biome formatter
run: pnpm biome format . --write
- - name: Commit changes if needed
- run: |
- BRANCH=$(echo "${{ github.head_ref || github.ref_name }}")
- git config --global user.name 'github-actions[bot]'
- git config --global user.email 'github-actions[bot]@users.noreply.github.com'
- git add .
- git diff --quiet && git diff --staged --quiet || git commit -m "chore: auto-format with Biome"
- git push origin HEAD:$BRANCH --force
+ - name: AutoFix
+ uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
From 9f096817085b182fb9fc1e03c49f20bcfef85652 Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:37:01 -0600
Subject: [PATCH 08/12] chore(workflow): streamline Biome setup by replacing
Node.js and pnpm steps with biomeJs action
---
.github/workflows/biome.yml | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml
index b5a6648f5..9358caa04 100644
--- a/.github/workflows/biome.yml
+++ b/.github/workflows/biome.yml
@@ -13,21 +13,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: 20
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v4
- with:
- version: 9.5.0
-
- - name: Install dependencies
- run: pnpm install
+ - name: Setup biomeJs
+ uses: biomejs/setup-biome@v2
- name: Run Biome formatter
- run: pnpm biome format . --write
+ run: biome format . --write
- name: AutoFix
uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
From 413eda50f473b6519a3e7d6f5eaea3c7bbef726c Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:37:43 -0600
Subject: [PATCH 09/12] chore(workflow): simplify AutoFix action usage in Biome
workflow
---
.github/workflows/biome.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml
index 9358caa04..acdb11b79 100644
--- a/.github/workflows/biome.yml
+++ b/.github/workflows/biome.yml
@@ -19,5 +19,4 @@ jobs:
- name: Run Biome formatter
run: biome format . --write
- - name: AutoFix
- uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
+ - uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
From 4ba2b9fe8d003fcb0414469ed7025634b8e6aa30 Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:38:55 -0600
Subject: [PATCH 10/12] chore(workflow): add new Biome formatting workflow for
canary branch
---
.github/workflows/{biome.yml => autofix.yml} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename .github/workflows/{biome.yml => autofix.yml} (100%)
diff --git a/.github/workflows/biome.yml b/.github/workflows/autofix.yml
similarity index 100%
rename from .github/workflows/biome.yml
rename to .github/workflows/autofix.yml
From 74f7c515308c1e9dcd39aa2459198ae2159d163f Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:39:57 -0600
Subject: [PATCH 11/12] chore(workflow): add autofix.ci workflow for automatic
code formatting with Biome
---
.github/workflows/{autofix.yml => autofix.ci} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename .github/workflows/{autofix.yml => autofix.ci} (100%)
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.ci
similarity index 100%
rename from .github/workflows/autofix.yml
rename to .github/workflows/autofix.ci
From b1ef9d25b1e108ba9fb52b78a67d55795c8772be Mon Sep 17 00:00:00 2001
From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
Date: Sat, 29 Mar 2025 13:41:05 -0600
Subject: [PATCH 12/12] chore(workflow): add autofix.ci workflow for automatic
code formatting on canary branch
---
.github/workflows/{autofix.ci => format.yml} | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename .github/workflows/{autofix.ci => format.yml} (93%)
diff --git a/.github/workflows/autofix.ci b/.github/workflows/format.yml
similarity index 93%
rename from .github/workflows/autofix.ci
rename to .github/workflows/format.yml
index acdb11b79..827ccc709 100644
--- a/.github/workflows/autofix.ci
+++ b/.github/workflows/format.yml
@@ -1,4 +1,4 @@
-name: Format Code with Biome
+name: autofix.ci
on:
push: