Compare commits

...

20 Commits

Author SHA1 Message Date
Mauricio Siu
bbe7d5bdc5 Merge pull request #1499 from Dokploy/1455-invalid-origin-on-login
chore: update better-auth package to version 1.2.4 and kysely to vers…
2025-03-15 14:46:28 -06:00
Mauricio Siu
6f7a5609a3 chore: update better-auth package to version 1.2.4 and kysely to version 0.27.6; enhance error handling in 2FA feature 2025-03-15 14:45:21 -06:00
Mauricio Siu
c3a5e2a8d6 Merge pull request #1498 from Dokploy/1486-mongodb-external-url-visual-bug
feat: add alert block for IP address requirement in database credenti…
2025-03-15 14:30:09 -06:00
Mauricio Siu
1ca965268e feat: add alert block for IP address requirement in database credential components 2025-03-15 14:29:16 -06:00
Mauricio Siu
e323ade29e Merge pull request #1473 from gentslava/fix/service_layout
fix(ui): projects layout
2025-03-15 13:41:08 -06:00
Mauricio Siu
8c916bc431 Merge pull request #1491 from tswymer/fix/duplicate-percentage-unit
fix: removed duplicate percentage label
2025-03-15 13:39:57 -06:00
Mauricio Siu
0670f9b910 Merge pull request #1474 from drudge/canary
Various Improvements
2025-03-15 13:24:39 -06:00
Mauricio Siu
44f002d8d0 Merge pull request #1497 from Dokploy/fix/adjust-images-templates
fix: update template logo URL to use the new domain for consistency
2025-03-15 13:23:17 -06:00
Mauricio Siu
27f6c945e0 fix: update template logo URL to use the new domain for consistency 2025-03-15 13:22:47 -06:00
Tobias Wymer
e61c216ea0 fix: removed duplicate percentage label 2025-03-14 19:34:15 +01:00
Nicholas Penree
9f9492af79 fix: generate domains from templates using slugified project name 2025-03-12 22:44:49 -04:00
Nicholas Penree
68f608bdc9 chore(ui): replace placeholder company name 2025-03-12 22:44:49 -04:00
Nicholas Penree
8f671d1691 chore(ui): standardize view logs / terminal menu items 2025-03-12 22:44:49 -04:00
Nicholas Penree
7afbe8b208 chore(ui): standardize status badge for containers 2025-03-12 22:44:48 -04:00
Nicholas Penree
8c05214e78 fix(monitoring): remove extra percent from cpu usage 2025-03-12 22:44:48 -04:00
Vyacheslav Shcherbinin
2ace36f035 fix(ui): projects layout for large screen 2025-03-12 19:16:16 +07:00
Vyacheslav Shcherbinin
b7196a3494 fix(config): large screens support 2025-03-12 19:16:16 +07:00
Mauricio Siu
3b737ca55b Merge pull request #1468 from ChrisvanChip/style-remove-gap-from-container
style: remove inconsistent gap between header and content
2025-03-12 00:55:32 -06:00
Chris
581e590f65 style: remove inconsistent gap between header and content 2025-03-11 12:18:17 +00:00
Mauricio Siu
d66a5d55a3 docs: update template contribution guidelines to reference external repository 2025-03-11 01:36:20 -06:00
29 changed files with 146 additions and 368 deletions

View File

