Compare commits

...

41 Commits

Author SHA1 Message Date
Mauricio Siu
9b2fcaea31 Merge pull request #317 from Dokploy/canary
v0.6.1
2024-08-03 15:46:05 -06:00
Mauricio Siu
2ffa95b9fa chore(version): bump version 2024-08-03 15:34:09 -06:00
Mauricio Siu
559872c4e4 Merge pull request #316 from Dokploy/315-docs-website-error-dialogclose-must-be-used-within-dialog
fix(docs): update dependencies
2024-08-03 15:32:36 -06:00
Mauricio Siu
85642ed5f2 refactor(docs): add volumes deployments 2024-08-03 15:14:02 -06:00
Mauricio Siu
8bf701d2f2 fix(docs): update dependencies 2024-08-03 15:06:47 -06:00
Mauricio Siu
38809a2034 Merge pull request #314 from Dokploy/fix/add-file-path
fix(template): add missing file path
2024-08-03 15:05:31 -06:00
Mauricio Siu
4bd6ec2232 fix(templates): use filePath instead of mountPath 2024-08-03 14:59:20 -06:00
Mauricio Siu
95899b7208 fix(templates): update path file path 2024-08-02 13:45:20 -06:00
Mauricio Siu
ac26bb95e3 fix(template): add missing file path 2024-08-02 13:40:25 -06:00
Mauricio Siu
5abcc82215 Merge pull request #312 from Dokploy/canary
v0.6.0
2024-08-02 10:47:43 -06:00
Mauricio Siu
16791a9f4b refactor: remove console log 2024-08-02 10:44:39 -06:00
Mauricio Siu
54ab6e3436 chore(version): bump version 2024-08-02 10:36:06 -06:00
Mauricio Siu
f5ca72ddd7 refactor: add default value to context path 2024-08-02 10:18:41 -06:00
Mauricio Siu
7245e7dfd7 Merge pull request #310 from Dokploy/fix/docker-context
fix(docker-context): add docker context path #284
2024-08-02 09:52:27 -06:00
Mauricio Siu
547d149987 Merge pull request #311 from kucherenko/canary
docs(templates): add documentation about teable and open webui templates
2024-08-02 09:52:05 -06:00
apk
3b2d29514c fix(docs): type in description 2024-08-02 11:20:45 +03:00
apk
115abd378f docs(templates): add information about open webui and about teable to documention 2024-08-02 11:18:32 +03:00
Mauricio Siu
9c101d78d1 Merge pull request #305 from kucherenko/canary
feat(template): add teable template
2024-08-02 01:06:53 -06:00
apk
610f8fa5bc fix(teable): remove network 2024-08-02 09:57:36 +03:00
Mauricio Siu
e201bf12f8 fix(test): add missing prop 2024-08-02 00:28:17 -06:00
Mauricio Siu
bf872200a7 refactor(docker): add type password to input 2024-08-02 00:25:44 -06:00
Mauricio Siu
abc6906349 fix(docker-context): add docker context path #284 2024-08-02 00:22:37 -06:00
apk
9440fd89ae fix(teable): round port for public database 2024-08-02 08:29:53 +03:00
apk
bce1eb8907 fix(teable): port for public database 2024-08-02 08:27:17 +03:00
apk
4bf44b3275 fix(docker-compose): issue with volumes, issue with database connection 2024-08-01 22:05:36 +03:00
Andrey Kucherenko
06355ff089 fix(taeble): version and env variables 2024-08-01 19:27:07 +03:00
Mauricio Siu
95ecf4fe21 Merge pull request #309 from ca110us/canary
fix: align entry point names in configs
2024-08-01 10:19:45 -06:00
ian
d50a6ce76f fix: align entry point names in configs 2024-08-01 23:53:53 +08:00
Mauricio Siu
2d951e0b1f Merge pull request #307 from Dokploy/306-fix-containers-are-deleted-when-dokploy-server-restart
fix(swarm): remove restart policy #306
2024-08-01 09:53:44 -06:00
Mauricio Siu
416de9879b fix(swarm): remove restart policy #306 2024-08-01 09:31:58 -06:00
Mauricio Siu
082aff58a9 chore: add ref query to links 2024-08-01 09:12:25 -06:00
Mauricio Siu
b74666fc2f Merge pull request #304 from lorenzomigliorero/feat/static-buildtype
feat: static buildtype
2024-08-01 09:11:02 -06:00
Andrey Kucherenko
dc626f1a94 chore(lint): fix formating 2024-08-01 13:00:03 +03:00
Andrey Kucherenko
533a5e490f feat(template): add teable template (one more no/low-code database) 2024-08-01 12:13:36 +03:00
Lorenzo Migliorero
cf54e4f5c2 feat: add static migration 2024-08-01 11:10:52 +02:00
Lorenzo Migliorero
d84c808887 feat: add build static 2024-08-01 11:10:28 +02:00
Andrey Kucherenko
89cd35adc6 chore(gitignore): add .idea folder to gitignore file 2024-08-01 11:34:09 +03:00
Mauricio Siu
6299385bb4 Merge pull request #297 from lorenzomigliorero/feat/static-build-phase
feat: new publish directory flag
2024-08-01 02:28:37 -06:00
Lorenzo Migliorero
e6f9867500 fix: error handling 2024-08-01 10:13:29 +02:00
Lorenzo Migliorero
3fdd3ddc74 fix: missing type 2024-07-31 19:27:11 +02:00
Lorenzo Migliorero
6ed379243e feat: add publish directory flag 2024-07-31 19:08:34 +02:00
35 changed files with 9558 additions and 118 deletions

