-
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 219e4218..5b963a4c 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 9f5b63c3..c00af42b 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 b5ed9f86..75772bfd 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 2c8ed5f5..73f99b7d 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 0c87a7bc..444fa0ce 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 cff00a99..545150f8 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 33ed7a60..f70cd8c9 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 f5566143..31ba80c8 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 75b5478a..46cb0953 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 d20b7c91..dd9839e3 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 5f6add3e..f9448733 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 016bc13d..1ebd4f22 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 f3cf0f16..9e1f21c3 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 9e1f21c3..b94ed58d 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 b94ed58d..b5a6648f 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 b5a6648f..9358caa0 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 9358caa0..acdb11b7 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 acdb11b7..827ccc70 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: