mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge pull request #713 from Dokploy/fix/build-i18n
refactor(dokploy): add missing next-18next to dockerfile
This commit is contained in:
@@ -99,14 +99,14 @@ workflows:
|
|||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
- canary
|
- canary
|
||||||
- pull/665
|
- fix/build-i18n
|
||||||
- build-arm64:
|
- build-arm64:
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
- canary
|
- canary
|
||||||
- pull/665
|
- fix/build-i18n
|
||||||
- combine-manifests:
|
- combine-manifests:
|
||||||
requires:
|
requires:
|
||||||
- build-amd64
|
- build-amd64
|
||||||
@@ -116,4 +116,4 @@ workflows:
|
|||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
- canary
|
- canary
|
||||||
- pull/665
|
- fix/build-i18n
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ 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/.next ./.next
|
||||||
COPY --from=build /prod/dokploy/dist ./dist
|
COPY --from=build /prod/dokploy/dist ./dist
|
||||||
COPY --from=build /prod/dokploy/next.config.mjs ./next.config.mjs
|
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/public ./public
|
||||||
COPY --from=build /prod/dokploy/package.json ./package.json
|
COPY --from=build /prod/dokploy/package.json ./package.json
|
||||||
COPY --from=build /prod/dokploy/drizzle ./drizzle
|
COPY --from=build /prod/dokploy/drizzle ./drizzle
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ 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/.next ./.next
|
||||||
COPY --from=build /prod/dokploy/dist ./dist
|
COPY --from=build /prod/dokploy/dist ./dist
|
||||||
COPY --from=build /prod/dokploy/next.config.mjs ./next.config.mjs
|
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/public ./public
|
||||||
COPY --from=build /prod/dokploy/package.json ./package.json
|
COPY --from=build /prod/dokploy/package.json ./package.json
|
||||||
COPY --from=build /prod/dokploy/drizzle ./drizzle
|
COPY --from=build /prod/dokploy/drizzle ./drizzle
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"build-next": "next build",
|
"build-next": "next build",
|
||||||
"setup": "tsx -r dotenv/config setup.ts && sleep 5 && pnpm run migration:run",
|
"setup": "tsx -r dotenv/config setup.ts && sleep 5 && pnpm run migration:run",
|
||||||
"reset-password": "node -r dotenv/config dist/reset-password.mjs",
|
"reset-password": "node -r dotenv/config dist/reset-password.mjs",
|
||||||
"dev": "tsx -r dotenv/config ./server/server.ts --project tsconfig.server.json ",
|
"dev": "TURBOPACK=1 tsx -r dotenv/config ./server/server.ts --project tsconfig.server.json ",
|
||||||
"studio": "drizzle-kit studio --config ./server/db/drizzle.config.ts",
|
"studio": "drizzle-kit studio --config ./server/db/drizzle.config.ts",
|
||||||
"migration:generate": "drizzle-kit generate --config ./server/db/drizzle.config.ts",
|
"migration:generate": "drizzle-kit generate --config ./server/db/drizzle.config.ts",
|
||||||
"migration:run": "tsx -r dotenv/config migration.ts",
|
"migration:run": "tsx -r dotenv/config migration.ts",
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { AppearanceForm } from "@/components/dashboard/settings/appearance-form"
|
|||||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
import { appRouter } from "@/server/api/root";
|
import { appRouter } from "@/server/api/root";
|
||||||
import { getLocale } from "@/utils/i18n";
|
import { getLocale, serverSideTranslations } from "@/utils/i18n";
|
||||||
import { validateRequest } from "@dokploy/server";
|
import { validateRequest } from "@dokploy/server";
|
||||||
import { createServerSideHelpers } from "@trpc/react-query/server";
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
|
||||||
import React, { type ReactElement } from "react";
|
import React, { type ReactElement } from "react";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
|
import nextI18NextConfig from "../../../next-i18next.config.cjs";
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
|||||||
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
import { appRouter } from "@/server/api/root";
|
import { appRouter } from "@/server/api/root";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { getLocale } from "@/utils/i18n";
|
import { getLocale, serverSideTranslations } from "@/utils/i18n";
|
||||||
import { validateRequest } from "@dokploy/server";
|
import { validateRequest } from "@dokploy/server";
|
||||||
import { createServerSideHelpers } from "@trpc/react-query/server";
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
|
||||||
import React, { type ReactElement } from "react";
|
import React, { type ReactElement } from "react";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,10 @@ import { WebServer } from "@/components/dashboard/settings/web-server";
|
|||||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
import { appRouter } from "@/server/api/root";
|
import { appRouter } from "@/server/api/root";
|
||||||
import { getLocale } from "@/utils/i18n";
|
import { getLocale, serverSideTranslations } from "@/utils/i18n";
|
||||||
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
||||||
import { createServerSideHelpers } from "@trpc/react-query/server";
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
|
||||||
import React, { type ReactElement } from "react";
|
import React, { type ReactElement } from "react";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { setupTerminalWebSocketServer } from "./wss/terminal";
|
|||||||
config({ path: ".env" });
|
config({ path: ".env" });
|
||||||
const PORT = Number.parseInt(process.env.PORT || "3000", 10);
|
const PORT = Number.parseInt(process.env.PORT || "3000", 10);
|
||||||
const dev = process.env.NODE_ENV !== "production";
|
const dev = process.env.NODE_ENV !== "production";
|
||||||
const app = next({ dev });
|
const app = next({ dev, turbopack: dev });
|
||||||
const handle = app.getRequestHandler();
|
const handle = app.getRequestHandler();
|
||||||
void app.prepare().then(async () => {
|
void app.prepare().then(async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,40 +1,44 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generateRandomDomain,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
|
|
||||||
const apiKey = Array.from({length: 32}, () =>
|
const apiKey = Array.from({ length: 32 }, () =>
|
||||||
Math.floor(Math.random() * 16).toString(16)).join('');
|
Math.floor(Math.random() * 16).toString(16),
|
||||||
const encryptionKey = Array.from({length: 32}, () =>
|
).join("");
|
||||||
Math.floor(Math.random() * 16).toString(16)).join('');
|
const encryptionKey = Array.from({ length: 32 }, () =>
|
||||||
const jwtSecret = Array.from({length: 32}, () =>
|
Math.floor(Math.random() * 16).toString(16),
|
||||||
Math.floor(Math.random() * 16).toString(16)).join('');
|
).join("");
|
||||||
const postgresPassword = Array.from({length: 32}, () =>
|
const jwtSecret = Array.from({ length: 32 }, () =>
|
||||||
Math.floor(Math.random() * 16).toString(16)).join('');
|
Math.floor(Math.random() * 16).toString(16),
|
||||||
|
).join("");
|
||||||
|
const postgresPassword = Array.from({ length: 32 }, () =>
|
||||||
|
Math.floor(Math.random() * 16).toString(16),
|
||||||
|
).join("");
|
||||||
|
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 80,
|
port: 80,
|
||||||
serviceName: "activepieces",
|
serviceName: "activepieces",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const envs = [
|
const envs = [
|
||||||
`AP_HOST=${mainDomain}`,
|
`AP_HOST=${mainDomain}`,
|
||||||
`AP_API_KEY=${apiKey}`,
|
`AP_API_KEY=${apiKey}`,
|
||||||
`AP_ENCRYPTION_KEY=${encryptionKey}`,
|
`AP_ENCRYPTION_KEY=${encryptionKey}`,
|
||||||
`AP_JWT_SECRET=${jwtSecret}`,
|
`AP_JWT_SECRET=${jwtSecret}`,
|
||||||
`AP_POSTGRES_PASSWORD=${postgresPassword}`,
|
`AP_POSTGRES_PASSWORD=${postgresPassword}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,46 +1,47 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generatePassword,
|
generatePassword,
|
||||||
generateRandomDomain,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
const mysqlPassword = generatePassword();
|
const mysqlPassword = generatePassword();
|
||||||
const mysqlRootPassword = generatePassword();
|
const mysqlRootPassword = generatePassword();
|
||||||
const mysqlUser = "tickets";
|
const mysqlUser = "tickets";
|
||||||
const mysqlDatabase = "tickets";
|
const mysqlDatabase = "tickets";
|
||||||
|
|
||||||
// Generate encryption key in the format they use
|
// Generate encryption key in the format they use
|
||||||
const encryptionKey = Array.from({length: 48}, () =>
|
const encryptionKey = Array.from({ length: 48 }, () =>
|
||||||
Math.floor(Math.random() * 16).toString(16)).join('');
|
Math.floor(Math.random() * 16).toString(16),
|
||||||
|
).join("");
|
||||||
|
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 8169,
|
port: 8169,
|
||||||
serviceName: "bot",
|
serviceName: "bot",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const envs = [
|
const envs = [
|
||||||
`TICKETS_HOST=${mainDomain}`,
|
`TICKETS_HOST=${mainDomain}`,
|
||||||
`MYSQL_DATABASE=${mysqlDatabase}`,
|
`MYSQL_DATABASE=${mysqlDatabase}`,
|
||||||
`MYSQL_PASSWORD=${mysqlPassword}`,
|
`MYSQL_PASSWORD=${mysqlPassword}`,
|
||||||
`MYSQL_ROOT_PASSWORD=${mysqlRootPassword}`,
|
`MYSQL_ROOT_PASSWORD=${mysqlRootPassword}`,
|
||||||
`MYSQL_USER=${mysqlUser}`,
|
`MYSQL_USER=${mysqlUser}`,
|
||||||
`ENCRYPTION_KEY=${encryptionKey}`,
|
`ENCRYPTION_KEY=${encryptionKey}`,
|
||||||
// These need to be set by the user through the UI
|
// These need to be set by the user through the UI
|
||||||
`# Follow the guide at: https://discordtickets.app/self-hosting/installation/docker/#creating-the-discord-application`,
|
"# Follow the guide at: https://discordtickets.app/self-hosting/installation/docker/#creating-the-discord-application",
|
||||||
`DISCORD_SECRET=`,
|
"DISCORD_SECRET=",
|
||||||
`DISCORD_TOKEN=`,
|
"DISCORD_TOKEN=",
|
||||||
`SUPER_USERS=YOUR_DISCORD_USER_ID`, // Default super user
|
"SUPER_USERS=YOUR_DISCORD_USER_ID", // Default super user
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,34 +1,34 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generatePassword,
|
generatePassword,
|
||||||
generateRandomDomain,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
const dbPassword = generatePassword();
|
const dbPassword = generatePassword();
|
||||||
const dbUsername = "invoiceshelf";
|
const dbUsername = "invoiceshelf";
|
||||||
const dbDatabase = "invoiceshelf";
|
const dbDatabase = "invoiceshelf";
|
||||||
|
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 80,
|
port: 80,
|
||||||
serviceName: "invoiceshelf",
|
serviceName: "invoiceshelf",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const envs = [
|
const envs = [
|
||||||
`INVOICESHELF_HOST=${mainDomain}`,
|
`INVOICESHELF_HOST=${mainDomain}`,
|
||||||
`DB_PASSWORD=${dbPassword}`,
|
`DB_PASSWORD=${dbPassword}`,
|
||||||
`DB_USERNAME=${dbUsername}`,
|
`DB_USERNAME=${dbUsername}`,
|
||||||
`DB_DATABASE=${dbDatabase}`,
|
`DB_DATABASE=${dbDatabase}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,43 +1,43 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generateBase64,
|
generateBase64,
|
||||||
generatePassword,
|
generatePassword,
|
||||||
generateRandomDomain,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
// Generate domains and secrets
|
// Generate domains and secrets
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
const apiDomain = generateRandomDomain(schema);
|
const apiDomain = generateRandomDomain(schema);
|
||||||
const postgresPassword = generatePassword();
|
const postgresPassword = generatePassword();
|
||||||
const secret = generateBase64(32);
|
const secret = generateBase64(32);
|
||||||
|
|
||||||
// Configure domain routing
|
// Configure domain routing
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 3000,
|
port: 3000,
|
||||||
serviceName: "peppermint",
|
serviceName: "peppermint",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: apiDomain,
|
host: apiDomain,
|
||||||
port: 5003,
|
port: 5003,
|
||||||
serviceName: "peppermint",
|
serviceName: "peppermint",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Set environment variables
|
// Set environment variables
|
||||||
const envs = [
|
const envs = [
|
||||||
`MAIN_DOMAIN=${mainDomain}`,
|
`MAIN_DOMAIN=${mainDomain}`,
|
||||||
`API_DOMAIN=${apiDomain}`,
|
`API_DOMAIN=${apiDomain}`,
|
||||||
`POSTGRES_PASSWORD=${postgresPassword}`,
|
`POSTGRES_PASSWORD=${postgresPassword}`,
|
||||||
`SECRET=${secret}`,
|
`SECRET=${secret}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,37 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generatePassword,
|
generateBase64,
|
||||||
generateRandomDomain,
|
generatePassword,
|
||||||
generateBase64,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
const dbPassword = generatePassword();
|
const dbPassword = generatePassword();
|
||||||
const dbUser = "postiz";
|
const dbUser = "postiz";
|
||||||
const dbName = "postiz";
|
const dbName = "postiz";
|
||||||
const jwtSecret = generateBase64(32);
|
const jwtSecret = generateBase64(32);
|
||||||
|
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 5000,
|
port: 5000,
|
||||||
serviceName: "postiz",
|
serviceName: "postiz",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const envs = [
|
const envs = [
|
||||||
`POSTIZ_HOST=${mainDomain}`,
|
`POSTIZ_HOST=${mainDomain}`,
|
||||||
`DB_PASSWORD=${dbPassword}`,
|
`DB_PASSWORD=${dbPassword}`,
|
||||||
`DB_USER=${dbUser}`,
|
`DB_USER=${dbUser}`,
|
||||||
`DB_NAME=${dbName}`,
|
`DB_NAME=${dbName}`,
|
||||||
`JWT_SECRET=${jwtSecret}`,
|
`JWT_SECRET=${jwtSecret}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,33 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generatePassword,
|
generatePassword,
|
||||||
generateRandomDomain,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
const dbPassword = generatePassword();
|
const dbPassword = generatePassword();
|
||||||
const dbUser = "slash";
|
const dbUser = "slash";
|
||||||
const dbName = "slash";
|
const dbName = "slash";
|
||||||
|
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 5231,
|
port: 5231,
|
||||||
serviceName: "slash",
|
serviceName: "slash",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const envs = [
|
const envs = [
|
||||||
`DB_USER=${dbUser}`,
|
`DB_USER=${dbUser}`,
|
||||||
`DB_PASSWORD=${dbPassword}`,
|
`DB_PASSWORD=${dbPassword}`,
|
||||||
`DB_NAME=${dbName}`,
|
`DB_NAME=${dbName}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -706,12 +706,13 @@ export const templates: TemplateData[] = [
|
|||||||
id: "peppermint",
|
id: "peppermint",
|
||||||
name: "Peppermint",
|
name: "Peppermint",
|
||||||
version: "latest",
|
version: "latest",
|
||||||
description: "Peppermint is a modern, open-source API development platform that helps you build, test and document your APIs.",
|
description:
|
||||||
|
"Peppermint is a modern, open-source API development platform that helps you build, test and document your APIs.",
|
||||||
logo: "peppermint.svg",
|
logo: "peppermint.svg",
|
||||||
links: {
|
links: {
|
||||||
github: "https://github.com/Peppermint-Lab/peppermint",
|
github: "https://github.com/Peppermint-Lab/peppermint",
|
||||||
website: "https://peppermint.sh/",
|
website: "https://peppermint.sh/",
|
||||||
docs: "https://docs.peppermint.sh/"
|
docs: "https://docs.peppermint.sh/",
|
||||||
},
|
},
|
||||||
tags: ["api", "development", "documentation"],
|
tags: ["api", "development", "documentation"],
|
||||||
load: () => import("./peppermint/index").then((m) => m.generate),
|
load: () => import("./peppermint/index").then((m) => m.generate),
|
||||||
@@ -720,7 +721,8 @@ export const templates: TemplateData[] = [
|
|||||||
id: "windmill",
|
id: "windmill",
|
||||||
name: "Windmill",
|
name: "Windmill",
|
||||||
version: "latest",
|
version: "latest",
|
||||||
description: "A developer platform to build production-grade workflows and internal apps. Open-source alternative to Airplane, Retool, and GitHub Actions.",
|
description:
|
||||||
|
"A developer platform to build production-grade workflows and internal apps. Open-source alternative to Airplane, Retool, and GitHub Actions.",
|
||||||
logo: "windmill.svg",
|
logo: "windmill.svg",
|
||||||
links: {
|
links: {
|
||||||
github: "https://github.com/windmill-labs/windmill",
|
github: "https://github.com/windmill-labs/windmill",
|
||||||
@@ -734,7 +736,8 @@ export const templates: TemplateData[] = [
|
|||||||
id: "activepieces",
|
id: "activepieces",
|
||||||
name: "Activepieces",
|
name: "Activepieces",
|
||||||
version: "0.35.0",
|
version: "0.35.0",
|
||||||
description: "Open-source no-code business automation tool. An alternative to Zapier, Make.com, and Tray.",
|
description:
|
||||||
|
"Open-source no-code business automation tool. An alternative to Zapier, Make.com, and Tray.",
|
||||||
logo: "activepieces.svg",
|
logo: "activepieces.svg",
|
||||||
links: {
|
links: {
|
||||||
github: "https://github.com/activepieces/activepieces",
|
github: "https://github.com/activepieces/activepieces",
|
||||||
@@ -748,21 +751,23 @@ export const templates: TemplateData[] = [
|
|||||||
id: "invoiceshelf",
|
id: "invoiceshelf",
|
||||||
name: "InvoiceShelf",
|
name: "InvoiceShelf",
|
||||||
version: "latest",
|
version: "latest",
|
||||||
description: "InvoiceShelf is a self-hosted open source invoicing system for freelancers and small businesses.",
|
description:
|
||||||
logo: "invoiceshelf.png",
|
"InvoiceShelf is a self-hosted open source invoicing system for freelancers and small businesses.",
|
||||||
links: {
|
logo: "invoiceshelf.png",
|
||||||
github: "https://github.com/InvoiceShelf/invoiceshelf",
|
links: {
|
||||||
website: "https://invoiceshelf.com",
|
github: "https://github.com/InvoiceShelf/invoiceshelf",
|
||||||
docs: "https://github.com/InvoiceShelf/invoiceshelf#readme",
|
website: "https://invoiceshelf.com",
|
||||||
},
|
docs: "https://github.com/InvoiceShelf/invoiceshelf#readme",
|
||||||
tags: ["invoice", "business", "finance"],
|
},
|
||||||
load: () => import("./invoiceshelf/index").then((m) => m.generate),
|
tags: ["invoice", "business", "finance"],
|
||||||
|
load: () => import("./invoiceshelf/index").then((m) => m.generate),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "postiz",
|
id: "postiz",
|
||||||
name: "Postiz",
|
name: "Postiz",
|
||||||
version: "latest",
|
version: "latest",
|
||||||
description: "Postiz is a modern, open-source platform for managing and publishing content across multiple channels.",
|
description:
|
||||||
|
"Postiz is a modern, open-source platform for managing and publishing content across multiple channels.",
|
||||||
logo: "postiz.png",
|
logo: "postiz.png",
|
||||||
links: {
|
links: {
|
||||||
github: "https://github.com/gitroomhq/postiz",
|
github: "https://github.com/gitroomhq/postiz",
|
||||||
@@ -776,7 +781,8 @@ export const templates: TemplateData[] = [
|
|||||||
id: "slash",
|
id: "slash",
|
||||||
name: "Slash",
|
name: "Slash",
|
||||||
version: "latest",
|
version: "latest",
|
||||||
description: "Slash is a modern, self-hosted bookmarking service and link shortener that helps you organize and share your favorite links.",
|
description:
|
||||||
|
"Slash is a modern, self-hosted bookmarking service and link shortener that helps you organize and share your favorite links.",
|
||||||
logo: "slash.png",
|
logo: "slash.png",
|
||||||
links: {
|
links: {
|
||||||
github: "https://github.com/yourselfhosted/slash",
|
github: "https://github.com/yourselfhosted/slash",
|
||||||
@@ -790,7 +796,8 @@ export const templates: TemplateData[] = [
|
|||||||
id: "discord-tickets",
|
id: "discord-tickets",
|
||||||
name: "Discord Tickets",
|
name: "Discord Tickets",
|
||||||
version: "4.0.21",
|
version: "4.0.21",
|
||||||
description: "An open-source Discord bot for creating and managing support ticket channels.",
|
description:
|
||||||
|
"An open-source Discord bot for creating and managing support ticket channels.",
|
||||||
logo: "discord-tickets.png",
|
logo: "discord-tickets.png",
|
||||||
links: {
|
links: {
|
||||||
github: "https://github.com/discord-tickets/bot",
|
github: "https://github.com/discord-tickets/bot",
|
||||||
@@ -799,8 +806,8 @@ export const templates: TemplateData[] = [
|
|||||||
},
|
},
|
||||||
tags: ["discord", "tickets", "support"],
|
tags: ["discord", "tickets", "support"],
|
||||||
load: () => import("./discord-tickets/index").then((m) => m.generate),
|
load: () => import("./discord-tickets/index").then((m) => m.generate),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "nextcloud-aio",
|
id: "nextcloud-aio",
|
||||||
name: "Nextcloud All in One",
|
name: "Nextcloud All in One",
|
||||||
version: "30.0.2",
|
version: "30.0.2",
|
||||||
@@ -814,8 +821,8 @@ export const templates: TemplateData[] = [
|
|||||||
},
|
},
|
||||||
tags: ["file", "sync"],
|
tags: ["file", "sync"],
|
||||||
load: () => import("./nextcloud-aio/index").then((m) => m.generate),
|
load: () => import("./nextcloud-aio/index").then((m) => m.generate),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "blender",
|
id: "blender",
|
||||||
name: "Blender",
|
name: "Blender",
|
||||||
version: "latest",
|
version: "latest",
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
import {
|
import {
|
||||||
type DomainSchema,
|
type DomainSchema,
|
||||||
type Schema,
|
type Schema,
|
||||||
type Template,
|
type Template,
|
||||||
generatePassword,
|
generatePassword,
|
||||||
generateRandomDomain,
|
generateRandomDomain,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
export function generate(schema: Schema): Template {
|
export function generate(schema: Schema): Template {
|
||||||
const mainDomain = generateRandomDomain(schema);
|
const mainDomain = generateRandomDomain(schema);
|
||||||
const postgresPassword = generatePassword();
|
const postgresPassword = generatePassword();
|
||||||
|
|
||||||
const domains: DomainSchema[] = [
|
const domains: DomainSchema[] = [
|
||||||
{
|
{
|
||||||
host: mainDomain,
|
host: mainDomain,
|
||||||
port: 80,
|
port: 80,
|
||||||
serviceName: "caddy",
|
serviceName: "caddy",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const envs = [
|
const envs = [
|
||||||
`WINDMILL_HOST=${mainDomain}`,
|
`WINDMILL_HOST=${mainDomain}`,
|
||||||
`POSTGRES_PASSWORD=${postgresPassword}`,
|
`POSTGRES_PASSWORD=${postgresPassword}`,
|
||||||
`DATABASE_URL=postgres://postgres:${postgresPassword}@db/windmill?sslmode=disable`,
|
`DATABASE_URL=postgres://postgres:${postgresPassword}@db/windmill?sslmode=disable`,
|
||||||
];
|
];
|
||||||
|
|
||||||
const mounts: Template["mounts"] = [
|
const mounts: Template["mounts"] = [
|
||||||
{
|
{
|
||||||
filePath: "Caddyfile",
|
filePath: "Caddyfile",
|
||||||
content: `:80 {
|
content: `:80 {
|
||||||
bind 0.0.0.0
|
bind 0.0.0.0
|
||||||
reverse_proxy /ws/* http://lsp:3001
|
reverse_proxy /ws/* http://lsp:3001
|
||||||
reverse_proxy /* http://windmill_server:8000
|
reverse_proxy /* http://windmill_server:8000
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domains,
|
domains,
|
||||||
envs,
|
envs,
|
||||||
mounts,
|
mounts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,8 @@
|
|||||||
"**/*.js",
|
"**/*.js",
|
||||||
".next/types/**/*.ts",
|
".next/types/**/*.ts",
|
||||||
"env.js",
|
"env.js",
|
||||||
"next.config.mjs"
|
"next.config.mjs",
|
||||||
|
"next-i18next.config.mjs"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|||||||
@@ -4,3 +4,12 @@ export function getLocale(cookies: NextApiRequestCookies) {
|
|||||||
const locale = cookies.DOKPLOY_LOCALE ?? "en";
|
const locale = cookies.DOKPLOY_LOCALE ?? "en";
|
||||||
return locale;
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// libs/i18n.js
|
||||||
|
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);
|
||||||
|
|||||||
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@@ -249,7 +249,7 @@ importers:
|
|||||||
version: 0.5.1(drizzle-orm@0.30.10(@types/react@18.3.5)(postgres@3.4.4)(react@18.2.0))(zod@3.23.8)
|
version: 0.5.1(drizzle-orm@0.30.10(@types/react@18.3.5)(postgres@3.4.4)(react@18.2.0))(zod@3.23.8)
|
||||||
i18next:
|
i18next:
|
||||||
specifier: ^23.16.4
|
specifier: ^23.16.4
|
||||||
version: 23.16.4
|
version: 23.16.5
|
||||||
input-otp:
|
input-otp:
|
||||||
specifier: ^1.2.4
|
specifier: ^1.2.4
|
||||||
version: 1.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
version: 1.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
@@ -276,7 +276,7 @@ importers:
|
|||||||
version: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
version: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: ^15.3.1
|
specifier: ^15.3.1
|
||||||
version: 15.3.1(i18next@23.16.4)(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-i18next@15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)
|
version: 15.3.1(i18next@23.16.5)(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-i18next@15.1.1(i18next@23.16.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: ^0.2.1
|
specifier: ^0.2.1
|
||||||
version: 0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
version: 0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
@@ -306,7 +306,7 @@ importers:
|
|||||||
version: 7.52.1(react@18.2.0)
|
version: 7.52.1(react@18.2.0)
|
||||||
react-i18next:
|
react-i18next:
|
||||||
specifier: ^15.1.0
|
specifier: ^15.1.0
|
||||||
version: 15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
version: 15.1.1(i18next@23.16.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
recharts:
|
recharts:
|
||||||
specifier: ^2.12.7
|
specifier: ^2.12.7
|
||||||
version: 2.12.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
version: 2.12.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
@@ -4734,8 +4734,8 @@ packages:
|
|||||||
i18next-fs-backend@2.3.2:
|
i18next-fs-backend@2.3.2:
|
||||||
resolution: {integrity: sha512-LIwUlkqDZnUI8lnUxBnEj8K/FrHQTT/Sc+1rvDm9E8YvvY5YxzoEAASNx+W5M9DfD5s77lI5vSAFWeTp26B/3Q==}
|
resolution: {integrity: sha512-LIwUlkqDZnUI8lnUxBnEj8K/FrHQTT/Sc+1rvDm9E8YvvY5YxzoEAASNx+W5M9DfD5s77lI5vSAFWeTp26B/3Q==}
|
||||||
|
|
||||||
i18next@23.16.4:
|
i18next@23.16.5:
|
||||||
resolution: {integrity: sha512-9NIYBVy9cs4wIqzurf7nLXPyf3R78xYbxExVqHLK9od3038rjpyOEzW+XB130kZ1N4PZ9inTtJ471CRJ4Ituyg==}
|
resolution: {integrity: sha512-KTlhE3EP9x6pPTAW7dy0WKIhoCpfOGhRQlO+jttQLgzVaoOjWwBWramu7Pp0i+8wDNduuzXfe3kkVbzrKyrbTA==}
|
||||||
|
|
||||||
iconv-lite@0.4.24:
|
iconv-lite@0.4.24:
|
||||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||||
@@ -5771,8 +5771,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^16.8.0 || ^17 || ^18 || ^19
|
react: ^16.8.0 || ^17 || ^18 || ^19
|
||||||
|
|
||||||
react-i18next@15.1.0:
|
react-i18next@15.1.1:
|
||||||
resolution: {integrity: sha512-zj3nJynMnZsy2gPZiOTC7XctCY5eQGqT3tcKMmfJWC9FMvgd+960w/adq61j8iPzpwmsXejqID9qC3Mqu1Xu2Q==}
|
resolution: {integrity: sha512-R/Vg9wIli2P3FfeI8o1eNJUJue5LWpFsQePCHdQDmX0Co3zkr6kdT8gAseb/yGeWbNz1Txc4bKDQuZYsC0kQfw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
i18next: '>= 23.2.3'
|
i18next: '>= 23.2.3'
|
||||||
react: '>= 16.8.0'
|
react: '>= 16.8.0'
|
||||||
@@ -10946,7 +10946,7 @@ snapshots:
|
|||||||
|
|
||||||
i18next-fs-backend@2.3.2: {}
|
i18next-fs-backend@2.3.2: {}
|
||||||
|
|
||||||
i18next@23.16.4:
|
i18next@23.16.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.25.0
|
'@babel/runtime': 7.25.0
|
||||||
|
|
||||||
@@ -11450,17 +11450,17 @@ snapshots:
|
|||||||
|
|
||||||
neotraverse@0.6.18: {}
|
neotraverse@0.6.18: {}
|
||||||
|
|
||||||
next-i18next@15.3.1(i18next@23.16.4)(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-i18next@15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0):
|
next-i18next@15.3.1(i18next@23.16.5)(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-i18next@15.1.1(i18next@23.16.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.25.0
|
'@babel/runtime': 7.25.0
|
||||||
'@types/hoist-non-react-statics': 3.3.5
|
'@types/hoist-non-react-statics': 3.3.5
|
||||||
core-js: 3.39.0
|
core-js: 3.39.0
|
||||||
hoist-non-react-statics: 3.3.2
|
hoist-non-react-statics: 3.3.2
|
||||||
i18next: 23.16.4
|
i18next: 23.16.5
|
||||||
i18next-fs-backend: 2.3.2
|
i18next-fs-backend: 2.3.2
|
||||||
next: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
next: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
react-i18next: 15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
react-i18next: 15.1.1(i18next@23.16.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||||
|
|
||||||
next-themes@0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
next-themes@0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -11951,11 +11951,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
|
|
||||||
react-i18next@15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
react-i18next@15.1.1(i18next@23.16.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.25.0
|
'@babel/runtime': 7.25.0
|
||||||
html-parse-stringify: 3.0.1
|
html-parse-stringify: 3.0.1
|
||||||
i18next: 23.16.4
|
i18next: 23.16.5
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
|||||||
Reference in New Issue
Block a user