Merge branch 'Dokploy:canary' into feature/gpu-support-blender-template

This commit is contained in:
Vishal kadam
2024-10-18 18:28:44 +05:30
committed by GitHub
11 changed files with 124 additions and 57 deletions

1
.husky/commit-msg Normal file
View File

@@ -0,0 +1 @@
npx commitlint --edit "$1"

6
.husky/install.mjs Normal file
View File

@@ -0,0 +1,6 @@
// Skip Husky install in production and CI
if (process.env.NODE_ENV === "production" || process.env.CI === "true") {
process.exit(0);
}
const husky = (await import("husky")).default;
console.log(husky());

2
.husky/pre-commit Normal file
View File

@@ -0,0 +1,2 @@
pnpm run check
git add .

View File

@@ -1,17 +1,17 @@
import { import {
createDefaultMiddlewares, createDefaultMiddlewares,
createDefaultTraefikConfig,
createDefaultServerTraefikConfig, createDefaultServerTraefikConfig,
createDefaultTraefikConfig,
initializeTraefik, initializeTraefik,
} from "@dokploy/server/dist/setup/traefik-setup"; } from "@dokploy/server/dist/setup/traefik-setup";
import { setupDirectories } from "@dokploy/server/dist/setup/config-paths";
import { initializePostgres } from "@dokploy/server/dist/setup/postgres-setup";
import { initializeRedis } from "@dokploy/server/dist/setup/redis-setup";
import { import {
initializeNetwork, initializeNetwork,
initializeSwarm, initializeSwarm,
} from "@dokploy/server/dist/setup/setup"; } from "@dokploy/server/dist/setup/setup";
import { setupDirectories } from "@dokploy/server/dist/setup/config-paths";
import { initializePostgres } from "@dokploy/server/dist/setup/postgres-setup";
import { initializeRedis } from "@dokploy/server/dist/setup/redis-setup";
(async () => { (async () => {
try { try {
setupDirectories(); setupDirectories();

View File

@@ -6,9 +6,9 @@ import GoogleAnalytics from "@/components/analitycs/google";
import { NextIntlClientProvider } from "next-intl"; import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server"; import { getMessages } from "next-intl/server";
import type { Metadata } from "next";
import { Header } from "@/components/Header";
import { Footer } from "@/components/Footer"; import { Footer } from "@/components/Footer";
import { Header } from "@/components/Header";
import type { Metadata } from "next";
export const metadata: Metadata = { export const metadata: Metadata = {
title: { title: {

View File

@@ -1,13 +1,13 @@
"use client"; "use client";
import clsx from "clsx"; import clsx from "clsx";
import { Container } from "./Container";
import { Button } from "./ui/button";
import { trackGAEvent } from "./analitycs";
import { Switch } from "./ui/switch";
import { useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { Container } from "./Container";
import { trackGAEvent } from "./analitycs";
import { Button } from "./ui/button";
import { Switch } from "./ui/switch";
function SwirlyDoodle(props: React.ComponentPropsWithoutRef<"svg">) { function SwirlyDoodle(props: React.ComponentPropsWithoutRef<"svg">) {
return ( return (

View File

@@ -1,29 +1,29 @@
"use client" "use client";
import * as React from "react" import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as SwitchPrimitives from "@radix-ui/react-switch" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Switch = React.forwardRef< const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>, React.ElementRef<typeof SwitchPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<SwitchPrimitives.Root <SwitchPrimitives.Root
className={cn( className={cn(
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className className,
)} )}
{...props} {...props}
ref={ref} ref={ref}
> >
<SwitchPrimitives.Thumb <SwitchPrimitives.Thumb
className={cn( className={cn(
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0" "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
)} )}
/> />
</SwitchPrimitives.Root> </SwitchPrimitives.Root>
)) ));
Switch.displayName = SwitchPrimitives.Root.displayName Switch.displayName = SwitchPrimitives.Root.displayName;
export { Switch } export { Switch };

View File

@@ -23,7 +23,7 @@
"format-and-lint": "biome check .", "format-and-lint": "biome check .",
"check": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true", "check": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true",
"format-and-lint:fix": "biome check . --write", "format-and-lint:fix": "biome check . --write",
"prepare": "node ./.config/.husky/install.mjs" "prepare": "node .husky/install.mjs"
}, },
"devDependencies": { "devDependencies": {
"dotenv": "16.4.5", "dotenv": "16.4.5",
@@ -31,7 +31,7 @@
"tsx": "4.16.2", "tsx": "4.16.2",
"lint-staged": "^15.2.7", "lint-staged": "^15.2.7",
"@biomejs/biome": "1.8.3", "@biomejs/biome": "1.8.3",
"husky": "^9.0.11", "husky": "^9.1.6",
"@commitlint/cli": "^19.3.0", "@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2", "@commitlint/config-conventional": "^19.2.2",
"@types/node": "^18.17.0" "@types/node": "^18.17.0"

View File

@@ -1,8 +1,8 @@
import { IS_CLOUD, paths } from "@/server/constants"; import { IS_CLOUD, paths } from "@/server/constants";
import { updateAdmin } from "@/server/services/admin"; import { updateAdmin } from "@/server/services/admin";
import { type RotatingFileStream, createStream } from "rotating-file-stream"; import { type RotatingFileStream, createStream } from "rotating-file-stream";
import { execAsync } from "../process/execAsync";
import { db } from "../../db"; import { db } from "../../db";
import { execAsync } from "../process/execAsync";
class LogRotationManager { class LogRotationManager {
private static instance: LogRotationManager; private static instance: LogRotationManager;

View File

@@ -2,7 +2,7 @@ import { createWriteStream } from "node:fs";
import path, { join } from "node:path"; import path, { join } from "node:path";
import { paths } from "@/server/constants"; import { paths } from "@/server/constants";
import type { Compose } from "@/server/services/compose"; import type { Compose } from "@/server/services/compose";
import { updateSSHKeyById } from "@/server/services/ssh-key"; import { findSSHKeyById, updateSSHKeyById } from "@/server/services/ssh-key";
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { recreateDirectory } from "../filesystem/directory"; import { recreateDirectory } from "../filesystem/directory";
import { execAsync, execAsyncRemote } from "../process/execAsync"; import { execAsync, execAsyncRemote } from "../process/execAsync";
@@ -29,13 +29,29 @@ export const cloneGitRepository = async (
} }
const writeStream = createWriteStream(logPath, { flags: "a" }); const writeStream = createWriteStream(logPath, { flags: "a" });
const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`); const temporalKeyPath = path.join("/tmp", "id_rsa");
if (customGitSSHKeyId) {
const sshKey = await findSSHKeyById(customGitSSHKeyId);
await execAsync(`
echo "${sshKey.privateKey}" > ${temporalKeyPath}
chmod 600 ${temporalKeyPath}
`);
}
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH; const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
const outputPath = join(basePath, appName, "code"); const outputPath = join(basePath, appName, "code");
const knownHostsPath = path.join(SSH_PATH, "known_hosts"); const knownHostsPath = path.join(SSH_PATH, "known_hosts");
try { try {
if (!isHttpOrHttps(customGitUrl)) { if (!isHttpOrHttps(customGitUrl)) {
if (!customGitSSHKeyId) {
throw new TRPCError({
code: "BAD_REQUEST",
message:
"Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key",
});
}
await addHostToKnownHosts(customGitUrl); await addHostToKnownHosts(customGitUrl);
} }
await recreateDirectory(outputPath); await recreateDirectory(outputPath);
@@ -74,7 +90,7 @@ export const cloneGitRepository = async (
env: { env: {
...process.env, ...process.env,
...(customGitSSHKeyId && { ...(customGitSSHKeyId && {
GIT_SSH_COMMAND: `ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}`, GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath} -o UserKnownHostsFile=${knownHostsPath}`,
}), }),
}, },
}, },
@@ -122,7 +138,6 @@ export const getCustomGitCloneCommand = async (
}); });
} }
const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`);
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH; const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
const outputPath = join(basePath, appName, "code"); const outputPath = join(basePath, appName, "code");
const knownHostsPath = path.join(SSH_PATH, "known_hosts"); const knownHostsPath = path.join(SSH_PATH, "known_hosts");
@@ -136,6 +151,13 @@ export const getCustomGitCloneCommand = async (
try { try {
const command = []; const command = [];
if (!isHttpOrHttps(customGitUrl)) { if (!isHttpOrHttps(customGitUrl)) {
if (!customGitSSHKeyId) {
command.push(
`echo "Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key ❌" >> ${logPath};
exit 1;
`,
);
}
command.push(addHostToKnownHostsCommand(customGitUrl)); command.push(addHostToKnownHostsCommand(customGitUrl));
} }
command.push(`rm -rf ${outputPath};`); command.push(`rm -rf ${outputPath};`);
@@ -144,8 +166,14 @@ export const getCustomGitCloneCommand = async (
`echo "Cloning Custom Git ${customGitUrl}" to ${outputPath}: ✅ >> ${logPath};`, `echo "Cloning Custom Git ${customGitUrl}" to ${outputPath}: ✅ >> ${logPath};`,
); );
if (customGitSSHKeyId) { if (customGitSSHKeyId) {
const sshKey = await findSSHKeyById(customGitSSHKeyId);
const gitSshCommand = `ssh -i /tmp/id_rsa -o UserKnownHostsFile=${knownHostsPath}`;
command.push( command.push(
`GIT_SSH_COMMAND="ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}"`, `
echo "${sshKey.privateKey}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
export GIT_SSH_COMMAND="${gitSshCommand}"
`,
); );
} }
@@ -184,7 +212,7 @@ const addHostToKnownHosts = async (repositoryURL: string) => {
}; };
const addHostToKnownHostsCommand = (repositoryURL: string) => { const addHostToKnownHostsCommand = (repositoryURL: string) => {
const { SSH_PATH } = paths(); const { SSH_PATH } = paths(true);
const { domain, port } = sanitizeRepoPathSSH(repositoryURL); const { domain, port } = sanitizeRepoPathSSH(repositoryURL);
const knownHostsPath = path.join(SSH_PATH, "known_hosts"); const knownHostsPath = path.join(SSH_PATH, "known_hosts");
@@ -242,13 +270,31 @@ export const cloneGitRawRepository = async (entity: {
} }
const { SSH_PATH, COMPOSE_PATH } = paths(); const { SSH_PATH, COMPOSE_PATH } = paths();
const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`); const temporalKeyPath = path.join("/tmp", "id_rsa");
const basePath = COMPOSE_PATH; const basePath = COMPOSE_PATH;
const outputPath = join(basePath, appName, "code"); const outputPath = join(basePath, appName, "code");
const knownHostsPath = path.join(SSH_PATH, "known_hosts"); const knownHostsPath = path.join(SSH_PATH, "known_hosts");
if (customGitSSHKeyId) {
const sshKey = await findSSHKeyById(customGitSSHKeyId);
await execAsync(`
echo "${sshKey.privateKey}" > ${temporalKeyPath}
chmod 600 ${temporalKeyPath}
`);
}
try { try {
await addHostToKnownHosts(customGitUrl); if (!isHttpOrHttps(customGitUrl)) {
if (!customGitSSHKeyId) {
throw new TRPCError({
code: "BAD_REQUEST",
message:
"Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key",
});
}
await addHostToKnownHosts(customGitUrl);
}
await recreateDirectory(outputPath); await recreateDirectory(outputPath);
if (customGitSSHKeyId) { if (customGitSSHKeyId) {
@@ -275,7 +321,7 @@ export const cloneGitRawRepository = async (entity: {
env: { env: {
...process.env, ...process.env,
...(customGitSSHKeyId && { ...(customGitSSHKeyId && {
GIT_SSH_COMMAND: `ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}`, GIT_SSH_COMMAND: `ssh -i ${temporalKeyPath} -o UserKnownHostsFile=${knownHostsPath}`,
}), }),
}, },
}, },
@@ -308,7 +354,6 @@ export const cloneRawGitRepositoryRemote = async (compose: Compose) => {
} }
const { SSH_PATH, COMPOSE_PATH } = paths(true); const { SSH_PATH, COMPOSE_PATH } = paths(true);
const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`);
const basePath = COMPOSE_PATH; const basePath = COMPOSE_PATH;
const outputPath = join(basePath, appName, "code"); const outputPath = join(basePath, appName, "code");
const knownHostsPath = path.join(SSH_PATH, "known_hosts"); const knownHostsPath = path.join(SSH_PATH, "known_hosts");
@@ -322,13 +367,26 @@ export const cloneRawGitRepositoryRemote = async (compose: Compose) => {
try { try {
const command = []; const command = [];
if (!isHttpOrHttps(customGitUrl)) { if (!isHttpOrHttps(customGitUrl)) {
if (!customGitSSHKeyId) {
command.push(
`echo "Error: you are trying to clone a ssh repository without a ssh key, please set a ssh key ❌" ;
exit 1;
`,
);
}
command.push(addHostToKnownHostsCommand(customGitUrl)); command.push(addHostToKnownHostsCommand(customGitUrl));
} }
command.push(`rm -rf ${outputPath};`); command.push(`rm -rf ${outputPath};`);
command.push(`mkdir -p ${outputPath};`); command.push(`mkdir -p ${outputPath};`);
if (customGitSSHKeyId) { if (customGitSSHKeyId) {
const sshKey = await findSSHKeyById(customGitSSHKeyId);
const gitSshCommand = `ssh -i /tmp/id_rsa -o UserKnownHostsFile=${knownHostsPath}`;
command.push( command.push(
`GIT_SSH_COMMAND="ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}"`, `
echo "${sshKey.privateKey}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
export GIT_SSH_COMMAND="${gitSshCommand}"
`,
); );
} }

16
pnpm-lock.yaml generated
View File

@@ -31,8 +31,8 @@ importers:
specifier: 0.20.2 specifier: 0.20.2
version: 0.20.2 version: 0.20.2
husky: husky:
specifier: ^9.0.11 specifier: ^9.1.6
version: 9.1.3 version: 9.1.6
lint-staged: lint-staged:
specifier: ^15.2.7 specifier: ^15.2.7
version: 15.2.7 version: 15.2.7
@@ -5504,8 +5504,8 @@ packages:
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
engines: {node: '>=16.17.0'} engines: {node: '>=16.17.0'}
husky@9.1.3: husky@9.1.6:
resolution: {integrity: sha512-ET3TQmQgdIu0pt+jKkpo5oGyg/4MQZpG6xcam5J5JyNJV+CBT23OBpCF15bKHKycRyMH9k6ONy8g2HdGIsSkMQ==} resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@@ -13020,7 +13020,7 @@ snapshots:
eslint: 8.45.0 eslint: 8.45.0
eslint-import-resolver-node: 0.3.9 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-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-jsx-a11y: 6.9.0(eslint@8.45.0)
eslint-plugin-react: 7.35.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) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.45.0)
@@ -13044,7 +13044,7 @@ snapshots:
enhanced-resolve: 5.17.1 enhanced-resolve: 5.17.1
eslint: 8.45.0 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-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 fast-glob: 3.3.2
get-tsconfig: 4.7.5 get-tsconfig: 4.7.5
is-core-module: 2.15.0 is-core-module: 2.15.0
@@ -13066,7 +13066,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - 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: dependencies:
array-includes: 3.1.8 array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5 array.prototype.findlastindex: 1.2.5
@@ -13816,7 +13816,7 @@ snapshots:
human-signals@5.0.0: {} human-signals@5.0.0: {}
husky@9.1.3: {} husky@9.1.6: {}
hyperdyperid@1.2.0: {} hyperdyperid@1.2.0: {}