mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge branch 'canary' into 379-preview-deployment
This commit is contained in:
@@ -241,7 +241,7 @@ export function generate(schema: Schema): Template {
|
||||
|
||||
- Use the same name of the folder as the id of the template.
|
||||
- The logo should be in the public folder.
|
||||
- If you want to show a domain in the UI, please add the prefix \_HOST at the end of the variable name.
|
||||
- If you want to show a domain in the UI, please add the `_HOST` suffix at the end of the variable name.
|
||||
- Test first on a vps or a server to make sure the template works.
|
||||
|
||||
## Docs & Website
|
||||
|
||||
@@ -35,7 +35,6 @@ RUN apt-get update && apt-get install -y curl unzip apache2-utils && rm -rf /var
|
||||
COPY --from=build /prod/dokploy/.next ./.next
|
||||
COPY --from=build /prod/dokploy/dist ./dist
|
||||
COPY --from=build /prod/dokploy/next.config.mjs ./next.config.mjs
|
||||
COPY --from=build /prod/dokploy/next-i18next.config.cjs ./next-i18next.config.cjs
|
||||
COPY --from=build /prod/dokploy/public ./public
|
||||
COPY --from=build /prod/dokploy/package.json ./package.json
|
||||
COPY --from=build /prod/dokploy/drizzle ./drizzle
|
||||
|
||||
@@ -44,7 +44,6 @@ RUN apt-get update && apt-get install -y curl unzip apache2-utils && rm -rf /var
|
||||
COPY --from=build /prod/dokploy/.next ./.next
|
||||
COPY --from=build /prod/dokploy/dist ./dist
|
||||
COPY --from=build /prod/dokploy/next.config.mjs ./next.config.mjs
|
||||
COPY --from=build /prod/dokploy/next-i18next.config.cjs ./next-i18next.config.cjs
|
||||
COPY --from=build /prod/dokploy/public ./public
|
||||
COPY --from=build /prod/dokploy/package.json ./package.json
|
||||
COPY --from=build /prod/dokploy/drizzle ./drizzle
|
||||
|
||||
@@ -26,6 +26,7 @@ if (typeof window === "undefined") {
|
||||
|
||||
const baseApp: ApplicationNested = {
|
||||
applicationId: "",
|
||||
herokuVersion: "",
|
||||
applicationStatus: "done",
|
||||
appName: "",
|
||||
autoDeploy: true,
|
||||
|
||||
@@ -6,6 +6,7 @@ import { expect, test } from "vitest";
|
||||
|
||||
const baseApp: ApplicationNested = {
|
||||
applicationId: "",
|
||||
herokuVersion: "",
|
||||
applicationStatus: "done",
|
||||
appName: "",
|
||||
autoDeploy: true,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CodeEditor } from "@/components/shared/code-editor";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
@@ -18,7 +19,6 @@ import {
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { api } from "@/utils/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
@@ -150,7 +150,7 @@ export const AddVolumes = ({
|
||||
<DialogTrigger className="" asChild>
|
||||
<Button>{children}</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-2xl">
|
||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-3xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Volumes / Mounts</DialogTitle>
|
||||
</DialogHeader>
|
||||
@@ -303,9 +303,12 @@ export const AddVolumes = ({
|
||||
<FormLabel>Content</FormLabel>
|
||||
<FormControl>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="Any content"
|
||||
className="h-64"
|
||||
<CodeEditor
|
||||
language="properties"
|
||||
placeholder={`NODE_ENV=production
|
||||
PORT=3000
|
||||
`}
|
||||
className="h-96 font-mono"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { AlertBlock } from "@/components/shared/alert-block";
|
||||
import { CodeEditor } from "@/components/shared/code-editor";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
@@ -19,7 +19,6 @@ import {
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { api } from "@/utils/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Pencil } from "lucide-react";
|
||||
@@ -119,7 +118,7 @@ export const UpdateVolume = ({
|
||||
} else if (typeForm === "file") {
|
||||
form.reset({
|
||||
content: data.content || "",
|
||||
mountPath: "/",
|
||||
mountPath: serviceType === "compose" ? "/" : data.mountPath,
|
||||
filePath: data.filePath || "",
|
||||
type: "file",
|
||||
});
|
||||
@@ -182,7 +181,7 @@ export const UpdateVolume = ({
|
||||
<Pencil className="size-4 text-muted-foreground" />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-lg">
|
||||
<DialogContent className="max-h-screen overflow-y-auto sm:max-w-3xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Update</DialogTitle>
|
||||
<DialogDescription>Update the mount</DialogDescription>
|
||||
@@ -247,9 +246,12 @@ export const UpdateVolume = ({
|
||||
<FormLabel>Content</FormLabel>
|
||||
<FormControl>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="Any content"
|
||||
className="h-64"
|
||||
<CodeEditor
|
||||
language="properties"
|
||||
placeholder={`NODE_ENV=production
|
||||
PORT=3000
|
||||
`}
|
||||
className="h-96 font-mono"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
@@ -41,6 +41,7 @@ const mySchema = z.discriminatedUnion("buildType", [
|
||||
}),
|
||||
z.object({
|
||||
buildType: z.literal("heroku_buildpacks"),
|
||||
herokuVersion: z.string().nullable().default(""),
|
||||
}),
|
||||
z.object({
|
||||
buildType: z.literal("paketo_buildpacks"),
|
||||
@@ -90,6 +91,13 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
dockerBuildStage: data.dockerBuildStage || "",
|
||||
}),
|
||||
});
|
||||
} else if (data.buildType === "heroku_buildpacks") {
|
||||
form.reset({
|
||||
buildType: data.buildType,
|
||||
...(data.buildType && {
|
||||
herokuVersion: data.herokuVersion || "",
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
form.reset({
|
||||
buildType: data.buildType,
|
||||
@@ -110,6 +118,8 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
data.buildType === "dockerfile" ? data.dockerContextPath : null,
|
||||
dockerBuildStage:
|
||||
data.buildType === "dockerfile" ? data.dockerBuildStage : null,
|
||||
herokuVersion:
|
||||
data.buildType === "heroku_buildpacks" ? data.herokuVersion : null,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Build type saved");
|
||||
@@ -200,6 +210,28 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
{buildType === "heroku_buildpacks" && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="herokuVersion"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem>
|
||||
<FormLabel>Heroku Version (Optional)</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={"Heroku Version (Default: 24)"}
|
||||
{...field}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{buildType === "dockerfile" && (
|
||||
<>
|
||||
<FormField
|
||||
|
||||
@@ -2,9 +2,9 @@ import { ShowBuildChooseForm } from "@/components/dashboard/application/build/sh
|
||||
import { ShowProviderForm } from "@/components/dashboard/application/general/generic/show";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Toggle } from "@/components/ui/toggle";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { api } from "@/utils/api";
|
||||
import { CheckCircle2, Terminal } from "lucide-react";
|
||||
import { Terminal } from "lucide-react";
|
||||
import React from "react";
|
||||
import { toast } from "sonner";
|
||||
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
||||
@@ -39,27 +39,6 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
||||
appName={data?.appName || ""}
|
||||
/>
|
||||
|
||||
<Toggle
|
||||
aria-label="Toggle italic"
|
||||
pressed={data?.autoDeploy || false}
|
||||
onPressedChange={async (enabled) => {
|
||||
await update({
|
||||
applicationId,
|
||||
autoDeploy: enabled,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Auto Deploy Updated");
|
||||
await refetch();
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to update Auto Deploy");
|
||||
});
|
||||
}}
|
||||
className="flex flex-row gap-2 items-center"
|
||||
>
|
||||
Autodeploy
|
||||
{data?.autoDeploy && <CheckCircle2 className="size-4" />}
|
||||
</Toggle>
|
||||
<RedbuildApplication applicationId={applicationId} />
|
||||
{data?.applicationStatus === "idle" ? (
|
||||
<StartApplication applicationId={applicationId} />
|
||||
@@ -75,6 +54,27 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
||||
Open Terminal
|
||||
</Button>
|
||||
</DockerTerminalModal>
|
||||
<div className="flex flex-row items-center gap-2 rounded-md px-4 py-2 border">
|
||||
<span className="text-sm font-medium">Autodeploy</span>
|
||||
<Switch
|
||||
aria-label="Toggle italic"
|
||||
checked={data?.autoDeploy || false}
|
||||
onCheckedChange={async (enabled) => {
|
||||
await update({
|
||||
applicationId,
|
||||
autoDeploy: enabled,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Auto Deploy Updated");
|
||||
await refetch();
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to update Auto Deploy");
|
||||
});
|
||||
}}
|
||||
className="flex flex-row gap-2 items-center"
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<ShowProviderForm applicationId={applicationId} />
|
||||
|
||||
@@ -8,12 +8,13 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Toggle } from "@/components/ui/toggle";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { api } from "@/utils/api";
|
||||
import { CheckCircle2, ExternalLink, Globe, Terminal } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { toast } from "sonner";
|
||||
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
||||
import { StartCompose } from "../start-compose";
|
||||
import { DeployCompose } from "./deploy-compose";
|
||||
import { RedbuildCompose } from "./rebuild-compose";
|
||||
import { StopCompose } from "./stop-compose";
|
||||
@@ -50,28 +51,11 @@ export const ComposeActions = ({ composeId }: Props) => {
|
||||
return (
|
||||
<div className="flex flex-row gap-4 w-full flex-wrap ">
|
||||
<DeployCompose composeId={composeId} />
|
||||
<Toggle
|
||||
aria-label="Toggle italic"
|
||||
pressed={data?.autoDeploy || false}
|
||||
onPressedChange={async (enabled) => {
|
||||
await update({
|
||||
composeId,
|
||||
autoDeploy: enabled,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Auto Deploy Updated");
|
||||
await refetch();
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to update Auto Deploy");
|
||||
});
|
||||
}}
|
||||
className="flex flex-row gap-2 items-center"
|
||||
>
|
||||
Autodeploy {data?.autoDeploy && <CheckCircle2 className="size-4" />}
|
||||
</Toggle>
|
||||
<RedbuildCompose composeId={composeId} />
|
||||
{data?.composeType === "docker-compose" && (
|
||||
{data?.composeType === "docker-compose" &&
|
||||
data?.composeStatus === "idle" ? (
|
||||
<StartCompose composeId={composeId} />
|
||||
) : (
|
||||
<StopCompose composeId={composeId} />
|
||||
)}
|
||||
|
||||
@@ -84,6 +68,27 @@ export const ComposeActions = ({ composeId }: Props) => {
|
||||
Open Terminal
|
||||
</Button>
|
||||
</DockerTerminalModal>
|
||||
<div className="flex flex-row items-center gap-2 rounded-md px-4 py-2 border">
|
||||
<span className="text-sm font-medium">Autodeploy</span>
|
||||
<Switch
|
||||
aria-label="Toggle italic"
|
||||
checked={data?.autoDeploy || false}
|
||||
onCheckedChange={async (enabled) => {
|
||||
await update({
|
||||
composeId,
|
||||
autoDeploy: enabled,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Auto Deploy Updated");
|
||||
await refetch();
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to update Auto Deploy");
|
||||
});
|
||||
}}
|
||||
className="flex flex-row gap-2 items-center"
|
||||
/>
|
||||
</div>
|
||||
{domains.length > 0 && (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
||||
65
apps/dokploy/components/dashboard/compose/start-compose.tsx
Normal file
65
apps/dokploy/components/dashboard/compose/start-compose.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { api } from "@/utils/api";
|
||||
import { CheckCircle2 } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface Props {
|
||||
composeId: string;
|
||||
}
|
||||
|
||||
export const StartCompose = ({ composeId }: Props) => {
|
||||
const { mutateAsync, isLoading } = api.compose.start.useMutation();
|
||||
const utils = api.useUtils();
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="secondary" isLoading={isLoading}>
|
||||
Start
|
||||
<CheckCircle2 className="size-4" />
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
Are you sure to start the compose?
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will start the compose
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={async () => {
|
||||
await mutateAsync({
|
||||
composeId,
|
||||
})
|
||||
.then(async () => {
|
||||
await utils.compose.one.invalidate({
|
||||
composeId,
|
||||
});
|
||||
toast.success("Compose started succesfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to start the Compose");
|
||||
});
|
||||
}}
|
||||
>
|
||||
Confirm
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
);
|
||||
};
|
||||
65
apps/dokploy/components/dashboard/compose/stop-compose.tsx
Normal file
65
apps/dokploy/components/dashboard/compose/stop-compose.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { api } from "@/utils/api";
|
||||
import { Ban } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface Props {
|
||||
composeId: string;
|
||||
}
|
||||
|
||||
export const StopCompose = ({ composeId }: Props) => {
|
||||
const { mutateAsync, isLoading } = api.compose.stop.useMutation();
|
||||
const utils = api.useUtils();
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive" isLoading={isLoading}>
|
||||
Stop
|
||||
<Ban className="size-4" />
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
Are you absolutely sure to stop the compose?
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will stop the compose
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={async () => {
|
||||
await mutateAsync({
|
||||
composeId,
|
||||
})
|
||||
.then(async () => {
|
||||
await utils.compose.one.invalidate({
|
||||
composeId,
|
||||
});
|
||||
toast.success("Compose stopped succesfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to stop the Compose");
|
||||
});
|
||||
}}
|
||||
>
|
||||
Confirm
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
);
|
||||
};
|
||||
@@ -1,13 +1,16 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useState } from "react";
|
||||
|
||||
const Terminal = dynamic(
|
||||
() => import("./docker-terminal").then((e) => e.DockerTerminal),
|
||||
@@ -27,8 +30,27 @@ export const DockerTerminalModal = ({
|
||||
containerId,
|
||||
serverId,
|
||||
}: Props) => {
|
||||
const [mainDialogOpen, setMainDialogOpen] = useState(false);
|
||||
const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
|
||||
|
||||
const handleMainDialogOpenChange = (open: boolean) => {
|
||||
if (!open) {
|
||||
setConfirmDialogOpen(true);
|
||||
} else {
|
||||
setMainDialogOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
setConfirmDialogOpen(false);
|
||||
setMainDialogOpen(false);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setConfirmDialogOpen(false);
|
||||
};
|
||||
return (
|
||||
<Dialog>
|
||||
<Dialog open={mainDialogOpen} onOpenChange={handleMainDialogOpenChange}>
|
||||
<DialogTrigger asChild>
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer space-x-3"
|
||||
@@ -50,6 +72,24 @@ export const DockerTerminalModal = ({
|
||||
containerId={containerId}
|
||||
serverId={serverId || ""}
|
||||
/>
|
||||
<Dialog open={confirmDialogOpen} onOpenChange={setConfirmDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Are you sure you want to close the terminal?
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
By clicking the confirm button, the terminal will be closed.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={handleCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleConfirm}>Confirm</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -49,8 +49,11 @@ export const columns: ColumnDef<LogEntry>[] = [
|
||||
const log = row.original;
|
||||
return (
|
||||
<div className=" flex flex-col gap-2">
|
||||
<div className="flex flex-row gap-3 ">
|
||||
<div className="flex items-center flex-row gap-3 ">
|
||||
{log.RequestMethod}{" "}
|
||||
<div className="inline-flex items-center gap-2 bg-muted p-1 rounded">
|
||||
<span>{log.RequestAddr}</span>
|
||||
</div>
|
||||
{log.RequestPath.length > 100
|
||||
? `${log.RequestPath.slice(0, 82)}...`
|
||||
: log.RequestPath}
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Languages } from "@/lib/languages";
|
||||
import useLocale from "@/utils/hooks/use-locale";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useTheme } from "next-themes";
|
||||
@@ -37,12 +38,9 @@ const appearanceFormSchema = z.object({
|
||||
theme: z.enum(["light", "dark", "system"], {
|
||||
required_error: "Please select a theme.",
|
||||
}),
|
||||
language: z.enum(
|
||||
["en", "pl", "ru", "fr", "de", "tr", "zh-Hant", "zh-Hans", "fa"],
|
||||
{
|
||||
required_error: "Please select a language.",
|
||||
},
|
||||
),
|
||||
language: z.nativeEnum(Languages, {
|
||||
required_error: "Please select a language.",
|
||||
}),
|
||||
});
|
||||
|
||||
type AppearanceFormValues = z.infer<typeof appearanceFormSchema>;
|
||||
@@ -50,7 +48,7 @@ type AppearanceFormValues = z.infer<typeof appearanceFormSchema>;
|
||||
// This can come from your database or API.
|
||||
const defaultValues: Partial<AppearanceFormValues> = {
|
||||
theme: "system",
|
||||
language: "en",
|
||||
language: Languages.English,
|
||||
};
|
||||
|
||||
export function AppearanceForm() {
|
||||
@@ -175,24 +173,15 @@ export function AppearanceForm() {
|
||||
<SelectValue placeholder="No preset selected" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{[
|
||||
{ label: "English", value: "en" },
|
||||
{ label: "Polski", value: "pl" },
|
||||
{ label: "Русский", value: "ru" },
|
||||
{ label: "Français", value: "fr" },
|
||||
{ label: "Deutsch", value: "de" },
|
||||
{ label: "繁體中文", value: "zh-Hant" },
|
||||
{ label: "简体中文", value: "zh-Hans" },
|
||||
{ label: "Türkçe", value: "tr" },
|
||||
{
|
||||
label: "Persian",
|
||||
value: "fa",
|
||||
},
|
||||
].map((preset) => (
|
||||
<SelectItem key={preset.label} value={preset.value}>
|
||||
{preset.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
{Object.keys(Languages).map((preset) => {
|
||||
const value =
|
||||
Languages[preset as keyof typeof Languages];
|
||||
return (
|
||||
<SelectItem key={value} value={value}>
|
||||
{preset}
|
||||
</SelectItem>
|
||||
);
|
||||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormItem>
|
||||
|
||||
@@ -667,7 +667,7 @@ export const AddNotification = () => {
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel>Dokploy Restart</FormLabel>
|
||||
<FormDescription>
|
||||
Trigger the action when a dokploy is restarted.
|
||||
Trigger the action when dokploy is restarted.
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
@@ -49,14 +51,34 @@ export const DockerTerminalModal = ({ children, appName, serverId }: Props) => {
|
||||
},
|
||||
);
|
||||
const [containerId, setContainerId] = useState<string | undefined>();
|
||||
const [mainDialogOpen, setMainDialogOpen] = useState(false);
|
||||
const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
|
||||
|
||||
const handleMainDialogOpenChange = (open: boolean) => {
|
||||
if (!open) {
|
||||
setConfirmDialogOpen(true);
|
||||
} else {
|
||||
setMainDialogOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
setConfirmDialogOpen(false);
|
||||
setMainDialogOpen(false);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setConfirmDialogOpen(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (data && data?.length > 0) {
|
||||
setContainerId(data[0]?.containerId);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Dialog>
|
||||
<Dialog open={mainDialogOpen} onOpenChange={handleMainDialogOpenChange}>
|
||||
<DialogTrigger asChild>{children}</DialogTrigger>
|
||||
<DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-7xl">
|
||||
<DialogHeader>
|
||||
@@ -96,6 +118,24 @@ export const DockerTerminalModal = ({ children, appName, serverId }: Props) => {
|
||||
id="terminal"
|
||||
containerId={containerId || "select-a-container"}
|
||||
/>
|
||||
<Dialog open={confirmDialogOpen} onOpenChange={setConfirmDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Are you sure you want to close the terminal?
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
By clicking the confirm button, the terminal will be closed.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={handleCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleConfirm}>Confirm</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import * as SwitchPrimitives from "@radix-ui/react-switch";
|
||||
import * as React from "react";
|
||||
|
||||
@@ -9,7 +11,7 @@ const Switch = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SwitchPrimitives.Root
|
||||
className={cn(
|
||||
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
||||
"peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -17,7 +19,7 @@ const Switch = React.forwardRef<
|
||||
>
|
||||
<SwitchPrimitives.Thumb
|
||||
className={cn(
|
||||
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
|
||||
"pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0",
|
||||
)}
|
||||
/>
|
||||
</SwitchPrimitives.Root>
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
ALTER TYPE "domainType" ADD VALUE 'preview';--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "preview_deployments" (
|
||||
"previewDeploymentId" text PRIMARY KEY NOT NULL,
|
||||
"branch" text NOT NULL,
|
||||
"pullRequestId" text NOT NULL,
|
||||
"pullRequestNumber" text NOT NULL,
|
||||
"pullRequestURL" text NOT NULL,
|
||||
"pullRequestTitle" text NOT NULL,
|
||||
"pullRequestCommentId" text NOT NULL,
|
||||
"appName" text NOT NULL,
|
||||
"applicationId" text NOT NULL,
|
||||
"domainId" text,
|
||||
"deploymentId" text,
|
||||
"createdAt" text NOT NULL,
|
||||
"expiresAt" text,
|
||||
CONSTRAINT "preview_deployments_appName_unique" UNIQUE("appName")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewEnv" text;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewBuildArgs" text;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewWildcard" text;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewPort" integer DEFAULT 3000;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewHttps" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewPath" text DEFAULT '/';--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "certificateType" "certificateType" DEFAULT 'none' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "previewLimit" integer DEFAULT 3;--> statement-breakpoint
|
||||
ALTER TABLE "application" ADD COLUMN "isPreviewDeploymentsActive" boolean DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "domain" ADD COLUMN "isPreviewDeployment" boolean DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "domain" ADD COLUMN "previewDeploymentId" text;--> statement-breakpoint
|
||||
ALTER TABLE "deployment" ADD COLUMN "isPreviewDeployment" boolean DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "deployment" ADD COLUMN "previewDeploymentId" text;--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "preview_deployments" ADD CONSTRAINT "preview_deployments_applicationId_application_applicationId_fk" FOREIGN KEY ("applicationId") REFERENCES "public"."application"("applicationId") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "preview_deployments" ADD CONSTRAINT "preview_deployments_domainId_domain_domainId_fk" FOREIGN KEY ("domainId") REFERENCES "public"."domain"("domainId") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "preview_deployments" ADD CONSTRAINT "preview_deployments_deploymentId_deployment_deploymentId_fk" FOREIGN KEY ("deploymentId") REFERENCES "public"."deployment"("deploymentId") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "domain" ADD CONSTRAINT "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk" FOREIGN KEY ("previewDeploymentId") REFERENCES "public"."preview_deployments"("previewDeploymentId") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "deployment" ADD CONSTRAINT "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk" FOREIGN KEY ("previewDeploymentId") REFERENCES "public"."preview_deployments"("previewDeploymentId") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
1
apps/dokploy/drizzle/0047_tidy_revanche.sql
Normal file
1
apps/dokploy/drizzle/0047_tidy_revanche.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "application" ADD COLUMN "herokuVersion" text;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE "preview_deployments" ADD COLUMN "previewStatus" "applicationStatus" DEFAULT 'idle' NOT NULL;
|
||||
1
apps/dokploy/drizzle/0048_flat_expediter.sql
Normal file
1
apps/dokploy/drizzle/0048_flat_expediter.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "application" ALTER COLUMN "herokuVersion" SET DEFAULT '24';
|
||||
1
apps/dokploy/drizzle/0049_overrated_sage.sql
Normal file
1
apps/dokploy/drizzle/0049_overrated_sage.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "application" ADD COLUMN "herokuVersion" text DEFAULT '24';
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE "preview_deployments" DROP CONSTRAINT "preview_deployments_deploymentId_deployment_deploymentId_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "preview_deployments" DROP COLUMN IF EXISTS "deploymentId";
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "053ad983-6299-4420-a551-645490689733",
|
||||
"id": "16ee50a9-7cbc-46a4-af70-c3c85ed45466",
|
||||
"prevId": "d70bcec5-e7af-4872-b2eb-f0a22ae2e3e8",
|
||||
"version": "6",
|
||||
"dialect": "postgresql",
|
||||
@@ -38,67 +38,6 @@
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewEnv": {
|
||||
"name": "previewEnv",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewBuildArgs": {
|
||||
"name": "previewBuildArgs",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewWildcard": {
|
||||
"name": "previewWildcard",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewPort": {
|
||||
"name": "previewPort",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 3000
|
||||
},
|
||||
"previewHttps": {
|
||||
"name": "previewHttps",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"previewPath": {
|
||||
"name": "previewPath",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'/'"
|
||||
},
|
||||
"certificateType": {
|
||||
"name": "certificateType",
|
||||
"type": "certificateType",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'none'"
|
||||
},
|
||||
"previewLimit": {
|
||||
"name": "previewLimit",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 3
|
||||
},
|
||||
"isPreviewDeploymentsActive": {
|
||||
"name": "isPreviewDeploymentsActive",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"buildArgs": {
|
||||
"name": "buildArgs",
|
||||
"type": "text",
|
||||
@@ -403,6 +342,12 @@
|
||||
"notNull": true,
|
||||
"default": "'nixpacks'"
|
||||
},
|
||||
"herokuVersion": {
|
||||
"name": "herokuVersion",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"publishDirectory": {
|
||||
"name": "publishDirectory",
|
||||
"type": "text",
|
||||
@@ -1192,13 +1137,6 @@
|
||||
"notNull": false,
|
||||
"default": "'application'"
|
||||
},
|
||||
"isPreviewDeployment": {
|
||||
"name": "isPreviewDeployment",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"uniqueConfigKey": {
|
||||
"name": "uniqueConfigKey",
|
||||
"type": "serial",
|
||||
@@ -1223,12 +1161,6 @@
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewDeploymentId": {
|
||||
"name": "previewDeploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"certificateType": {
|
||||
"name": "certificateType",
|
||||
"type": "certificateType",
|
||||
@@ -1265,19 +1197,6 @@
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
|
||||
"name": "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
|
||||
"tableFrom": "domain",
|
||||
"tableTo": "preview_deployments",
|
||||
"columnsFrom": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
@@ -2047,19 +1966,6 @@
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"isPreviewDeployment": {
|
||||
"name": "isPreviewDeployment",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"previewDeploymentId": {
|
||||
"name": "previewDeploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"createdAt": {
|
||||
"name": "createdAt",
|
||||
"type": "text",
|
||||
@@ -2107,19 +2013,6 @@
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
|
||||
"name": "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
|
||||
"tableFrom": "deployment",
|
||||
"tableTo": "preview_deployments",
|
||||
"columnsFrom": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
@@ -3927,142 +3820,6 @@
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.preview_deployments": {
|
||||
"name": "preview_deployments",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"previewDeploymentId": {
|
||||
"name": "previewDeploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"branch": {
|
||||
"name": "branch",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestId": {
|
||||
"name": "pullRequestId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestNumber": {
|
||||
"name": "pullRequestNumber",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestURL": {
|
||||
"name": "pullRequestURL",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestTitle": {
|
||||
"name": "pullRequestTitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestCommentId": {
|
||||
"name": "pullRequestCommentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"appName": {
|
||||
"name": "appName",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"applicationId": {
|
||||
"name": "applicationId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"domainId": {
|
||||
"name": "domainId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"deploymentId": {
|
||||
"name": "deploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"createdAt": {
|
||||
"name": "createdAt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"expiresAt": {
|
||||
"name": "expiresAt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"preview_deployments_applicationId_application_applicationId_fk": {
|
||||
"name": "preview_deployments_applicationId_application_applicationId_fk",
|
||||
"tableFrom": "preview_deployments",
|
||||
"tableTo": "application",
|
||||
"columnsFrom": [
|
||||
"applicationId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"applicationId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"preview_deployments_domainId_domain_domainId_fk": {
|
||||
"name": "preview_deployments_domainId_domain_domainId_fk",
|
||||
"tableFrom": "preview_deployments",
|
||||
"tableTo": "domain",
|
||||
"columnsFrom": [
|
||||
"domainId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"domainId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"preview_deployments_deploymentId_deployment_deploymentId_fk": {
|
||||
"name": "preview_deployments_deploymentId_deployment_deploymentId_fk",
|
||||
"tableFrom": "preview_deployments",
|
||||
"tableTo": "deployment",
|
||||
"columnsFrom": [
|
||||
"deploymentId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"deploymentId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"preview_deployments_appName_unique": {
|
||||
"name": "preview_deployments_appName_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"appName"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
@@ -4102,8 +3859,7 @@
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"compose",
|
||||
"application",
|
||||
"preview"
|
||||
"application"
|
||||
]
|
||||
},
|
||||
"public.databaseType": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "20236ed8-104c-487b-bcdf-d08b69fbc80a",
|
||||
"prevId": "053ad983-6299-4420-a551-645490689733",
|
||||
"id": "928417c8-2e7b-43ba-bc19-44b4d70107f1",
|
||||
"prevId": "16ee50a9-7cbc-46a4-af70-c3c85ed45466",
|
||||
"version": "6",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
@@ -38,67 +38,6 @@
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewEnv": {
|
||||
"name": "previewEnv",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewBuildArgs": {
|
||||
"name": "previewBuildArgs",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewWildcard": {
|
||||
"name": "previewWildcard",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewPort": {
|
||||
"name": "previewPort",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 3000
|
||||
},
|
||||
"previewHttps": {
|
||||
"name": "previewHttps",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"previewPath": {
|
||||
"name": "previewPath",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'/'"
|
||||
},
|
||||
"certificateType": {
|
||||
"name": "certificateType",
|
||||
"type": "certificateType",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'none'"
|
||||
},
|
||||
"previewLimit": {
|
||||
"name": "previewLimit",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 3
|
||||
},
|
||||
"isPreviewDeploymentsActive": {
|
||||
"name": "isPreviewDeploymentsActive",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"buildArgs": {
|
||||
"name": "buildArgs",
|
||||
"type": "text",
|
||||
@@ -403,6 +342,13 @@
|
||||
"notNull": true,
|
||||
"default": "'nixpacks'"
|
||||
},
|
||||
"herokuVersion": {
|
||||
"name": "herokuVersion",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'24'"
|
||||
},
|
||||
"publishDirectory": {
|
||||
"name": "publishDirectory",
|
||||
"type": "text",
|
||||
@@ -1192,13 +1138,6 @@
|
||||
"notNull": false,
|
||||
"default": "'application'"
|
||||
},
|
||||
"isPreviewDeployment": {
|
||||
"name": "isPreviewDeployment",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"uniqueConfigKey": {
|
||||
"name": "uniqueConfigKey",
|
||||
"type": "serial",
|
||||
@@ -1223,12 +1162,6 @@
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"previewDeploymentId": {
|
||||
"name": "previewDeploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"certificateType": {
|
||||
"name": "certificateType",
|
||||
"type": "certificateType",
|
||||
@@ -1265,19 +1198,6 @@
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
|
||||
"name": "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
|
||||
"tableFrom": "domain",
|
||||
"tableTo": "preview_deployments",
|
||||
"columnsFrom": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
@@ -2047,19 +1967,6 @@
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"isPreviewDeployment": {
|
||||
"name": "isPreviewDeployment",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"previewDeploymentId": {
|
||||
"name": "previewDeploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"createdAt": {
|
||||
"name": "createdAt",
|
||||
"type": "text",
|
||||
@@ -2107,19 +2014,6 @@
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk": {
|
||||
"name": "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk",
|
||||
"tableFrom": "deployment",
|
||||
"tableTo": "preview_deployments",
|
||||
"columnsFrom": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"previewDeploymentId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
@@ -3927,150 +3821,6 @@
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.preview_deployments": {
|
||||
"name": "preview_deployments",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"previewDeploymentId": {
|
||||
"name": "previewDeploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"branch": {
|
||||
"name": "branch",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestId": {
|
||||
"name": "pullRequestId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestNumber": {
|
||||
"name": "pullRequestNumber",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestURL": {
|
||||
"name": "pullRequestURL",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestTitle": {
|
||||
"name": "pullRequestTitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"pullRequestCommentId": {
|
||||
"name": "pullRequestCommentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"previewStatus": {
|
||||
"name": "previewStatus",
|
||||
"type": "applicationStatus",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'idle'"
|
||||
},
|
||||
"appName": {
|
||||
"name": "appName",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"applicationId": {
|
||||
"name": "applicationId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"domainId": {
|
||||
"name": "domainId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"deploymentId": {
|
||||
"name": "deploymentId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"createdAt": {
|
||||
"name": "createdAt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"expiresAt": {
|
||||
"name": "expiresAt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"preview_deployments_applicationId_application_applicationId_fk": {
|
||||
"name": "preview_deployments_applicationId_application_applicationId_fk",
|
||||
"tableFrom": "preview_deployments",
|
||||
"tableTo": "application",
|
||||
"columnsFrom": [
|
||||
"applicationId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"applicationId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"preview_deployments_domainId_domain_domainId_fk": {
|
||||
"name": "preview_deployments_domainId_domain_domainId_fk",
|
||||
"tableFrom": "preview_deployments",
|
||||
"tableTo": "domain",
|
||||
"columnsFrom": [
|
||||
"domainId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"domainId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"preview_deployments_deploymentId_deployment_deploymentId_fk": {
|
||||
"name": "preview_deployments_deploymentId_deployment_deploymentId_fk",
|
||||
"tableFrom": "preview_deployments",
|
||||
"tableTo": "deployment",
|
||||
"columnsFrom": [
|
||||
"deploymentId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"deploymentId"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"preview_deployments_appName_unique": {
|
||||
"name": "preview_deployments_appName_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"appName"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
@@ -4110,8 +3860,7 @@
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"compose",
|
||||
"application",
|
||||
"preview"
|
||||
"application"
|
||||
]
|
||||
},
|
||||
"public.databaseType": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "71016fed-2c39-4d31-aa33-0e0aceb313ef",
|
||||
"prevId": "20236ed8-104c-487b-bcdf-d08b69fbc80a",
|
||||
"id": "82e1398d-0f5d-4290-9cb2-fd812f096b28",
|
||||
"prevId": "71016fed-2c39-4d31-aa33-0e0aceb313ef",
|
||||
"version": "6",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
@@ -403,6 +403,13 @@
|
||||
"notNull": true,
|
||||
"default": "'nixpacks'"
|
||||
},
|
||||
"herokuVersion": {
|
||||
"name": "herokuVersion",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'24'"
|
||||
},
|
||||
"publishDirectory": {
|
||||
"name": "publishDirectory",
|
||||
"type": "text",
|
||||
|
||||
@@ -334,22 +334,22 @@
|
||||
{
|
||||
"idx": 47,
|
||||
"version": "6",
|
||||
"when": 1733089956329,
|
||||
"tag": "0047_red_stephen_strange",
|
||||
"when": 1733599090582,
|
||||
"tag": "0047_tidy_revanche",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 48,
|
||||
"version": "6",
|
||||
"when": 1733091544421,
|
||||
"tag": "0048_clumsy_matthew_murdock",
|
||||
"when": 1733599163710,
|
||||
"tag": "0048_flat_expediter",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 49,
|
||||
"version": "6",
|
||||
"when": 1733091820570,
|
||||
"tag": "0049_useful_mole_man",
|
||||
"when": 1733628466143,
|
||||
"tag": "0049_overrated_sage",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
16
apps/dokploy/lib/languages.ts
Normal file
16
apps/dokploy/lib/languages.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export enum Languages {
|
||||
English = "en",
|
||||
Polish = "pl",
|
||||
Russian = "ru",
|
||||
French = "fr",
|
||||
German = "de",
|
||||
ChineseTraditional = "zh-Hant",
|
||||
ChineseSimplified = "zh-Hans",
|
||||
Turkish = "tr",
|
||||
Kazakh = "kz",
|
||||
Persian = "fa",
|
||||
Korean = "ko",
|
||||
Portuguese = "pt-br",
|
||||
}
|
||||
|
||||
export type Language = keyof typeof Languages;
|
||||
@@ -1,10 +1,23 @@
|
||||
/** @type {import('next-i18next').UserConfig} */
|
||||
module.exports = {
|
||||
i18n: {
|
||||
defaultLocale: "en",
|
||||
locales: ["en", "pl", "ru", "fr", "de", "tr", "zh-Hant", "zh-Hans", "fa"],
|
||||
localeDetection: false,
|
||||
},
|
||||
fallbackLng: "en",
|
||||
keySeparator: false,
|
||||
i18n: {
|
||||
defaultLocale: "en",
|
||||
locales: [
|
||||
"en",
|
||||
"pl",
|
||||
"ru",
|
||||
"fr",
|
||||
"de",
|
||||
"tr",
|
||||
"kz",
|
||||
"zh-Hant",
|
||||
"zh-Hans",
|
||||
"fa",
|
||||
"ko",
|
||||
"pt-br",
|
||||
],
|
||||
localeDetection: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "@/styles/globals.css";
|
||||
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { Languages } from "@/lib/languages";
|
||||
import { api } from "@/utils/api";
|
||||
import type { NextPage } from "next";
|
||||
import { appWithTranslation } from "next-i18next";
|
||||
@@ -71,17 +72,7 @@ export default api.withTRPC(
|
||||
{
|
||||
i18n: {
|
||||
defaultLocale: "en",
|
||||
locales: [
|
||||
"en",
|
||||
"pl",
|
||||
"ru",
|
||||
"fr",
|
||||
"de",
|
||||
"tr",
|
||||
"zh-Hant",
|
||||
"zh-Hans",
|
||||
"fa",
|
||||
],
|
||||
locales: Object.values(Languages),
|
||||
localeDetection: false,
|
||||
},
|
||||
fallbackLng: "en",
|
||||
|
||||
@@ -77,6 +77,7 @@ export default async function handler(
|
||||
const repository = githubBody?.repository?.name;
|
||||
const deploymentTitle = extractCommitMessage(req.headers, req.body);
|
||||
const deploymentHash = extractHash(req.headers, req.body);
|
||||
const owner = githubBody?.repository?.owner?.name;
|
||||
|
||||
const apps = await db.query.applications.findMany({
|
||||
where: and(
|
||||
@@ -84,6 +85,7 @@ export default async function handler(
|
||||
eq(applications.autoDeploy, true),
|
||||
eq(applications.branch, branchName),
|
||||
eq(applications.repository, repository),
|
||||
eq(applications.owner, owner),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -118,6 +120,7 @@ export default async function handler(
|
||||
eq(compose.autoDeploy, true),
|
||||
eq(compose.branch, branchName),
|
||||
eq(compose.repository, repository),
|
||||
eq(compose.owner, owner),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -160,6 +163,8 @@ export default async function handler(
|
||||
}
|
||||
} else if (req.headers["x-github-event"] === "pull_request") {
|
||||
const prId = githubBody?.pull_request?.id;
|
||||
|
||||
console.log(githubBody);
|
||||
if (githubBody?.action === "closed") {
|
||||
const previewDeploymentResult =
|
||||
await findPreviewDeploymentsByPullRequestId(prId);
|
||||
|
||||
1
apps/dokploy/public/locales/ko/common.json
Normal file
1
apps/dokploy/public/locales/ko/common.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
44
apps/dokploy/public/locales/ko/settings.json
Normal file
44
apps/dokploy/public/locales/ko/settings.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"settings.common.save": "저장",
|
||||
"settings.server.domain.title": "서버 도메인",
|
||||
"settings.server.domain.description": "서버 애플리케이션에 도메인을 추가합니다.",
|
||||
"settings.server.domain.form.domain": "도메인",
|
||||
"settings.server.domain.form.letsEncryptEmail": "Let's Encrypt 이메일",
|
||||
"settings.server.domain.form.certificate.label": "인증서",
|
||||
"settings.server.domain.form.certificate.placeholder": "인증서 선택",
|
||||
"settings.server.domain.form.certificateOptions.none": "없음",
|
||||
"settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt (기본)",
|
||||
|
||||
"settings.server.webServer.title": "웹 서버",
|
||||
"settings.server.webServer.description": "웹 서버를 재시작하거나 정리합니다.",
|
||||
"settings.server.webServer.actions": "작업",
|
||||
"settings.server.webServer.reload": "재시작",
|
||||
"settings.server.webServer.watchLogs": "로그 보기",
|
||||
"settings.server.webServer.updateServerIp": "서버 IP 갱신",
|
||||
"settings.server.webServer.server.label": "서버",
|
||||
"settings.server.webServer.traefik.label": "Traefik",
|
||||
"settings.server.webServer.traefik.modifyEnv": "환경 변수 수정",
|
||||
"settings.server.webServer.storage.label": "저장 공간",
|
||||
"settings.server.webServer.storage.cleanUnusedImages": "사용하지 않는 이미지 정리",
|
||||
"settings.server.webServer.storage.cleanUnusedVolumes": "사용하지 않는 볼륨 정리",
|
||||
"settings.server.webServer.storage.cleanStoppedContainers": "정지된 컨테이너 정리",
|
||||
"settings.server.webServer.storage.cleanDockerBuilder": "도커 빌더 & 시스템 정리",
|
||||
"settings.server.webServer.storage.cleanMonitoring": "모니터링 데이터 정리",
|
||||
"settings.server.webServer.storage.cleanAll": "전체 정리",
|
||||
|
||||
"settings.profile.title": "계정",
|
||||
"settings.profile.description": "여기에서 프로필 세부 정보를 변경하세요.",
|
||||
"settings.profile.email": "이메일",
|
||||
"settings.profile.password": "비밀번호",
|
||||
"settings.profile.avatar": "아바타",
|
||||
|
||||
"settings.appearance.title": "외관",
|
||||
"settings.appearance.description": "대시보드의 테마를 사용자 설정합니다.",
|
||||
"settings.appearance.theme": "테마",
|
||||
"settings.appearance.themeDescription": "대시보드 테마 선택",
|
||||
"settings.appearance.themes.light": "라이트",
|
||||
"settings.appearance.themes.dark": "다크",
|
||||
"settings.appearance.themes.system": "시스템",
|
||||
"settings.appearance.language": "언어",
|
||||
"settings.appearance.languageDescription": "대시보드에서 사용할 언어 선택"
|
||||
}
|
||||
1
apps/dokploy/public/locales/kz/common.json
Normal file
1
apps/dokploy/public/locales/kz/common.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
41
apps/dokploy/public/locales/kz/settings.json
Normal file
41
apps/dokploy/public/locales/kz/settings.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"settings.common.save": "Сақтау",
|
||||
"settings.server.domain.title": "Сервер домені",
|
||||
"settings.server.domain.description": "Dokploy сервер қолданбасына домен енгізіңіз.",
|
||||
"settings.server.domain.form.domain": "Домен",
|
||||
"settings.server.domain.form.letsEncryptEmail": "Let's Encrypt Эл. поштасы",
|
||||
"settings.server.domain.form.certificate.label": "Сертификат",
|
||||
"settings.server.domain.form.certificate.placeholder": "Сертификатты таңдаңыз",
|
||||
"settings.server.domain.form.certificateOptions.none": "Жоқ",
|
||||
"settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt (Стандартты)",
|
||||
"settings.server.webServer.title": "Веб-Сервер",
|
||||
"settings.server.webServer.description": "Веб-серверді қайта жүктеу немесе тазалау.",
|
||||
"settings.server.webServer.actions": "Әрекеттер",
|
||||
"settings.server.webServer.reload": "Қайта жүктеу",
|
||||
"settings.server.webServer.watchLogs": "Журналдарды қарау",
|
||||
"settings.server.webServer.updateServerIp": "Сервердің IP жаңарту",
|
||||
"settings.server.webServer.server.label": "Сервер",
|
||||
"settings.server.webServer.traefik.label": "Traefik",
|
||||
"settings.server.webServer.traefik.modifyEnv": "Env Өзгерту",
|
||||
"settings.server.webServer.storage.label": "Диск кеңістігі",
|
||||
"settings.server.webServer.storage.cleanUnusedImages": "Пайдаланылмаған образды тазалау",
|
||||
"settings.server.webServer.storage.cleanUnusedVolumes": "Пайдаланылмаған томды тазалау",
|
||||
"settings.server.webServer.storage.cleanStoppedContainers": "Тоқтатылған контейнерлерді тазалау",
|
||||
"settings.server.webServer.storage.cleanDockerBuilder": "Docker Builder & Системаны тазалау",
|
||||
"settings.server.webServer.storage.cleanMonitoring": "Мониторингті тазалау",
|
||||
"settings.server.webServer.storage.cleanAll": "Барлығын тазалау",
|
||||
"settings.profile.title": "Аккаунт",
|
||||
"settings.profile.description": "Профиль мәліметтерін осы жерден өзгертіңіз.",
|
||||
"settings.profile.email": "Эл. пошта",
|
||||
"settings.profile.password": "Құпия сөз",
|
||||
"settings.profile.avatar": "Аватар",
|
||||
"settings.appearance.title": "Сыртқы түрі",
|
||||
"settings.appearance.description": "Dokploy сыртқы келбетін өзгерту.",
|
||||
"settings.appearance.theme": "Келбеті",
|
||||
"settings.appearance.themeDescription": "Жүйе тақтасының келбетің таңдаңыз",
|
||||
"settings.appearance.themes.light": "Жарық",
|
||||
"settings.appearance.themes.dark": "Қараңғы",
|
||||
"settings.appearance.themes.system": "Жүйелік",
|
||||
"settings.appearance.language": "Тіл",
|
||||
"settings.appearance.languageDescription": "Жүйе тақтасының тілің таңдаңыз"
|
||||
}
|
||||
1
apps/dokploy/public/locales/pt-br/common.json
Normal file
1
apps/dokploy/public/locales/pt-br/common.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
44
apps/dokploy/public/locales/pt-br/settings.json
Normal file
44
apps/dokploy/public/locales/pt-br/settings.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"settings.common.save": "Salvar",
|
||||
"settings.server.domain.title": "Domínio do Servidor",
|
||||
"settings.server.domain.description": "Configure o domínio do servidor",
|
||||
"settings.server.domain.form.domain": "Domínio",
|
||||
"settings.server.domain.form.letsEncryptEmail": "Email do Let's Encrypt",
|
||||
"settings.server.domain.form.certificate.label": "Certificado",
|
||||
"settings.server.domain.form.certificate.placeholder": "Selecione um Certificado",
|
||||
"settings.server.domain.form.certificateOptions.none": "Nenhum",
|
||||
"settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt (Padrão)",
|
||||
|
||||
"settings.server.webServer.title": "Servidor web",
|
||||
"settings.server.webServer.description": "Limpar e recarregar servidor web.",
|
||||
"settings.server.webServer.actions": "Ações",
|
||||
"settings.server.webServer.reload": "Recarregar",
|
||||
"settings.server.webServer.watchLogs": "Ver logs",
|
||||
"settings.server.webServer.updateServerIp": "Atualizar IP do Servidor",
|
||||
"settings.server.webServer.server.label": "Servidor",
|
||||
"settings.server.webServer.traefik.label": "Traefik",
|
||||
"settings.server.webServer.traefik.modifyEnv": "Alterar Env",
|
||||
"settings.server.webServer.storage.label": "Armazenamento",
|
||||
"settings.server.webServer.storage.cleanUnusedImages": "Limpar imagens não utilizadas",
|
||||
"settings.server.webServer.storage.cleanUnusedVolumes": "Limpar volumes não utilizados",
|
||||
"settings.server.webServer.storage.cleanStoppedContainers": "Limpar containers parados",
|
||||
"settings.server.webServer.storage.cleanDockerBuilder": "Limpar Docker Builder & System",
|
||||
"settings.server.webServer.storage.cleanMonitoring": "Limpar Monitoramento",
|
||||
"settings.server.webServer.storage.cleanAll": "Limpar Tudo",
|
||||
|
||||
"settings.profile.title": "Conta",
|
||||
"settings.profile.description": "Altere os detalhes do seu perfil aqui.",
|
||||
"settings.profile.email": "Email",
|
||||
"settings.profile.password": "Senha",
|
||||
"settings.profile.avatar": "Avatar",
|
||||
|
||||
"settings.appearance.title": "Aparencia",
|
||||
"settings.appearance.description": "Personalize o tema do seu dashboard.",
|
||||
"settings.appearance.theme": "Tema",
|
||||
"settings.appearance.themeDescription": "Selecione um tema para o dashboard",
|
||||
"settings.appearance.themes.light": "Claro",
|
||||
"settings.appearance.themes.dark": "Escuro",
|
||||
"settings.appearance.themes.system": "Automático",
|
||||
"settings.appearance.language": "Linguagem",
|
||||
"settings.appearance.languageDescription": "Selecione o idioma do dashboard"
|
||||
}
|
||||
2
apps/dokploy/public/templates/triggerdotdev.svg
Normal file
2
apps/dokploy/public/templates/triggerdotdev.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 7.2 KiB |
@@ -296,6 +296,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
publishDirectory: input.publishDirectory,
|
||||
dockerContextPath: input.dockerContextPath,
|
||||
dockerBuildStage: input.dockerBuildStage,
|
||||
herokuVersion: input.herokuVersion,
|
||||
});
|
||||
|
||||
return true;
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
removeCompose,
|
||||
removeComposeDirectory,
|
||||
removeDeploymentsByComposeId,
|
||||
startCompose,
|
||||
stopCompose,
|
||||
updateCompose,
|
||||
} from "@dokploy/server";
|
||||
@@ -309,6 +310,20 @@ export const composeRouter = createTRPCRouter({
|
||||
}
|
||||
await stopCompose(input.composeId);
|
||||
|
||||
return true;
|
||||
}),
|
||||
start: protectedProcedure
|
||||
.input(apiFindCompose)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const compose = await findComposeById(input.composeId);
|
||||
if (compose.project.adminId !== ctx.user.adminId) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to stop this compose",
|
||||
});
|
||||
}
|
||||
await startCompose(input.composeId);
|
||||
|
||||
return true;
|
||||
}),
|
||||
getDefaultCommand: protectedProcedure
|
||||
|
||||
@@ -188,8 +188,9 @@ export const notificationRouter = createTRPCRouter({
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
await sendDiscordNotification(input, {
|
||||
title: "Test Notification",
|
||||
description: "Hi, From Dokploy 👋",
|
||||
title: "> `🤚` - Test Notification",
|
||||
description: "> Hi, From Dokploy 👋",
|
||||
color: 0xf3f7f4,
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
pocketbase:
|
||||
image: spectado/pocketbase:0.22.12
|
||||
image: spectado/pocketbase:0.23.3
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /etc/dokploy/templates/${HASH}/data:/pb_data
|
||||
|
||||
@@ -380,7 +380,7 @@ export const templates: TemplateData[] = [
|
||||
{
|
||||
id: "umami",
|
||||
name: "Umami",
|
||||
version: "v2.12.1",
|
||||
version: "v2.14.0",
|
||||
description:
|
||||
"Umami is a simple, fast, privacy-focused alternative to Google Analytics.",
|
||||
logo: "umami.png",
|
||||
@@ -972,4 +972,19 @@ export const templates: TemplateData[] = [
|
||||
tags: ["event"],
|
||||
load: () => import("./ontime/index").then((m) => m.generate),
|
||||
},
|
||||
{
|
||||
id: "triggerdotdev",
|
||||
name: "Trigger.dev",
|
||||
version: "v3",
|
||||
description:
|
||||
"Trigger is a platform for building event-driven applications.",
|
||||
logo: "triggerdotdev.svg",
|
||||
links: {
|
||||
github: "https://github.com/triggerdotdev/trigger.dev",
|
||||
website: "https://trigger.dev/",
|
||||
docs: "https://trigger.dev/docs",
|
||||
},
|
||||
tags: ["event-driven", "applications"],
|
||||
load: () => import("./triggerdotdev/index").then((m) => m.generate),
|
||||
},
|
||||
];
|
||||
|
||||
107
apps/dokploy/templates/triggerdotdev/docker-compose.yml
Normal file
107
apps/dokploy/templates/triggerdotdev/docker-compose.yml
Normal file
@@ -0,0 +1,107 @@
|
||||
x-webapp-env: &webapp-env
|
||||
LOGIN_ORIGIN: &trigger-url ${TRIGGER_PROTOCOL:-http}://${TRIGGER_DOMAIN:-localhost:3040}
|
||||
APP_ORIGIN: *trigger-url
|
||||
DEV_OTEL_EXPORTER_OTLP_ENDPOINT: &trigger-otel ${TRIGGER_PROTOCOL:-http}://${TRIGGER_DOMAIN:-localhost:3040}/otel
|
||||
ELECTRIC_ORIGIN: http://electric:3000
|
||||
|
||||
x-worker-env: &worker-env
|
||||
PLATFORM_HOST: webapp
|
||||
PLATFORM_WS_PORT: 3030
|
||||
SECURE_CONNECTION: "false"
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: *trigger-otel
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
redis-data:
|
||||
|
||||
networks:
|
||||
webapp:
|
||||
|
||||
services:
|
||||
webapp:
|
||||
image: ghcr.io/triggerdotdev/trigger.dev:${TRIGGER_IMAGE_TAG:-v3}
|
||||
restart: ${RESTART_POLICY:-unless-stopped}
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
<<: *webapp-env
|
||||
ports:
|
||||
- 3000
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
networks:
|
||||
- webapp
|
||||
|
||||
postgres:
|
||||
image: postgres:${POSTGRES_IMAGE_TAG:-16}
|
||||
restart: ${RESTART_POLICY:-unless-stopped}
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data/
|
||||
env_file:
|
||||
- .env
|
||||
networks:
|
||||
- webapp
|
||||
ports:
|
||||
- 5432
|
||||
command:
|
||||
- -c
|
||||
- wal_level=logical
|
||||
|
||||
redis:
|
||||
image: redis:${REDIS_IMAGE_TAG:-7}
|
||||
restart: ${RESTART_POLICY:-unless-stopped}
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
networks:
|
||||
- webapp
|
||||
ports:
|
||||
- 6379
|
||||
|
||||
docker-provider:
|
||||
image: ghcr.io/triggerdotdev/provider/docker:${TRIGGER_IMAGE_TAG:-v3}
|
||||
restart: ${RESTART_POLICY:-unless-stopped}
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
user: root
|
||||
networks:
|
||||
- webapp
|
||||
depends_on:
|
||||
- webapp
|
||||
ports:
|
||||
- 9020
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
<<: *worker-env
|
||||
PLATFORM_SECRET: $PROVIDER_SECRET
|
||||
|
||||
coordinator:
|
||||
image: ghcr.io/triggerdotdev/coordinator:${TRIGGER_IMAGE_TAG:-v3}
|
||||
restart: ${RESTART_POLICY:-unless-stopped}
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
user: root
|
||||
networks:
|
||||
- webapp
|
||||
depends_on:
|
||||
- webapp
|
||||
ports:
|
||||
- 9020
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
<<: *worker-env
|
||||
PLATFORM_SECRET: $COORDINATOR_SECRET
|
||||
|
||||
electric:
|
||||
image: electricsql/electric:${ELECTRIC_IMAGE_TAG:-latest}
|
||||
restart: ${RESTART_POLICY:-unless-stopped}
|
||||
environment:
|
||||
DATABASE_URL: ${DATABASE_URL}?sslmode=disable
|
||||
networks:
|
||||
- webapp
|
||||
depends_on:
|
||||
- postgres
|
||||
ports:
|
||||
- 3000
|
||||
93
apps/dokploy/templates/triggerdotdev/index.ts
Normal file
93
apps/dokploy/templates/triggerdotdev/index.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Secrets } from "@/components/ui/secrets";
|
||||
import {
|
||||
type DomainSchema,
|
||||
type Schema,
|
||||
type Template,
|
||||
generateBase64,
|
||||
generateRandomDomain,
|
||||
} from "../utils";
|
||||
|
||||
export function generate(schema: Schema): Template {
|
||||
const triggerDomain = generateRandomDomain(schema);
|
||||
|
||||
const magicLinkSecret = generateBase64(16);
|
||||
const sessionSecret = generateBase64(16);
|
||||
const encryptionKey = generateBase64(32);
|
||||
const providerSecret = generateBase64(32);
|
||||
const coordinatorSecret = generateBase64(32);
|
||||
|
||||
const dbPassword = generateBase64(24);
|
||||
const dbUser = "triggeruser";
|
||||
const dbName = "triggerdb";
|
||||
|
||||
const domains: DomainSchema[] = [
|
||||
{
|
||||
host: triggerDomain,
|
||||
port: 3000,
|
||||
serviceName: "webapp",
|
||||
},
|
||||
];
|
||||
|
||||
const envs = [
|
||||
"NODE_ENV=production",
|
||||
"RUNTIME_PLATFORM=docker-compose",
|
||||
"V3_ENABLED=true",
|
||||
|
||||
"# Domain configuration",
|
||||
`TRIGGER_DOMAIN=${triggerDomain}`,
|
||||
"TRIGGER_PROTOCOL=http",
|
||||
|
||||
"# Database configuration with secure credentials",
|
||||
`POSTGRES_USER=${dbUser}`,
|
||||
`POSTGRES_PASSWORD=${dbPassword}`,
|
||||
`POSTGRES_DB=${dbName}`,
|
||||
`DATABASE_URL=postgresql://${dbUser}:${dbPassword}@postgres:5432/${dbName}`,
|
||||
|
||||
"# Secrets",
|
||||
`MAGIC_LINK_SECRET=${magicLinkSecret}`,
|
||||
`SESSION_SECRET=${sessionSecret}`,
|
||||
`ENCRYPTION_KEY=${encryptionKey}`,
|
||||
`PROVIDER_SECRET=${providerSecret}`,
|
||||
`COORDINATOR_SECRET=${coordinatorSecret}`,
|
||||
|
||||
"# TRIGGER_TELEMETRY_DISABLED=1",
|
||||
"INTERNAL_OTEL_TRACE_DISABLED=1",
|
||||
"INTERNAL_OTEL_TRACE_LOGGING_ENABLED=0",
|
||||
|
||||
"DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT=300",
|
||||
"DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT=100",
|
||||
|
||||
"DIRECT_URL=${DATABASE_URL}",
|
||||
"REDIS_HOST=redis",
|
||||
"REDIS_PORT=6379",
|
||||
"REDIS_TLS_DISABLED=true",
|
||||
|
||||
"# If this is set, emails that are not specified won't be able to log in",
|
||||
'# WHITELISTED_EMAILS="authorized@yahoo.com|authorized@gmail.com"',
|
||||
"# Accounts with these emails will become admins when signing up and get access to the admin panel",
|
||||
'# ADMIN_EMAILS="admin@example.com|another-admin@example.com"',
|
||||
|
||||
"# If this is set, your users will be able to log in via GitHub",
|
||||
"# AUTH_GITHUB_CLIENT_ID=",
|
||||
"# AUTH_GITHUB_CLIENT_SECRET=",
|
||||
|
||||
"# E-mail settings",
|
||||
"# Ensure the FROM_EMAIL matches what you setup with Resend.com",
|
||||
"# If these are not set, emails will be printed to the console",
|
||||
"# FROM_EMAIL=",
|
||||
"# REPLY_TO_EMAIL=",
|
||||
"# RESEND_API_KEY=",
|
||||
|
||||
"# Worker settings",
|
||||
"HTTP_SERVER_PORT=9020",
|
||||
"COORDINATOR_HOST=127.0.0.1",
|
||||
"COORDINATOR_PORT=${HTTP_SERVER_PORT}",
|
||||
"# REGISTRY_HOST=${DEPLOY_REGISTRY_HOST}",
|
||||
"# REGISTRY_NAMESPACE=${DEPLOY_REGISTRY_NAMESPACE}",
|
||||
];
|
||||
|
||||
return {
|
||||
envs,
|
||||
domains,
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
umami:
|
||||
image: ghcr.io/umami-software/umami:postgresql-v2.13.2
|
||||
image: ghcr.io/umami-software/umami:postgresql-v2.14.0
|
||||
restart: always
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"]
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
import type { Languages } from "@/lib/languages";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
const SUPPORTED_LOCALES = [
|
||||
"en",
|
||||
"pl",
|
||||
"ru",
|
||||
"fr",
|
||||
"de",
|
||||
"tr",
|
||||
"zh-Hant",
|
||||
"zh-Hans",
|
||||
"fa",
|
||||
] as const;
|
||||
|
||||
type Locale = (typeof SUPPORTED_LOCALES)[number];
|
||||
|
||||
export default function useLocale() {
|
||||
const currentLocale = (Cookies.get("DOKPLOY_LOCALE") ?? "en") as Locale;
|
||||
const currentLocale = (Cookies.get("DOKPLOY_LOCALE") ?? "en") as Languages;
|
||||
|
||||
const setLocale = (locale: Locale) => {
|
||||
const setLocale = (locale: Languages) => {
|
||||
Cookies.set("DOKPLOY_LOCALE", locale, { expires: 365 });
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
@@ -5,11 +5,19 @@ export function getLocale(cookies: NextApiRequestCookies) {
|
||||
return locale;
|
||||
}
|
||||
|
||||
// libs/i18n.js
|
||||
import { Languages } from "@/lib/languages";
|
||||
import { serverSideTranslations as originalServerSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import nextI18NextConfig from "../next-i18next.config.cjs";
|
||||
|
||||
export const serverSideTranslations = (
|
||||
locale: string,
|
||||
namespaces = ["common"],
|
||||
) => originalServerSideTranslations(locale, namespaces, nextI18NextConfig);
|
||||
) =>
|
||||
originalServerSideTranslations(locale, namespaces, {
|
||||
fallbackLng: "en",
|
||||
keySeparator: false,
|
||||
i18n: {
|
||||
defaultLocale: "en",
|
||||
locales: Object.values(Languages),
|
||||
localeDetection: false,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -192,6 +192,7 @@ export const applications = pgTable("application", {
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
buildType: buildType("buildType").notNull().default("nixpacks"),
|
||||
herokuVersion: text("herokuVersion").default("24"),
|
||||
publishDirectory: text("publishDirectory"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
@@ -384,6 +385,7 @@ const createSchema = createInsertSchema(applications, {
|
||||
"nixpacks",
|
||||
"static",
|
||||
]),
|
||||
herokuVersion: z.string().optional(),
|
||||
publishDirectory: z.string().optional(),
|
||||
owner: z.string(),
|
||||
healthCheckSwarm: HealthCheckSwarmSchema.nullable(),
|
||||
@@ -432,6 +434,7 @@ export const apiSaveBuildType = createSchema
|
||||
dockerfile: true,
|
||||
dockerContextPath: true,
|
||||
dockerBuildStage: true,
|
||||
herokuVersion: true,
|
||||
})
|
||||
.required()
|
||||
.merge(createSchema.pick({ publishDirectory: true }));
|
||||
|
||||
@@ -468,6 +468,36 @@ export const removeCompose = async (compose: Compose) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
export const startCompose = async (composeId: string) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
try {
|
||||
const { COMPOSE_PATH } = paths(!!compose.serverId);
|
||||
if (compose.composeType === "docker-compose") {
|
||||
if (compose.serverId) {
|
||||
await execAsyncRemote(
|
||||
compose.serverId,
|
||||
`cd ${join(COMPOSE_PATH, compose.appName, "code")} && docker compose -p ${compose.appName} up -d`,
|
||||
);
|
||||
} else {
|
||||
await execAsync(`docker compose -p ${compose.appName} up -d`, {
|
||||
cwd: join(COMPOSE_PATH, compose.appName, "code"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await updateCompose(composeId, {
|
||||
composeStatus: "done",
|
||||
});
|
||||
} catch (error) {
|
||||
await updateCompose(composeId, {
|
||||
composeStatus: "idle",
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export const stopCompose = async (composeId: string) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
try {
|
||||
|
||||
@@ -22,7 +22,7 @@ export const buildHeroku = async (
|
||||
"--path",
|
||||
buildAppDirectory,
|
||||
"--builder",
|
||||
"heroku/builder:24",
|
||||
`heroku/builder:${application.herokuVersion || "24"}`,
|
||||
];
|
||||
|
||||
for (const env of envVariables) {
|
||||
@@ -58,7 +58,7 @@ export const getHerokuCommand = (
|
||||
"--path",
|
||||
buildAppDirectory,
|
||||
"--builder",
|
||||
"heroku/builder:24",
|
||||
`heroku/builder:${application.herokuVersion || "24"}`,
|
||||
];
|
||||
|
||||
for (const env of envVariables) {
|
||||
|
||||
@@ -59,31 +59,46 @@ export const sendBuildErrorNotifications = async ({
|
||||
|
||||
if (discord) {
|
||||
await sendDiscordNotification(discord, {
|
||||
title: "⚠️ Build Failed",
|
||||
color: 0xff0000,
|
||||
title: "> `⚠️` - Build Failed",
|
||||
color: 0xed4245,
|
||||
fields: [
|
||||
{
|
||||
name: "Project",
|
||||
name: "`🛠️`・Project",
|
||||
value: projectName,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Application",
|
||||
name: "`⚙️`・Application",
|
||||
value: applicationName,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Type",
|
||||
name: "`❔`・Type",
|
||||
value: applicationType,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Error",
|
||||
value: errorMessage,
|
||||
name: "`📅`・Date",
|
||||
value: date.toLocaleDateString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Build Link",
|
||||
value: buildLink,
|
||||
name: "`⌚`・Time",
|
||||
value: date.toLocaleTimeString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`❓`・Type",
|
||||
value: "Failed",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`⚠️`・Error Message",
|
||||
value: `\`\`\`${errorMessage}\`\`\``,
|
||||
},
|
||||
{
|
||||
name: "`🧷`・Build Link",
|
||||
value: `[Click here to access build link](${buildLink})`,
|
||||
},
|
||||
],
|
||||
timestamp: date.toISOString(),
|
||||
|
||||
@@ -57,27 +57,42 @@ export const sendBuildSuccessNotifications = async ({
|
||||
|
||||
if (discord) {
|
||||
await sendDiscordNotification(discord, {
|
||||
title: "✅ Build Success",
|
||||
color: 0x00ff00,
|
||||
title: "> `✅` - Build Success",
|
||||
color: 0x57f287,
|
||||
fields: [
|
||||
{
|
||||
name: "Project",
|
||||
name: "`🛠️`・Project",
|
||||
value: projectName,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Application",
|
||||
name: "`⚙️`・Application",
|
||||
value: applicationName,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Type",
|
||||
name: "`❔`・Application Type",
|
||||
value: applicationType,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Build Link",
|
||||
value: buildLink,
|
||||
name: "`📅`・Date",
|
||||
value: date.toLocaleDateString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`⌚`・Time",
|
||||
value: date.toLocaleTimeString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`❓`・Type",
|
||||
value: "Successful",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`🧷`・Build Link",
|
||||
value: `[Click here to access build link](${buildLink})`,
|
||||
},
|
||||
],
|
||||
timestamp: date.toISOString(),
|
||||
|
||||
@@ -64,39 +64,47 @@ export const sendDatabaseBackupNotifications = async ({
|
||||
await sendDiscordNotification(discord, {
|
||||
title:
|
||||
type === "success"
|
||||
? "✅ Database Backup Successful"
|
||||
: "❌ Database Backup Failed",
|
||||
color: type === "success" ? 0x00ff00 : 0xff0000,
|
||||
? "> `✅` - Database Backup Successful"
|
||||
: "> `❌` - Database Backup Failed",
|
||||
color: type === "success" ? 0x57f287 : 0xed4245,
|
||||
fields: [
|
||||
{
|
||||
name: "Project",
|
||||
name: "`🛠️`・Project",
|
||||
value: projectName,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Application",
|
||||
name: "`⚙️`・Application",
|
||||
value: applicationName,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Type",
|
||||
name: "`❔`・Database",
|
||||
value: databaseType,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Time",
|
||||
value: date.toLocaleString(),
|
||||
name: "`📅`・Date",
|
||||
value: date.toLocaleDateString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Type",
|
||||
value: type,
|
||||
name: "`⌚`・Time",
|
||||
value: date.toLocaleTimeString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`❓`・Type",
|
||||
value: type
|
||||
.replace("error", "Failed")
|
||||
.replace("success", "Successful"),
|
||||
inline: true,
|
||||
},
|
||||
...(type === "error" && errorMessage
|
||||
? [
|
||||
{
|
||||
name: "Error Message",
|
||||
value: errorMessage,
|
||||
name: "`⚠️`・Error Message",
|
||||
value: `\`\`\`${errorMessage}\`\`\``,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
||||
@@ -45,12 +45,27 @@ export const sendDockerCleanupNotifications = async (
|
||||
|
||||
if (discord) {
|
||||
await sendDiscordNotification(discord, {
|
||||
title: "✅ Docker Cleanup",
|
||||
color: 0x00ff00,
|
||||
title: "> `✅` - Docker Cleanup",
|
||||
color: 0x57f287,
|
||||
fields: [
|
||||
{
|
||||
name: "Message",
|
||||
value: message,
|
||||
name: "`📅`・Date",
|
||||
value: date.toLocaleDateString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`⌚`・Time",
|
||||
value: date.toLocaleTimeString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`❓`・Type",
|
||||
value: "Successful",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`📜`・Message",
|
||||
value: `\`\`\`${message}\`\`\``,
|
||||
},
|
||||
],
|
||||
timestamp: date.toISOString(),
|
||||
|
||||
@@ -34,12 +34,22 @@ export const sendDokployRestartNotifications = async () => {
|
||||
|
||||
if (discord) {
|
||||
await sendDiscordNotification(discord, {
|
||||
title: "✅ Dokploy Server Restarted",
|
||||
color: 0x00ff00,
|
||||
title: "> `✅` - Dokploy Server Restarted",
|
||||
color: 0x57f287,
|
||||
fields: [
|
||||
{
|
||||
name: "Time",
|
||||
value: date.toLocaleString(),
|
||||
name: "`📅`・Date",
|
||||
value: date.toLocaleDateString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`⌚`・Time",
|
||||
value: date.toLocaleTimeString(),
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "`❓`・Type",
|
||||
value: "Successful",
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user