mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge branch 'canary' into feat/shared-ssh
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { domain } from "@/server/db/validations";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { boolean, integer, pgTable, serial, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { applications } from "./application";
|
||||
import { certificateType } from "./shared";
|
||||
|
||||
@@ -31,27 +31,17 @@ export const domainsRelations = relations(domains, ({ one }) => ({
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
}));
|
||||
const hostnameRegex = /^[a-zA-Z0-9][a-zA-Z0-9\.-]*\.[a-zA-Z]{2,}$/;
|
||||
const createSchema = createInsertSchema(domains, {
|
||||
domainId: z.string().min(1),
|
||||
host: z.string().min(1),
|
||||
path: z.string().min(1),
|
||||
port: z.number(),
|
||||
https: z.boolean(),
|
||||
applicationId: z.string(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]),
|
||||
});
|
||||
|
||||
export const apiCreateDomain = createSchema
|
||||
.pick({
|
||||
host: true,
|
||||
path: true,
|
||||
port: true,
|
||||
https: true,
|
||||
applicationId: true,
|
||||
certificateType: true,
|
||||
})
|
||||
.required();
|
||||
const createSchema = createInsertSchema(domains, domain._def.schema.shape);
|
||||
|
||||
export const apiCreateDomain = createSchema.pick({
|
||||
host: true,
|
||||
path: true,
|
||||
port: true,
|
||||
https: true,
|
||||
applicationId: true,
|
||||
certificateType: true,
|
||||
});
|
||||
|
||||
export const apiFindDomain = createSchema
|
||||
.pick({
|
||||
@@ -59,19 +49,16 @@ export const apiFindDomain = createSchema
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindDomainByApplication = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
export const apiFindDomainByApplication = createSchema.pick({
|
||||
applicationId: true,
|
||||
});
|
||||
|
||||
export const apiUpdateDomain = createSchema
|
||||
.pick({
|
||||
domainId: true,
|
||||
host: true,
|
||||
path: true,
|
||||
port: true,
|
||||
https: true,
|
||||
certificateType: true,
|
||||
})
|
||||
.required();
|
||||
.merge(createSchema.pick({ domainId: true }).required());
|
||||
|
||||
@@ -33,3 +33,28 @@ export const sshKeyUpdate = sshKeyCreate.pick({
|
||||
});
|
||||
|
||||
export const sshKeyType = z.enum(["rsa", "ed25519"]).optional();
|
||||
|
||||
export const domain = z
|
||||
.object({
|
||||
host: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9\.-]*\.[a-zA-Z]{2,}$/, {
|
||||
message: "Invalid hostname",
|
||||
}),
|
||||
path: z.string().min(1).optional(),
|
||||
port: z
|
||||
.number()
|
||||
.min(1, { message: "Port must be at least 1" })
|
||||
.max(65535, { message: "Port must be 65535 or below" })
|
||||
.optional(),
|
||||
https: z.boolean().optional(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]).optional(),
|
||||
})
|
||||
.superRefine((input, ctx) => {
|
||||
if (input.https && !input.certificateType) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ["certificateType"],
|
||||
message: "Required",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { existsSync, mkdirSync } from "node:fs";
|
||||
import { chmodSync, existsSync, mkdirSync } from "node:fs";
|
||||
import {
|
||||
APPLICATIONS_PATH,
|
||||
BASE_PATH,
|
||||
@@ -32,6 +32,9 @@ export const setupDirectories = () => {
|
||||
for (const dir of directories) {
|
||||
try {
|
||||
createDirectoryIfNotExist(dir);
|
||||
if (dir === SSH_PATH) {
|
||||
chmodSync(SSH_PATH, "600");
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error, " On path: ", dir);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
||||
import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { CreateServiceOptions } from "dockerode";
|
||||
import { dump } from "js-yaml";
|
||||
@@ -86,6 +86,7 @@ export const initializeTraefik = async () => {
|
||||
|
||||
export const createDefaultServerTraefikConfig = () => {
|
||||
const configFilePath = path.join(DYNAMIC_TRAEFIK_PATH, "dokploy.yml");
|
||||
|
||||
if (existsSync(configFilePath)) {
|
||||
console.log("Default traefik config already exists");
|
||||
return;
|
||||
@@ -125,6 +126,11 @@ export const createDefaultServerTraefikConfig = () => {
|
||||
|
||||
export const createDefaultTraefikConfig = () => {
|
||||
const mainConfig = path.join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
||||
const acmeJsonPath = path.join(DYNAMIC_TRAEFIK_PATH, "acme.json");
|
||||
|
||||
if (existsSync(acmeJsonPath)) {
|
||||
chmodSync(acmeJsonPath, "600");
|
||||
}
|
||||
if (existsSync(mainConfig)) {
|
||||
console.log("Main config already exists");
|
||||
return;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { WriteStream } from "node:fs";
|
||||
import { docker } from "@/server/constants";
|
||||
import { prepareBuildArgs } from "@/server/utils/docker/utils";
|
||||
import * as tar from "tar-fs";
|
||||
import { prepareEnvironmentVariables } from "@/server/utils/docker/utils";
|
||||
import type { ApplicationNested } from ".";
|
||||
import { getBuildAppDirectory } from "../filesystem/directory";
|
||||
import { spawnAsync } from "../process/spawnAsync";
|
||||
import { createEnvFile } from "./utils";
|
||||
|
||||
export const buildCustomDocker = async (
|
||||
@@ -14,29 +13,30 @@ export const buildCustomDocker = async (
|
||||
const dockerFilePath = getBuildAppDirectory(application);
|
||||
try {
|
||||
const image = `${appName}`;
|
||||
|
||||
const contextPath =
|
||||
dockerFilePath.substring(0, dockerFilePath.lastIndexOf("/") + 1) || ".";
|
||||
const tarStream = tar.pack(contextPath);
|
||||
const args = prepareEnvironmentVariables(buildArgs);
|
||||
|
||||
const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."];
|
||||
|
||||
for (const arg of args) {
|
||||
commandArgs.push("--build-arg", arg);
|
||||
}
|
||||
|
||||
createEnvFile(dockerFilePath, env);
|
||||
|
||||
const stream = await docker.buildImage(tarStream, {
|
||||
t: image,
|
||||
buildargs: prepareBuildArgs(buildArgs),
|
||||
dockerfile: dockerFilePath.substring(dockerFilePath.lastIndexOf("/") + 1),
|
||||
});
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
docker.modem.followProgress(
|
||||
stream,
|
||||
(err, res) => (err ? reject(err) : resolve(res)),
|
||||
(event) => {
|
||||
if (event.stream) {
|
||||
writeStream.write(event.stream);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
await spawnAsync(
|
||||
"docker",
|
||||
commandArgs,
|
||||
(data) => {
|
||||
if (writeStream.writable) {
|
||||
writeStream.write(data);
|
||||
}
|
||||
},
|
||||
{
|
||||
cwd: contextPath,
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user