1
.gitignore vendored
View File

@@ -35,6 +35,7 @@ yarn-error.log*
# Editor
.vscode
.idea
# Misc
.DS_Store

View File

@@ -59,7 +59,7 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
### Premium Supporters 🥇
<div style="display: flex; gap: 30px; flex-wrap: wrap;">
<a href="https://supafort.com/" target="_blank"><img src="https://supafort.com/build/q-4Ht4rBZR.webp" alt="Supafort.com" width="190"/></a>
<a href="https://supafort.com/?ref=dokploy" target="_blank"><img src="https://supafort.com/build/q-4Ht4rBZR.webp" alt="Supafort.com" width="190"/></a>
</div>
<!-- Elite Contributors 🥈 -->
@@ -69,13 +69,13 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
### Supporting Members 🥉
<div style="display: flex; gap: 30px; flex-wrap: wrap;">
<a href="https://lightspeed.run/"><img src="https://github.com/lightspeedrun.png" width="60px" alt="Lightspeed.run"/></a>
<a href="https://lightspeed.run/?ref=dokploy"><img src="https://github.com/lightspeedrun.png" width="60px" alt="Lightspeed.run"/></a>
</div>
### Community Backers 🤝
<div style="display: flex; gap: 30px; flex-wrap: wrap;">
<a href="https://steamsets.com/"><img src="https://avatars.githubusercontent.com/u/111978405?s=200&v=4" width="60px" alt="Steamsets.com"/></a>
<a href="https://steamsets.com/?ref=dokploy"><img src="https://avatars.githubusercontent.com/u/111978405?s=200&v=4" width="60px" alt="Steamsets.com"/></a>
</div>
#### Organizations:

View File

@@ -3,13 +3,14 @@ title: "Overview"
description: "Learn how to use Docker Compose with Dokploy"
---
import { Callout } from "fumadocs-ui/components/callout";
Dokploy integrates with Docker Compose and Docker Stack to provide flexible deployment solutions. Whether you are developing locally or deploying at scale, Dokploy facilitates application management through these powerful Docker tools.
### Configuration Methods
Dokploy provides two methods for creating Docker Compose configurations:
- **Docker Compose**: Ideal for standard Docker Compose configurations.
- **Stack**: Geared towards orchestrating applications using Docker Swarm. Note that some Docker Compose features, such as `build`, are not available in this mode.
@@ -21,7 +22,7 @@ Configure the source of your code, the way your application is built, and also m
A code editor within Dokploy allows you to specify environment variables for your Docker Compose file. By default, Dokploy creates a `.env` file in the specified Docker Compose file path.
### Monitoring
### Monitoring
Monitor each service individually within Dokploy. If your application consists of multiple services, each can be monitored separately to ensure optimal performance.
@@ -29,7 +30,6 @@ Monitor each service individually within Dokploy. If your application consists o
Access detailed logs for each service through the Dokploy log viewer, which can help in troubleshooting and ensuring the stability of your services.
### Deployments
You can view the last 10 deployments of your application. When you deploy your application in real time, a new deployment record will be created and it will gradually show you how your application is being built.
@@ -38,7 +38,6 @@ We also offer a button to cancel deployments that are in queue. Note that those
We provide a webhook so that you can trigger your own deployments by pushing to your GitHub, Gitea, GitLab, Bitbucket repository.
### Advanced
This section provides advanced configuration options for experienced users. It includes tools for custom commands within the container and volumes.
@@ -46,4 +45,32 @@ This section provides advanced configuration options for experienced users. It i
- **Command**: Dokploy has a defined command to run the Docker Compose file, ensuring complete control through the UI. However, you can append flags or options to the command.
- **Volumes**: To ensure data persistence across deployments, configure storage volumes for your application.
<ImageZoom src="/assets/images/compose/overview.png" width={800} height={630} quality={100} priority alt='home og image' className="rounded-lg" />
<ImageZoom
src="/assets/images/compose/overview.png"
width={800}
height={630}
quality={100}
priority
alt="home og image"
className="rounded-lg"
/>
<Callout title="Volumes">
Docker volumes are a way to persist data generated and used by Docker containers. They are particularly useful for maintaining data between container restarts or for sharing data among different containers.
To bind a volume to the host machine, you can use the following syntax in your docker-compose.yml file, but this way will clean up the volumes when a new deployment is made:
```yaml
volumes:
- "/folder:/path/in/container" ❌
```
It's recommended to use the ../files folder to ensure your data persists between deployments. For example:
```yaml
volumes:
- "../files/my-database:/var/lib/mysql" ✅
- "../files/my-configs:/etc/my-app/config" ✅
```
</Callout>