@@ -165,86 +165,8 @@ Thank you for your contribution!
## Templates
To add a new template, go to `templates` folder and create a new folder with the name of the template.
To add a new template, go to `https://github.com/Dokploy/templates` repository and read the README.md file.
Let's take the example of `plausible` template.
1. create a folder in `templates/plausible`
2. create a `docker-compose.yml` file inside the folder with the content of compose.
3. create a `index.ts` file inside the folder with the following code as base:
4. When creating a pull request, please provide a video of the template working in action.
```typescript
// EXAMPLE
import {
generateBase64,
generateHash,
generateRandomDomain,
type Template,
type Schema,
type DomainSchema,
} from "../utils";
export function generate(schema: Schema): Template {
// do your stuff here, like create a new domain, generate random passwords, mounts.
const mainServiceHash = generateHash(schema.projectName);
const mainDomain = generateRandomDomain(schema);
const secretBase = generateBase64(64);
const toptKeyBase = generateBase64(32);
const domains: DomainSchema[] = [
{
host: mainDomain,
port: 8000,
serviceName: "plausible",
},
];
const envs = [
`BASE_URL=http://${mainDomain}`,
`SECRET_KEY_BASE=${secretBase}`,
`TOTP_VAULT_KEY=${toptKeyBase}`,
`HASH=${mainServiceHash}`,
];
const mounts: Template["mounts"] = [
{
filePath: "./clickhouse/clickhouse-config.xml",
content: "some content......",
},
];
return {
envs,
mounts,
domains,
};
}
```
4. Now you need to add the information about the template to the `templates/templates.ts` is a object with the following properties:
**Make sure the id of the template is the same as the folder name and don't have any spaces, only slugified names and lowercase.**
```typescript
{
id: "plausible",
name: "Plausible",
version: "v2.1.0",
description:
"Plausible is a open source, self-hosted web analytics platform that lets you track website traffic and user behavior.",
logo: "plausible.svg", // we defined the name and the extension of the logo
links: {
github: "https://github.com/plausible/plausible",
website: "https://plausible.io/",
docs: "https://plausible.io/docs",
},
tags: ["analytics"],
load: () => import("./plausible/index").then((m) => m.generate),
},
```
5. Add the logo or image of the template to `public/templates/plausible.svg`
### Recommendations

View File

@@ -1,242 +0,0 @@
# Contributing
Hey, thanks for your interest in contributing to Dokploy! We appreciate your help and taking your time to contribute.
Before you start, please first discuss the feature/bug you want to add with the owners and comunity via github issues.
We have a few guidelines to follow when contributing to this project:
- [Commit Convention](#commit-convention)
- [Setup](#setup)
- [Development](#development)
- [Build](#build)
- [Pull Request](#pull-request)
## Commit Convention
Before you craete a Pull Request, please make sure your commit message follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
### Commit Message Format
```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
#### Type
Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing tests or correcting existing tests
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
* **chore**: Other changes that don't modify `src` or `test` files
* **revert**: Reverts a previous commit
Example:
```
feat: add new feature
```
## Setup
Before you start, please make the clone based on the `canary` branch, since the `main` branch is the source of truth and should always reflect the latest stable release, also the PRs will be merged to the `canary` branch.
```bash
git clone https://github.com/dokploy/dokploy.git
cd dokploy
pnpm install
cp .env.example .env
```
## Development
Is required to have **Docker** installed on your machine.
### Setup
Run the command that will spin up all the required services and files.
```bash
pnpm run setup
```
Now run the development server.
```bash
pnpm run dev
```
Go to http://localhost:3000 to see the development server
## Build
```bash
pnpm run build
```
## Docker
To build the docker image
```bash
pnpm run docker:build
```
To push the docker image
```bash
pnpm run docker:push
```
## Password Reset
In the case you lost your password, you can reset it using the following command
```bash
pnpm run reset-password
```
If you want to test the webhooks on development mode using localtunnel, make sure to install `localtunnel`
```bash
bunx lt --port 3000
```
If you run into permission issues of docker run the following command
```bash
sudo chown -R USERNAME dokploy or sudo chown -R $(whoami) ~/.docker
```
## Application deploy
In case you want to deploy the application on your machine and you selected nixpacks or buildpacks, you need to install first.
```bash
# Install Nixpacks
curl -sSL https://nixpacks.com/install.sh -o install.sh \
&& chmod +x install.sh \
&& ./install.sh
```
```bash
# Install Buildpacks
curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.32.1/pack-v0.32.1-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack
```
## Pull Request
- The `main` branch is the source of truth and should always reflect the latest stable release.
- Create a new branch for each feature or bug fix.
- Make sure to add tests for your changes.
- Make sure to update the documentation for any changes Go to the [docs.dokploy.com](https://docs.dokploy.com) website to see the changes.
- When creating a pull request, please provide a clear and concise description of the changes made.
- If you include a video or screenshot, would be awesome so we can see the changes in action.
- If your pull request fixes an open issue, please reference the issue in the pull request description.
- Once your pull request is merged, you will be automatically added as a contributor to the project.
Thank you for your contribution!
## Templates
To add a new template, go to `templates` folder and create a new folder with the name of the template.
Let's take the example of `plausible` template.
1. create a folder in `templates/plausible`
2. create a `docker-compose.yml` file inside the folder with the content of compose.
3. create a `index.ts` file inside the folder with the following code as base:
4. When creating a pull request, please provide a video of the template working in action.
```typescript
// EXAMPLE
import {
generateHash,
generateRandomDomain,
type Template,
type Schema,
} from "../utils";
export function generate(schema: Schema): Template {
// do your stuff here, like create a new domain, generate random passwords, mounts.
const mainServiceHash = generateHash(schema.projectName);
const randomDomain = generateRandomDomain(schema);
const secretBase = generateBase64(64);
const toptKeyBase = generateBase64(32);
const envs = [
// If you want to show a domain in the UI, please add the prefix _HOST at the end of the variable name.
`PLAUSIBLE_HOST=${randomDomain}`,
"PLAUSIBLE_PORT=8000",
`BASE_URL=http://${randomDomain}`,
`SECRET_KEY_BASE=${secretBase}`,
`TOTP_VAULT_KEY=${toptKeyBase}`,
`HASH=${mainServiceHash}`,
];
const mounts: Template["mounts"] = [
{
mountPath: "./clickhouse/clickhouse-config.xml",
content: `some content......`,
},
];
return {
envs,
mounts,
};
}
```
4. Now you need to add the information about the template to the `templates/templates.ts` is a object with the following properties:
**Make sure the id of the template is the same as the folder name and don't have any spaces, only slugified names and lowercase.**
```typescript
{
id: "plausible",
name: "Plausible",
version: "v2.1.0",
description:
"Plausible is a open source, self-hosted web analytics platform that lets you track website traffic and user behavior.",
logo: "plausible.svg", // we defined the name and the extension of the logo
links: {
github: "https://github.com/plausible/plausible",
website: "https://plausible.io/",
docs: "https://plausible.io/docs",
},
tags: ["analytics"],
load: () => import("./plausible/index").then((m) => m.generate),
},
```
5. Add the logo or image of the template to `public/templates/plausible.svg`
### Recomendations
- 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.
- Test first on a vps or a server to make sure the template works.

View File

@@ -121,7 +121,7 @@ export const UpdateApplication = ({ applicationId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -121,7 +121,7 @@ export const UpdateCompose = ({ composeId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -1,5 +1,6 @@
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Button } from "@/components/ui/button";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -23,6 +24,7 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import Link from "next/link";
const DockerProviderSchema = z.object({
externalPort: z.preprocess((a) => {
@@ -106,6 +108,17 @@ export const ShowExternalMariadbCredentials = ({ mariadbId }: Props) => {
</CardDescription>
</CardHeader>
<CardContent className="flex w-full flex-col gap-4">
{!getIp && (
<AlertBlock type="warning">
You need to set an IP address in your{" "}
<Link href="/dashboard/settings" className="text-primary">
{data?.serverId
? "Remote Servers -> Server -> Edit Server -> Update IP Address"
: "Web Server -> Server -> Update Server IP"}
</Link>{" "}
to fix the database url connection.
</AlertBlock>
)}
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}

View File

@@ -119,7 +119,7 @@ export const UpdateMariadb = ({ mariadbId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -1,5 +1,6 @@
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Button } from "@/components/ui/button";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -23,6 +24,7 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import Link from "next/link";
const DockerProviderSchema = z.object({
externalPort: z.preprocess((a) => {
@@ -106,6 +108,17 @@ export const ShowExternalMongoCredentials = ({ mongoId }: Props) => {
</CardDescription>
</CardHeader>
<CardContent className="flex w-full flex-col gap-4">
{!getIp && (
<AlertBlock type="warning">
You need to set an IP address in your{" "}
<Link href="/dashboard/settings" className="text-primary">
{data?.serverId
? "Remote Servers -> Server -> Edit Server -> Update IP Address"
: "Web Server -> Server -> Update Server IP"}
</Link>{" "}
to fix the database url connection.
</AlertBlock>
)}
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}

View File

@@ -121,7 +121,7 @@ export const UpdateMongo = ({ mongoId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -218,7 +218,7 @@ export const ContainerFreeMonitoring = ({
<CardContent>
<div className="flex flex-col gap-2 w-full">
<span className="text-sm text-muted-foreground">
Used: {currentData.cpu.value}%
Used: {currentData.cpu.value}
</span>
<Progress value={currentData.cpu.value} className="w-[100%]" />
<DockerCpuChart acummulativeData={acummulativeData.cpu} />

View File

@@ -1,5 +1,6 @@
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Button } from "@/components/ui/button";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -23,6 +24,7 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import Link from "next/link";
const DockerProviderSchema = z.object({
externalPort: z.preprocess((a) => {
@@ -106,6 +108,17 @@ export const ShowExternalMysqlCredentials = ({ mysqlId }: Props) => {
</CardDescription>
</CardHeader>
<CardContent className="flex w-full flex-col gap-4">
{!getIp && (
<AlertBlock type="warning">
You need to set an IP address in your{" "}
<Link href="/dashboard/settings" className="text-primary">
{data?.serverId
? "Remote Servers -> Server -> Edit Server -> Update IP Address"
: "Web Server -> Server -> Update Server IP"}
</Link>{" "}
to fix the database url connection.
</AlertBlock>
)}
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}

View File

@@ -119,7 +119,7 @@ export const UpdateMysql = ({ mysqlId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -1,5 +1,6 @@
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Button } from "@/components/ui/button";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -23,6 +24,7 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import Link from "next/link";
const DockerProviderSchema = z.object({
externalPort: z.preprocess((a) => {
@@ -108,6 +110,17 @@ export const ShowExternalPostgresCredentials = ({ postgresId }: Props) => {
</CardDescription>
</CardHeader>
<CardContent className="flex w-full flex-col gap-4">
{!getIp && (
<AlertBlock type="warning">
You need to set an IP address in your{" "}
<Link href="/dashboard/settings" className="text-primary">
{data?.serverId
? "Remote Servers -> Server -> Edit Server -> Update IP Address"
: "Web Server -> Server -> Update Server IP"}
</Link>{" "}
to fix the database url connection.
</AlertBlock>
)}
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}

View File

@@ -121,7 +121,7 @@ export const UpdatePostgres = ({ postgresId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -324,7 +324,7 @@ export const AddTemplate = ({ projectId, baseUrl }: Props) => {
)}
>
<img
src={`${customBaseUrl || "https://dokploy.github.io/templates"}/blueprints/${template.id}/${template.logo}`}
src={`${customBaseUrl || "https://templates.dokploy.com/"}/blueprints/${template.id}/${template.logo}`}
className={cn(
"object-contain",
viewMode === "detailed" ? "size-24" : "size-16",

View File

@@ -148,7 +148,7 @@ export const HandleProject = ({ projectId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -115,7 +115,7 @@ export const ShowProjects = () => {
</span>
</div>
)}
<div className="w-full grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 flex-wrap gap-5">
<div className="w-full grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 3xl:grid-cols-5 flex-wrap gap-5">
{filteredProjects?.map((project) => {
const emptyServices =
project?.mariadb.length === 0 &&

View File

@@ -1,5 +1,6 @@
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Button } from "@/components/ui/button";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -23,6 +24,7 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import Link from "next/link";
const DockerProviderSchema = z.object({
externalPort: z.preprocess((a) => {
@@ -100,6 +102,17 @@ export const ShowExternalRedisCredentials = ({ redisId }: Props) => {
</CardDescription>
</CardHeader>
<CardContent className="flex w-full flex-col gap-4">
{!getIp && (
<AlertBlock type="warning">
You need to set an IP address in your{" "}
<Link href="/dashboard/settings" className="text-primary">
{data?.serverId
? "Remote Servers -> Server -> Edit Server -> Update IP Address"
: "Web Server -> Server -> Update Server IP"}
</Link>{" "}
to fix the database url connection.
</AlertBlock>
)}
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}

View File

@@ -119,7 +119,7 @@ export const UpdateRedis = ({ redisId }: Props) => {
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Tesla" {...field} />
<Input placeholder="Vandelay Industries" {...field} />
</FormControl>
<FormMessage />

View File

@@ -64,12 +64,12 @@ export const Enable2FA = () => {
const handlePasswordSubmit = async (formData: PasswordForm) => {
setIsPasswordLoading(true);
try {
const { data: enableData } = await authClient.twoFactor.enable({
const { data: enableData, error } = await authClient.twoFactor.enable({
password: formData.password,
});
if (!enableData) {
throw new Error("No data received from server");
throw new Error(error?.message || "Error enabling 2FA");
}
if (enableData.backupCodes) {
@@ -95,7 +95,8 @@ export const Enable2FA = () => {
error instanceof Error ? error.message : "Error setting up 2FA",
);
passwordForm.setError("password", {
message: "Error verifying password",
message:
error instanceof Error ? error.message : "Error setting up 2FA",
});
} finally {
setIsPasswordLoading(false);

View File

@@ -1,3 +1,4 @@
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -23,6 +24,7 @@ import { Loader2 } from "lucide-react";
import dynamic from "next/dynamic";
import type React from "react";
import { useEffect, useState } from "react";
import { badgeStateColor } from "../../application/logs/show";
const Terminal = dynamic(
() =>
@@ -109,7 +111,10 @@ export const DockerTerminalModal = ({ children, appName, serverId }: Props) => {
key={container.containerId}
value={container.containerId}
>
{container.name} ({container.containerId}) {container.state}
{container.name} ({container.containerId}){" "}
<Badge variant={badgeStateColor(container.state)}>
{container.state}
</Badge>
</SelectItem>
))}
<SelectLabel>Containers ({data?.length})</SelectLabel>

View File

@@ -21,6 +21,8 @@ import { Loader2 } from "lucide-react";
import dynamic from "next/dynamic";
import type React from "react";
import { useEffect, useState } from "react";
import { badgeStateColor } from "../../application/logs/show";
import { Badge } from "@/components/ui/badge";
export const DockerLogsId = dynamic(
() =>
@@ -90,7 +92,10 @@ export const ShowModalLogs = ({
key={container.containerId}
value={container.containerId}
>
{container.name} ({container.containerId}) {container.state}
{container.name} ({container.containerId}){" "}
<Badge variant={badgeStateColor(container.state)}>
{container.state}
</Badge>
</SelectItem>
))}
<SelectLabel>Containers ({data?.length})</SelectLabel>

View File

@@ -1068,7 +1068,7 @@ export default function Page({ children }: Props) {
</header>
)}
<div className="flex flex-col w-full gap-4 p-4 pt-0">{children}</div>
<div className="flex flex-col w-full p-4 pt-0">{children}</div>
</SidebarInset>
</SidebarProvider>
);

View File

@@ -93,7 +93,7 @@
"adm-zip": "^0.5.14",
"ai": "^4.0.23",
"bcrypt": "5.1.1",
"better-auth": "1.2.0",
"better-auth": "1.2.4",
"bl": "6.0.11",
"boxen": "^7.1.1",
"bullmq": "5.4.2",

View File

@@ -1,6 +1,6 @@
{
"settings.common.save": "Save",
"settings.common.enterTerminal": "Enter the terminal",
"settings.common.enterTerminal": "Terminal",
"settings.server.domain.title": "Server Domain",
"settings.server.domain.description": "Add a domain to your server application.",
"settings.server.domain.form.domain": "Domain",
@@ -14,7 +14,7 @@
"settings.server.webServer.description": "Reload or clean the web server.",
"settings.server.webServer.actions": "Actions",
"settings.server.webServer.reload": "Reload",
"settings.server.webServer.watchLogs": "Watch logs",
"settings.server.webServer.watchLogs": "View Logs",
"settings.server.webServer.updateServerIp": "Update Server IP",
"settings.server.webServer.server.label": "Server",
"settings.server.webServer.traefik.label": "Traefik",

View File

@@ -437,13 +437,12 @@ export const composeRouter = createTRPCRouter({
serverIp = "127.0.0.1";
}
const projectName = slugify(`${project.name} ${input.id}`);
const generate = processTemplate(template.config, {
serverIp: serverIp,
projectName: project.name,
projectName: projectName,
});
const projectName = slugify(`${project.name} ${input.id}`);
const compose = await createComposeByTemplate({
...input,
composeFile: template.dockerCompose,

View File

@@ -22,6 +22,9 @@ const config = {
fontFamily: {
sans: ["var(--font-inter)", ...defaultTheme.fontFamily.sans],
},
screens: {
"3xl": "120rem",
},
maxWidth: {
"2xl": "40rem",
"8xl": "85rem",

View File

@@ -40,7 +40,7 @@
"@oslojs/encoding":"1.1.0",
"@oslojs/crypto":"1.0.1",
"drizzle-dbml-generator":"0.10.0",
"better-auth":"1.2.0",
"better-auth":"1.2.4",
"@faker-js/faker": "^8.4.1",
"@lucia-auth/adapter-drizzle": "1.0.7",
"@octokit/auth-app": "^6.0.4",

View File

@@ -28,6 +28,26 @@ const { handler, api } = betterAuth({
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
...(!IS_CLOUD && {
async trustedOrigins() {
const admin = await db.query.member.findFirst({
where: eq(schema.member.role, "owner"),
with: {
user: true,
},
});
if (admin) {
return [
...(admin.user.serverIp
? [`http://${admin.user.serverIp}:3000`]
: []),
...(admin.user.host ? [`https://${admin.user.host}`] : []),
];
}
return [];
},
}),
emailVerification: {
sendOnSignUp: true,
autoSignInAfterVerification: true,

46
pnpm-lock.yaml generated
View File

@@ -269,8 +269,8 @@ importers:
specifier: 5.1.1
version: 5.1.1(encoding@0.1.13)
better-auth:
specifier: 1.2.0
version: 1.2.0(typescript@5.5.3)
specifier: 1.2.4
version: 1.2.4(typescript@5.5.3)
bl:
specifier: 6.0.11
version: 6.0.11
@@ -303,10 +303,10 @@ importers:
version: 16.4.5
drizzle-orm:
specifier: ^0.39.1
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-zod:
specifier: 0.5.1
version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
fancy-ansi:
specifier: ^0.1.3
version: 0.1.3
@@ -547,7 +547,7 @@ importers:
version: 16.4.5
drizzle-orm:
specifier: ^0.39.1
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
hono:
specifier: ^4.5.8
version: 4.5.8
@@ -646,8 +646,8 @@ importers:
specifier: 5.1.1
version: 5.1.1(encoding@0.1.13)
better-auth:
specifier: 1.2.0
version: 1.2.0(typescript@5.5.3)
specifier: 1.2.4
version: 1.2.4(typescript@5.5.3)
bl:
specifier: 6.0.11
version: 6.0.11
@@ -665,13 +665,13 @@ importers:
version: 16.4.5
drizzle-dbml-generator:
specifier: 0.10.0
version: 0.10.0(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))
version: 0.10.0(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))
drizzle-orm:
specifier: ^0.39.1
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-zod:
specifier: 0.5.1
version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
hi-base32:
specifier: ^0.5.1
version: 0.5.1
@@ -4030,8 +4030,8 @@ packages:
before-after-hook@2.2.3:
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
better-auth@1.2.0:
resolution: {integrity: sha512-eIRGOXfix25bh4fgs8jslZAZssufpIkxfEeEokQu5G4wICoDee1wPctkFb8v80PvhtI4dPm28SuAoZaAdRc6Wg==}
better-auth@1.2.4:
resolution: {integrity: sha512-/ZK2jbUjm8JwdeCLFrUWUBmexPyI9PkaLVXWLWtN60sMDHTY8B5G72wcHglo1QMFBaw4G0qFkP5ayl9k6XfDaA==}
better-call@1.0.3:
resolution: {integrity: sha512-DUKImKoDIy5UtCvQbHTg0wuBRse6gu1Yvznn7+1B3I5TeY8sclRPFce0HI+4WF2bcb+9PqmkET8nXZubrHQh9A==}
@@ -5486,8 +5486,8 @@ packages:
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
kysely@0.27.5:
resolution: {integrity: sha512-s7hZHcQeSNKpzCkHRm8yA+0JPLjncSWnjb+2TIElwS2JAqYr+Kv3Ess+9KFfJS0C1xcQ1i9NkNHpWwCYpHMWsA==}
kysely@0.27.6:
resolution: {integrity: sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ==}
engines: {node: '>=14.0.0'}
leac@0.6.0:
@@ -10902,7 +10902,7 @@ snapshots:
before-after-hook@2.2.3: {}
better-auth@1.2.0(typescript@5.5.3):
better-auth@1.2.4(typescript@5.5.3):
dependencies:
'@better-auth/utils': 0.2.3
'@better-fetch/fetch': 1.1.15
@@ -10913,7 +10913,7 @@ snapshots:
better-call: 1.0.3
defu: 6.1.4
jose: 5.9.6
kysely: 0.27.5
kysely: 0.27.6
nanostores: 0.11.3
valibot: 1.0.0-beta.15(typescript@5.5.3)
zod: 3.24.1
@@ -11534,9 +11534,9 @@ snapshots:
drange@1.1.1: {}
drizzle-dbml-generator@0.10.0(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)):
drizzle-dbml-generator@0.10.0(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)):
dependencies:
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-kit@0.30.4:
dependencies:
@@ -11547,18 +11547,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7):
drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7):
optionalDependencies:
'@opentelemetry/api': 1.9.0
'@types/react': 18.3.5
kysely: 0.27.5
kysely: 0.27.6
postgres: 3.4.4
react: 18.2.0
sqlite3: 5.1.7
drizzle-zod@0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8):
drizzle-zod@0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8):
dependencies:
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
zod: 3.23.8
eastasianwidth@0.2.0: {}
@@ -12450,7 +12450,7 @@ snapshots:
dependencies:
json-buffer: 3.0.1
kysely@0.27.5: {}
kysely@0.27.6: {}
leac@0.6.0: {}