View File

@@ -32,7 +32,8 @@ The following templates are available:
- **Metabase**: Open Source Business Intelligence
- **Grafana**: Open Source Dashboard for your metrics
- **Wordpress**: Open Source Content Management System
- **Open WebUI**: Free and Open Source ChatGPT Alternative
- **Teable**: Open Source Airtable Alternative, Developer Friendly, No-code Database Built on Postgres
@@ -42,4 +43,4 @@ We accept contributions to upload new templates to the dokploy repository.
Make sure to follow the guidelines for creating a template:
[Steps to create your own template](https://github.com/Dokploy/dokploy/blob/canary/CONTRIBUTING.md#templates)
[Steps to create your own template](https://github.com/Dokploy/dokploy/blob/canary/CONTRIBUTING.md#templates)

View File

@@ -10,10 +10,10 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"fumadocs-core": "12.2.2",
"fumadocs-mdx": "8.2.33",
"fumadocs-openapi": "^3.1.3",
"fumadocs-ui": "12.2.2",
"fumadocs-core": "^12.5.6",
"fumadocs-mdx": "^8.2.34",
"fumadocs-openapi": "^3.3.0",
"fumadocs-ui": "^12.5.6",
"lucide-react": "^0.394.0",
"next": "^14.2.4",
"react": "^18.3.1",

View File

@@ -78,7 +78,7 @@ test("Should not touch config without host", () => {
expect(originalConfig).toEqual(config);
});
test("Should remove web-secure if https rollback to http", () => {
test("Should remove websecure if https rollback to http", () => {
const originalConfig: FileConfig = loadOrCreateConfig("dokploy");
updateServerTraefik(

View File

@@ -40,6 +40,7 @@ const baseApp: ApplicationNested = {
placementSwarm: null,
ports: [],
projectId: "",
publishDirectory: null,
redirects: [],
refreshToken: "",
registry: null,
@@ -54,6 +55,7 @@ const baseApp: ApplicationNested = {
title: null,
updateConfigSwarm: null,
username: null,
dockerContextPath: null,
};
const baseDomain: Domain = {

View File

@@ -3,6 +3,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
@@ -23,6 +24,7 @@ enum BuildType {
heroku_buildpacks = "heroku_buildpacks",
paketo_buildpacks = "paketo_buildpacks",
nixpacks = "nixpacks",
static = "static",
}
const mySchema = z.discriminatedUnion("buildType", [
@@ -34,6 +36,7 @@ const mySchema = z.discriminatedUnion("buildType", [
invalid_type_error: "Dockerfile path is required",
})
.min(1, "Dockerfile required"),
dockerContextPath: z.string().nullable().default(""),
}),
z.object({
buildType: z.literal("heroku_buildpacks"),
@@ -43,6 +46,10 @@ const mySchema = z.discriminatedUnion("buildType", [
}),
z.object({
buildType: z.literal("nixpacks"),
publishDirectory: z.string().optional(),
}),
z.object({
buildType: z.literal("static"),
}),
]);
@@ -73,17 +80,18 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
const buildType = form.watch("buildType");
useEffect(() => {
if (data) {
// TODO: refactor this
if (data.buildType === "dockerfile") {
form.reset({
buildType: data.buildType,
...(data.buildType && {
dockerfile: data.dockerfile || "",
dockerContextPath: data.dockerContextPath || "",
}),
});
} else {
form.reset({
buildType: data.buildType,
publishDirectory: data.publishDirectory || undefined,
});
}
}
@@ -93,7 +101,11 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
await mutateAsync({
applicationId,
buildType: data.buildType,
publishDirectory:
data.buildType === "nixpacks" ? data.publishDirectory : null,
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
dockerContextPath:
data.buildType === "dockerfile" ? data.dockerContextPath : null,
})
.then(async () => {
toast.success("Build type saved");
@@ -171,6 +183,12 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
Paketo Buildpacks
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="static" />
</FormControl>
<FormLabel className="font-normal">Static</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
@@ -179,16 +197,71 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
}}
/>
{buildType === "dockerfile" && (
<>
<FormField
control={form.control}
name="dockerfile"
render={({ field }) => {
return (
<FormItem>
<FormLabel>Docker File</FormLabel>
<FormControl>
<Input
placeholder={"Path of your docker file"}
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
<FormField
control={form.control}
name="dockerContextPath"
render={({ field }) => {
return (
<FormItem>
<FormLabel>Docker Context Path</FormLabel>
<FormControl>
<Input
placeholder={
"Path of your docker context default: ."
}
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
</>
)}
{buildType === "nixpacks" && (
<FormField
control={form.control}
name="dockerfile"
name="publishDirectory"
render={({ field }) => {
return (
<FormItem>
<FormLabel>Docker File</FormLabel>
<div className="space-y-0.5">
<FormLabel>Publish Directory</FormLabel>
<FormDescription>
Allows you to serve a single directory via NGINX after
the build phase. Useful if the final build assets
should be served as a static site.
</FormDescription>
</div>
<FormControl>
<Input
placeholder={"Path of your docker file"}
placeholder={"Publish Directory"}
{...field}
value={field.value ?? ""}
/>

View File

@@ -114,7 +114,7 @@ export const SaveDockerProvider = ({ applicationId }: Props) => {
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input placeholder="Password" {...field} />
<Input placeholder="Password" {...field} type="password" />
</FormControl>
<FormMessage />
</FormItem>

View File

@@ -0,0 +1 @@
ALTER TABLE "application" ADD COLUMN "publishDirectory" text;

View File

@@ -0,0 +1 @@
ALTER TYPE "buildType" ADD VALUE 'static';

View File

@@ -0,0 +1 @@
ALTER TABLE "application" ADD COLUMN "dockerContextPath" text;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -190,6 +190,27 @@
"when": 1721979220929,
"tag": "0026_known_dormammu",
"breakpoints": true
},
{
"idx": 27,
"version": "6",
"when": 1722445099203,
"tag": "0027_red_lady_bullseye",
"breakpoints": true
},
{
"idx": 28,
"version": "6",
"when": 1722503439951,
"tag": "0028_jittery_eternity",
"breakpoints": true
},
{
"idx": 29,
"version": "6",
"when": 1722578386823,
"tag": "0029_colossal_zodiak",
"breakpoints": true
}
]
}

View File

@@ -1,6 +1,6 @@
{
"name": "dokploy",
"version": "v0.5.1",
"version": "v0.6.1",
"private": true,
"license": "Apache-2.0",
"type": "module",

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

View File

@@ -191,6 +191,8 @@ export const applicationRouter = createTRPCRouter({
await updateApplication(input.applicationId, {
buildType: input.buildType,
dockerfile: input.dockerfile,
publishDirectory: input.publishDirectory,
dockerContextPath: input.dockerContextPath,
});
return true;

View File

@@ -227,7 +227,8 @@ export const composeRouter = createTRPCRouter({
if (mounts && mounts?.length > 0) {
for (const mount of mounts) {
await createMount({
mountPath: mount.mountPath,
filePath: mount.filePath,
mountPath: "",
content: mount.content,
serviceId: compose.composeId,
serviceType: "compose",

View File

@@ -35,6 +35,7 @@ export const buildType = pgEnum("buildType", [
"heroku_buildpacks",
"paketo_buildpacks",
"nixpacks",
"static",
]);
// TODO: refactor this types
@@ -140,6 +141,7 @@ export const applications = pgTable("application", {
},
),
dockerfile: text("dockerfile"),
dockerContextPath: text("dockerContextPath"),
// Drop
dropBuildPath: text("dropBuildPath"),
// Docker swarm json
@@ -157,6 +159,7 @@ export const applications = pgTable("application", {
.notNull()
.default("idle"),
buildType: buildType("buildType").notNull().default("nixpacks"),
publishDirectory: text("publishDirectory"),
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
@@ -315,7 +318,9 @@ const createSchema = createInsertSchema(applications, {
"heroku_buildpacks",
"paketo_buildpacks",
"nixpacks",
"static",
]),
publishDirectory: z.string().optional(),
owner: z.string(),
healthCheckSwarm: HealthCheckSwarmSchema.nullable(),
restartPolicySwarm: RestartPolicySwarmSchema.nullable(),
@@ -352,8 +357,10 @@ export const apiSaveBuildType = createSchema
applicationId: true,
buildType: true,
dockerfile: true,
dockerContextPath: true,
})
.required();
.required()
.merge(createSchema.pick({ publishDirectory: true }));
export const apiSaveGithubProvider = createSchema
.pick({

View File

@@ -1,7 +1,10 @@
import type { WriteStream } from "node:fs";
import { prepareEnvironmentVariables } from "@/server/utils/docker/utils";
import type { ApplicationNested } from ".";
import { getBuildAppDirectory } from "../filesystem/directory";
import {
getBuildAppDirectory,
getDockerContextPath,
} from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
import { createEnvFile } from "./utils";
@@ -9,22 +12,30 @@ export const buildCustomDocker = async (
application: ApplicationNested,
writeStream: WriteStream,
) => {
const { appName, env, buildArgs } = application;
const { appName, env, publishDirectory, buildArgs } = application;
const dockerFilePath = getBuildAppDirectory(application);
try {
const image = `${appName}`;
const contextPath =
const defaultContextPath =
dockerFilePath.substring(0, dockerFilePath.lastIndexOf("/") + 1) || ".";
const args = prepareEnvironmentVariables(buildArgs);
const dockerContextPath = getDockerContextPath(application);
const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."];
for (const arg of args) {
commandArgs.push("--build-arg", arg);
}
/*
Do not generate an environment file when publishDirectory is specified,
as it could be publicly exposed.
*/
if (!publishDirectory) {
createEnvFile(dockerFilePath, env);
}
createEnvFile(dockerFilePath, env);
await spawnAsync(
"docker",
commandArgs,
@@ -34,7 +45,7 @@ export const buildCustomDocker = async (
}
},
{
cwd: contextPath,
cwd: dockerContextPath || defaultContextPath,
},
);
} catch (error) {

View File

@@ -15,6 +15,7 @@ import { buildCustomDocker } from "./docker-file";
import { buildHeroku } from "./heroku";
import { buildNixpacks } from "./nixpacks";
import { buildPaketo } from "./paketo";
import { buildStatic } from "./static";
// NIXPACKS codeDirectory = where is the path of the code directory
// HEROKU codeDirectory = where is the path of the code directory
@@ -43,6 +44,8 @@ export const buildApplication = async (
await buildPaketo(application, writeStream);
} else if (buildType === "dockerfile") {
await buildCustomDocker(application, writeStream);
} else if (buildType === "static") {
await buildStatic(application, writeStream);
}
if (application.registryId) {

View File

@@ -1,18 +1,28 @@
import type { WriteStream } from "node:fs";
import path from "node:path";
import { buildStatic } from "@/server/utils/builders/static";
import { nanoid } from "nanoid";
import type { ApplicationNested } from ".";
import { prepareEnvironmentVariables } from "../docker/utils";
import { getBuildAppDirectory } from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
// TODO: integrate in the vps sudo chown -R $(whoami) ~/.docker
export const buildNixpacks = async (
application: ApplicationNested,
writeStream: WriteStream,
) => {
const { env, appName } = application;
const buildAppDirectory = getBuildAppDirectory(application);
const { env, appName, publishDirectory } = application;
const buildAppDirectory = getBuildAppDirectory(application);
const buildContainerId = `${appName}-${nanoid(10)}`;
const envVariables = prepareEnvironmentVariables(env);
const writeToStream = (data: string) => {
if (writeStream.writable) {
writeStream.write(data);
}
};
try {
const args = ["build", buildAppDirectory, "--name", appName];
@@ -20,13 +30,44 @@ export const buildNixpacks = async (
args.push("--env", env);
}
await spawnAsync("nixpacks", args, (data) => {
if (writeStream.writable) {
writeStream.write(data);
}
});
if (publishDirectory) {
/* No need for any start command, since we'll use nginx later on */
args.push("--no-error-without-start");
}
await spawnAsync("nixpacks", args, writeToStream);
/*
Run the container with the image created by nixpacks,
and copy the artifacts on the host filesystem.
Then, remove the container and create a static build.
*/
if (publishDirectory) {
await spawnAsync(
"docker",
["create", "--name", buildContainerId, appName],
writeToStream,
);
await spawnAsync(
"docker",
[
"cp",
`${buildContainerId}:/app/${publishDirectory}`,
path.join(buildAppDirectory, publishDirectory),
],
writeToStream,
);
await spawnAsync("docker", ["rm", buildContainerId], writeToStream);
await buildStatic(application, writeStream);
}
return true;
} catch (e) {
await spawnAsync("docker", ["rm", buildContainerId], writeToStream);
throw e;
}
};

View File

@@ -0,0 +1,38 @@
import type { WriteStream } from "node:fs";
import { buildCustomDocker } from "@/server/utils/builders/docker-file";
import type { ApplicationNested } from ".";
import { createFile } from "../docker/utils";
import { getBuildAppDirectory } from "../filesystem/directory";
export const buildStatic = async (
application: ApplicationNested,
writeStream: WriteStream,
) => {
const { publishDirectory } = application;
const buildAppDirectory = getBuildAppDirectory(application);
try {
createFile(
buildAppDirectory,
"Dockerfile",
[
"FROM nginx:alpine",
"WORKDIR /usr/share/nginx/html/",
`COPY ${publishDirectory || "."} .`,
].join("\n"),
);
await buildCustomDocker(
{
...application,
buildType: "dockerfile",
dockerfile: "Dockerfile",
},
writeStream,
);
return true;
} catch (e) {
throw e;
}
};

View File

@@ -242,12 +242,7 @@ export const generateConfigContainer = (application: ApplicationNested) => {
? {
RestartPolicy: restartPolicySwarm,
}
: {
// if no restartPolicySwarm provided use default
RestartPolicy: {
Condition: "on-failure",
},
}),
: {}),
...(placementSwarm
? {
Placement: placementSwarm,

View File

@@ -89,3 +89,12 @@ export const getBuildAppDirectory = (application: Application) => {
return path.join(APPLICATIONS_PATH, appName, "code", buildPath ?? "");
};
export const getDockerContextPath = (application: Application) => {
const { appName, dockerContextPath } = application;
if (!dockerContextPath) {
return null;
}
return path.join(APPLICATIONS_PATH, appName, "code", dockerContextPath);
};

View File

@@ -25,7 +25,7 @@ export const updateServerTraefik = (
if (admin?.certificateType === "letsencrypt") {
config.http.routers[`${appName}-router-app-secure`] = {
...currentRouterConfig,
entryPoints: ["web-secure"],
entryPoints: ["websecure"],
tls: { certResolver: "letsencrypt" },
};

View File

@@ -21,7 +21,7 @@ export function generate(schema: Schema): Template {
const mounts: Template["mounts"] = [
{
mountPath: "./config.toml",
filePath: "config.toml",
content: `[app]
address = "0.0.0.0:9000"

View File

@@ -23,7 +23,7 @@ export function generate(schema: Schema): Template {
const mounts: Template["mounts"] = [
{
mountPath: "./clickhouse/clickhouse-config.xml",
filePath: "/clickhouse/clickhouse-config.xml",
content: `
<clickhouse>
<logger>
@@ -45,7 +45,7 @@ export function generate(schema: Schema): Template {
`,
},
{
mountPath: "./clickhouse/clickhouse-user-config.xml",
filePath: "/clickhouse/clickhouse-user-config.xml",
content: `
<clickhouse>
<profiles>

View File

@@ -0,0 +1,81 @@
version: "3.9"
services:
teable:
image: ghcr.io/teableio/teable:1.3.1-alpha-build.460
restart: always
ports:
- ${TEABLE_PORT}
volumes:
- teable-data:/app/.assets
# you may use a bind-mounted host directory instead,
# so that it is harder to accidentally remove the volume and lose all your data!
# - ./docker/teable/data:/app/.assets:rw
environment:
- TZ=${TIMEZONE}
- NEXT_ENV_IMAGES_ALL_REMOTE=true
- PUBLIC_ORIGIN=${PUBLIC_ORIGIN}
- PRISMA_DATABASE_URL=${PRISMA_DATABASE_URL}
- PUBLIC_DATABASE_PROXY=${PUBLIC_DATABASE_PROXY}
- BACKEND_MAIL_HOST=${BACKEND_MAIL_HOST}
- BACKEND_MAIL_PORT=${BACKEND_MAIL_PORT}
- BACKEND_MAIL_SECURE=${BACKEND_MAIL_SECURE}
- BACKEND_MAIL_SENDER=${BACKEND_MAIL_SENDER}
- BACKEND_MAIL_SENDER_NAME=${BACKEND_MAIL_SENDER_NAME}
- BACKEND_MAIL_AUTH_USER=${BACKEND_MAIL_AUTH_USER}
- BACKEND_MAIL_AUTH_PASS=${BACKEND_MAIL_AUTH_PASS}
networks:
- dokploy-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.${HASH}.rule=Host(`${TEABLE_HOST}`)"
- "traefik.http.services.${HASH}.loadbalancer.server.port=${TEABLE_PORT}"
depends_on:
teable-db-migrate:
condition: service_completed_successfully
teable-db:
image: postgres:15.4
restart: always
ports:
- "${TEABLE_DB_PORT}:${POSTGRES_PORT}"
volumes:
- teable-db:/var/lib/postgresql/data
# you may use a bind-mounted host directory instead,
# so that it is harder to accidentally remove the volume and lose all your data!
# - ./docker/db/data:/var/lib/postgresql/data:rw
environment:
- TZ=${TIMEZONE}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
networks:
- dokploy-network
healthcheck:
test:
[
"CMD-SHELL",
"sh -c 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}'",
]
interval: 10s
timeout: 3s
retries: 3
teable-db-migrate:
image: ghcr.io/teableio/teable-db-migrate:latest
environment:
- TZ=${TIMEZONE}
- PRISMA_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
networks:
- dokploy-network
depends_on:
teable-db:
condition: service_healthy
networks:
dokploy-network:
external: true
volumes:
teable-data: {}
teable-db: {}

View File

@@ -0,0 +1,48 @@
import {
type Schema,
type Template,
generateHash,
generatePassword,
generateRandomDomain,
} from "../utils";
export function generate(schema: Schema): Template {
const mainServiceHash = generateHash(schema.projectName);
const password = generatePassword();
const randomDomain = generateRandomDomain(schema);
const publicDbPort = ((min: number, max: number) => {
return Math.round(Math.random() * (max - min) + min);
})(32769, 65534);
const envs = [
`TEABLE_HOST=${randomDomain}`,
"TEABLE_PORT=3000",
`TEABLE_DB_PORT=${publicDbPort}`,
`HASH=${mainServiceHash}`,
"TIMEZONE=UTC",
"# Postgres",
"POSTGRES_HOST=teable-db",
"POSTGRES_PORT=5432",
"POSTGRES_DB=teable",
"POSTGRES_USER=teable",
`POSTGRES_PASSWORD=${password}`,
"# App",
"PUBLIC_ORIGIN=https://${TEABLE_HOST}",
"PRISMA_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}",
"PUBLIC_DATABASE_PROXY=${TEABLE_HOST}:${TEABLE_DB_PORT}",
"# Need to support sending emails to enable the following configurations",
"# You need to modify the configuration according to the actual situation, otherwise it will not be able to send emails correctly.",
"#BACKEND_MAIL_HOST=smtp.teable.io",
"#BACKEND_MAIL_PORT=465",
"#BACKEND_MAIL_SECURE=true",
"#BACKEND_MAIL_SENDER=noreply.teable.io",
"#BACKEND_MAIL_SENDER_NAME=Teable",
"#BACKEND_MAIL_AUTH_USER=username",
"#BACKEND_MAIL_AUTH_PASS=password",
];
return {
envs,
};
}

View File

@@ -393,4 +393,19 @@ export const templates: TemplateData[] = [
tags: ["media system"],
load: () => import("./jellyfin/index").then((m) => m.generate),
},
{
id: "teable",
name: "teable",
version: "v1.3.1-alpha-build.460",
description:
"Teable is a Super fast, Real-time, Professional, Developer friendly, No-code database built on Postgres. It uses a simple, spreadsheet-like interface to create complex enterprise-level database applications. Unlock efficient app development with no-code, free from the hurdles of data security and scalability.",
logo: "teable.png",
links: {
github: "https://github.com/teableio/teable",
website: "https://teable.io/",
docs: "https://help.teable.io/",
},
tags: ["database", "spreadsheet", "low-code", "nocode"],
load: () => import("./teable/index").then((m) => m.generate),
},
];

View File

@@ -13,7 +13,7 @@ export interface Schema {
export interface Template {
envs: string[];
mounts?: {
mountPath: string;
filePath: string;
content?: string;
}[];
}

147
pnpm-lock.yaml generated
View File

@@ -39,17 +39,17 @@ importers:
apps/docs:
dependencies:
fumadocs-core:
specifier: 12.2.2
version: 12.2.2(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
specifier: ^12.5.6
version: 12.5.6(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
fumadocs-mdx:
specifier: 8.2.33
version: 8.2.33(fumadocs-core@12.2.2(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
specifier: ^8.2.34
version: 8.2.34(fumadocs-core@12.5.6(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
fumadocs-openapi:
specifier: ^3.1.3
specifier: ^3.3.0
version: 3.3.0
fumadocs-ui:
specifier: 12.2.2
version: 12.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.7)
specifier: ^12.5.6
version: 12.5.6(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.7)
lucide-react:
specifier: ^0.394.0
version: 0.394.0(react@18.3.1)
@@ -2251,6 +2251,19 @@ packages:
'@types/react-dom':
optional: true
'@radix-ui/react-accordion@1.2.0':
resolution: {integrity: sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-alert-dialog@1.1.1':
resolution: {integrity: sha512-wmCoJwj7byuVuiLKqDLlX7ClSUU0vd9sdCeM+2Ls+uf13+cpSJoMgwysHq1SGVVkJj5Xn0XWi1NoRCdkMpr6Mw==}
peerDependencies:
@@ -2316,6 +2329,19 @@ packages:
'@types/react-dom':
optional: true
'@radix-ui/react-collapsible@1.1.0':
resolution: {integrity: sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-collection@1.0.3':
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
peerDependencies:
@@ -5409,15 +5435,15 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
fumadocs-core@12.2.2:
resolution: {integrity: sha512-e8WZ/+iNUuqsxMHWYr/gBXjB5tHVJpeNfNkINyzrwDpatVQ3Ds3sGyvPn/cWkNka4ZYvMbwkjw/7n/0ijsjfRA==}
fumadocs-core@12.5.6:
resolution: {integrity: sha512-sKbVq+Yrf7uLZD/pHojLGwClRxuOyjR1NaIlm/cO9dCaEO6n568NTom/2rEn+jyhII+LbGTJqfIJmktBW6rgNA==}
peerDependencies:
next: '>= 14.1.0'
react: '>= 18'
react-dom: '>= 18'
fumadocs-mdx@8.2.33:
resolution: {integrity: sha512-bKT4CaFMWrPYUqsM2MD6uN4i2XIgZ2mCw9XoMJMpPS3Oq2Eq5MlNs9B5L6ItO7FfckCb9hoCA6LHdT1tVkgtyQ==}
fumadocs-mdx@8.2.34:
resolution: {integrity: sha512-vq7gd16z3fxMCjkjzFSTkqbQXbhZ3ucNvXAWdQxhkbhRbx3EAcmokkbcySsqVdqHPDIm0eGmCV33fQJsku1DgA==}
peerDependencies:
fumadocs-core: 12.x.x
next: '>= 14.1.0'
@@ -5425,8 +5451,8 @@ packages:
fumadocs-openapi@3.3.0:
resolution: {integrity: sha512-a6G1+FoBA4kH2HnjlgwmPpO9z4itrKPRENkVqxJPsOCwpCKdHZc6Tpwogo9CXvEifGqjAvyTbhNPy0N3+YmHLg==}
fumadocs-ui@12.2.2:
resolution: {integrity: sha512-cOUiGk/Bp8Cqd/lBx5LqjbCHO4Ny8qtFItJog6aI5POFVJDJoYuCMv65MLoS/ar7QxIdaiFSw2XYYziZQaLmrQ==}
fumadocs-ui@12.5.6:
resolution: {integrity: sha512-8kYsrSCbRuo2rS09xTAb5HejtH8QDsSlqWGC8k+D9GI4WdAW7kAQCg6k9idnhhP/nq3QOsyMtvpoUGkje91bpQ==}
peerDependencies:
next: '>= 14.1.0'
react: '>= 18'
@@ -6212,10 +6238,10 @@ packages:
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0
lucide-react@0.395.0:
resolution: {integrity: sha512-6hzdNH5723A4FLaYZWpK50iyZH8iS2Jq5zuPRRotOFkhu6kxxJiebVdJ72tCR5XkiIeYFOU5NUawFZOac+VeYw==}
lucide-react@0.414.0:
resolution: {integrity: sha512-Krr/MHg9AWoJc52qx8hyJ64X9++JNfS1wjaJviLM1EP/68VNB7Tv0VMldLCB1aUe6Ka9QxURPhQm/eB6cqOM3A==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
luxon@3.4.4:
resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==}
@@ -10203,18 +10229,17 @@ snapshots:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
'@radix-ui/react-accordion@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@radix-ui/react-accordion@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.25.0
'@radix-ui/primitive': 1.0.1
'@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-collection': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-direction': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-id': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/primitive': 1.1.0
'@radix-ui/react-collapsible': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
@@ -10298,17 +10323,16 @@ snapshots:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
'@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@radix-ui/react-collapsible@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.25.0
'@radix-ui/primitive': 1.0.1
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-id': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/primitive': 1.1.0
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
@@ -10328,19 +10352,6 @@ snapshots:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
'@radix-ui/react-collection@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.25.0
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
'@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.2.0)
@@ -10529,13 +10540,6 @@ snapshots:
optionalDependencies:
'@types/react': 18.3.3
'@radix-ui/react-direction@1.0.1(@types/react@18.3.3)(react@18.3.1)':
dependencies:
'@babel/runtime': 7.25.0
react: 18.3.1
optionalDependencies:
'@types/react': 18.3.3
'@radix-ui/react-direction@1.1.0(@types/react@18.3.3)(react@18.2.0)':
dependencies:
react: 18.2.0
@@ -12409,7 +12413,7 @@ snapshots:
'@types/hast@3.0.4':
dependencies:
'@types/unist': 2.0.10
'@types/unist': 3.0.2
'@types/http-cache-semantics@4.0.4': {}
@@ -12429,7 +12433,7 @@ snapshots:
'@types/mdast@4.0.4':
dependencies:
'@types/unist': 2.0.10
'@types/unist': 3.0.2
'@types/mdx@2.0.13': {}
@@ -14033,7 +14037,7 @@ snapshots:
eslint: 8.45.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0)
eslint-plugin-jsx-a11y: 6.9.0(eslint@8.45.0)
eslint-plugin-react: 7.35.0(eslint@8.45.0)
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.45.0)
@@ -14057,7 +14061,7 @@ snapshots:
enhanced-resolve: 5.17.1
eslint: 8.45.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.5
is-core-module: 2.15.0
@@ -14079,7 +14083,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0):
eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
@@ -14434,7 +14438,7 @@ snapshots:
fsevents@2.3.3:
optional: true
fumadocs-core@12.2.2(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
fumadocs-core@12.5.6(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@formatjs/intl-localematcher': 0.5.4
'@shikijs/rehype': 1.12.0
@@ -14458,13 +14462,13 @@ snapshots:
- '@types/react'
- supports-color
fumadocs-mdx@8.2.33(fumadocs-core@12.2.2(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
fumadocs-mdx@8.2.34(fumadocs-core@12.5.6(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
dependencies:
'@mdx-js/mdx': 3.0.1
cross-spawn: 7.0.3
estree-util-value-to-estree: 3.1.2
fast-glob: 3.3.2
fumadocs-core: 12.2.2(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
fumadocs-core: 12.5.6(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
gray-matter: 4.0.3
next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
zod: 3.23.8
@@ -14479,10 +14483,10 @@ snapshots:
json-schema-to-typescript: 14.1.0
openapi-sampler: 1.5.1
fumadocs-ui@12.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.7):
fumadocs-ui@12.5.6(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.7):
dependencies:
'@radix-ui/react-accordion': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-accordion': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-collapsible': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-popover': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -14491,13 +14495,14 @@ snapshots:
'@tailwindcss/typography': 0.5.13(tailwindcss@3.4.7)
class-variance-authority: 0.7.0
cmdk: 1.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
fumadocs-core: 12.2.2(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
lucide-react: 0.395.0(react@18.3.1)
fumadocs-core: 12.5.6(@types/react@18.3.3)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
lucide-react: 0.414.0(react@18.3.1)
next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-themes: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-medium-image-zoom: 5.2.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
swr: 2.2.5(react@18.3.1)
tailwind-merge: 2.4.0
transitivePeerDependencies:
- '@types/react'
@@ -15357,7 +15362,7 @@ snapshots:
dependencies:
react: 18.3.1
lucide-react@0.395.0(react@18.3.1):
lucide-react@0.414.0(react@18.3.1):
dependencies:
react: 18.3.1