mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-12 17:35:21 +02:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cd624c7ea | ||
|
|
34b12a0315 | ||
|
|
e9e6064eb6 | ||
|
|
6b7712e35f | ||
|
|
89c7e96df0 | ||
|
|
8af5afbb6c | ||
|
|
ef9f16a3c3 | ||
|
|
d15b6387a3 | ||
|
|
2e9e39dcf5 | ||
|
|
d901b02e92 | ||
|
|
766a25ccad | ||
|
|
fae97b1817 | ||
|
|
b2cc5e58a3 | ||
|
|
1b56a6b400 | ||
|
|
996d449f0f | ||
|
|
3b197f3624 |
@@ -119,7 +119,7 @@ export const UpdateVolume = ({
|
|||||||
} else if (typeForm === "file") {
|
} else if (typeForm === "file") {
|
||||||
form.reset({
|
form.reset({
|
||||||
content: data.content || "",
|
content: data.content || "",
|
||||||
mountPath: data.mountPath,
|
mountPath: "/",
|
||||||
filePath: data.filePath || "",
|
filePath: data.filePath || "",
|
||||||
type: "file",
|
type: "file",
|
||||||
});
|
});
|
||||||
@@ -296,15 +296,13 @@ export const UpdateVolume = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<DialogClose>
|
<Button
|
||||||
<Button
|
isLoading={isLoading}
|
||||||
isLoading={isLoading}
|
// form="hook-form-update-volume"
|
||||||
form="hook-form-update-volume"
|
type="submit"
|
||||||
type="submit"
|
>
|
||||||
>
|
Update
|
||||||
Update
|
</Button>
|
||||||
</Button>
|
|
||||||
</DialogClose>
|
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dokploy",
|
"name": "dokploy",
|
||||||
"version": "v0.10.7",
|
"version": "v0.10.10",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -132,16 +132,20 @@ export const projectRouter = createTRPCRouter({
|
|||||||
if (accesedProjects.length === 0) {
|
if (accesedProjects.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = await db.query.projects.findMany({
|
const query = await db.query.projects.findMany({
|
||||||
where: sql`${projects.projectId} IN (${sql.join(
|
where: and(
|
||||||
accesedProjects.map((projectId) => sql`${projectId}`),
|
sql`${projects.projectId} IN (${sql.join(
|
||||||
sql`, `,
|
accesedProjects.map((projectId) => sql`${projectId}`),
|
||||||
)})`,
|
sql`, `,
|
||||||
|
)})`,
|
||||||
|
eq(projects.adminId, ctx.user.adminId),
|
||||||
|
),
|
||||||
with: {
|
with: {
|
||||||
applications: {
|
applications: {
|
||||||
where: and(
|
where: buildServiceFilter(
|
||||||
buildServiceFilter(applications.applicationId, accesedServices),
|
applications.applicationId,
|
||||||
eq(projects.adminId, ctx.user.adminId),
|
accesedServices,
|
||||||
),
|
),
|
||||||
with: { domains: true },
|
with: { domains: true },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
await cleanUpUnusedImages(server.serverId);
|
await cleanUpUnusedImages(server.serverId);
|
||||||
await cleanUpDockerBuilder(server.serverId);
|
await cleanUpDockerBuilder(server.serverId);
|
||||||
await cleanUpSystemPrune(server.serverId);
|
await cleanUpSystemPrune(server.serverId);
|
||||||
await sendDockerCleanupNotifications();
|
await sendDockerCleanupNotifications(server.adminId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -278,7 +278,7 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
await cleanUpUnusedImages();
|
await cleanUpUnusedImages();
|
||||||
await cleanUpDockerBuilder();
|
await cleanUpDockerBuilder();
|
||||||
await cleanUpSystemPrune();
|
await cleanUpSystemPrune();
|
||||||
await sendDockerCleanupNotifications();
|
await sendDockerCleanupNotifications(admin.adminId);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const currentJob = scheduledJobs["docker-cleanup"];
|
const currentJob = scheduledJobs["docker-cleanup"];
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
}
|
}
|
||||||
stream
|
stream
|
||||||
.on("close", () => {
|
.on("close", () => {
|
||||||
console.log("Connection closed ✅ Container Logs");
|
|
||||||
client.end();
|
client.end();
|
||||||
ws.close();
|
ws.close();
|
||||||
})
|
})
|
||||||
@@ -88,7 +87,6 @@ export const setupDockerContainerLogsWebSocketServer = (
|
|||||||
privateKey: server.sshKey?.privateKey,
|
privateKey: server.sshKey?.privateKey,
|
||||||
});
|
});
|
||||||
ws.on("close", () => {
|
ws.on("close", () => {
|
||||||
console.log("Connection closed ✅, From Container Logs WS");
|
|
||||||
client.end();
|
client.end();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ export const setupTerminalWebSocketServer = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
ws.on("close", () => {
|
ws.on("close", () => {
|
||||||
console.log("Connection closed ✅");
|
|
||||||
stream.end();
|
stream.end();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
version: '3.3'
|
version: "3"
|
||||||
services:
|
|
||||||
stirling-pdf:
|
|
||||||
image: frooodle/s-pdf:0.30.1
|
|
||||||
ports:
|
|
||||||
- '8080'
|
|
||||||
volumes:
|
|
||||||
- training-data:/usr/share/tessdata #Required for extra OCR languages
|
|
||||||
- extra-configs:/configs
|
|
||||||
# - /location/of/customFiles:/customFiles/
|
|
||||||
# - /location/of/logs:/logs/
|
|
||||||
environment:
|
|
||||||
- DOCKER_ENABLE_SECURITY=false
|
|
||||||
- INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
|
|
||||||
- LANGS=en_GB
|
|
||||||
|
|
||||||
volumes:
|
services:
|
||||||
training-data: {}
|
soketi:
|
||||||
extra-configs: {}
|
image: quay.io/soketi/soketi:1.4-16-debian
|
||||||
|
container_name: soketi
|
||||||
|
environment:
|
||||||
|
SOKETI_DEBUG: "1"
|
||||||
|
SOKETI_HOST: "0.0.0.0"
|
||||||
|
SOKETI_PORT: "6001"
|
||||||
|
SOKETI_METRICS_SERVER_PORT: "9601"
|
||||||
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { relations, sql } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import { boolean, pgEnum, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
import { pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { admins } from "./admin";
|
import { admins } from "./admin";
|
||||||
import { applications } from "./application";
|
import { applications } from "./application";
|
||||||
import { auth } from "./auth";
|
|
||||||
/**
|
/**
|
||||||
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||||
* database instance for multiple projects.
|
* database instance for multiple projects.
|
||||||
@@ -48,7 +47,7 @@ const createSchema = createInsertSchema(registry, {
|
|||||||
registryUrl: z.string(),
|
registryUrl: z.string(),
|
||||||
adminId: z.string().min(1),
|
adminId: z.string().min(1),
|
||||||
registryId: z.string().min(1),
|
registryId: z.string().min(1),
|
||||||
registryType: z.enum(["selfHosted", "cloud"]),
|
registryType: z.enum(["cloud"]),
|
||||||
imagePrefix: z.string().nullable().optional(),
|
imagePrefix: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -59,7 +58,7 @@ export const apiCreateRegistry = createSchema
|
|||||||
username: z.string().min(1),
|
username: z.string().min(1),
|
||||||
password: z.string().min(1),
|
password: z.string().min(1),
|
||||||
registryUrl: z.string(),
|
registryUrl: z.string(),
|
||||||
registryType: z.enum(["selfHosted", "cloud"]),
|
registryType: z.enum(["cloud"]),
|
||||||
imagePrefix: z.string().nullable().optional(),
|
imagePrefix: z.string().nullable().optional(),
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
@@ -72,7 +71,7 @@ export const apiTestRegistry = createSchema.pick({}).extend({
|
|||||||
username: z.string().min(1),
|
username: z.string().min(1),
|
||||||
password: z.string().min(1),
|
password: z.string().min(1),
|
||||||
registryUrl: z.string(),
|
registryUrl: z.string(),
|
||||||
registryType: z.enum(["selfHosted", "cloud"]),
|
registryType: z.enum(["cloud"]),
|
||||||
imagePrefix: z.string().nullable().optional(),
|
imagePrefix: z.string().nullable().optional(),
|
||||||
serverId: z.string().optional(),
|
serverId: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ export const deployApplication = async ({
|
|||||||
applicationName: application.name,
|
applicationName: application.name,
|
||||||
applicationType: "application",
|
applicationType: "application",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: application.project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
@@ -204,6 +205,7 @@ export const deployApplication = async ({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error to build",
|
errorMessage: error?.message || "Error to build",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: application.project.adminId,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
@@ -314,6 +316,7 @@ export const deployRemoteApplication = async ({
|
|||||||
applicationName: application.name,
|
applicationName: application.name,
|
||||||
applicationType: "application",
|
applicationType: "application",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: application.project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -336,6 +339,7 @@ export const deployRemoteApplication = async ({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error to build",
|
errorMessage: error?.message || "Error to build",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: application.project.adminId,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ export const deployCompose = async ({
|
|||||||
applicationName: compose.name,
|
applicationName: compose.name,
|
||||||
applicationType: "compose",
|
applicationType: "compose",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: compose.project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
@@ -248,6 +249,7 @@ export const deployCompose = async ({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error to build",
|
errorMessage: error?.message || "Error to build",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: compose.project.adminId,
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@@ -353,6 +355,7 @@ export const deployRemoteCompose = async ({
|
|||||||
applicationName: compose.name,
|
applicationName: compose.name,
|
||||||
applicationType: "compose",
|
applicationType: "compose",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: compose.project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -376,6 +379,7 @@ export const deployRemoteCompose = async ({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error to build",
|
errorMessage: error?.message || "Error to build",
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId: compose.project.adminId,
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ const installRequirements = async (serverId: string, logPath: string) => {
|
|||||||
}
|
}
|
||||||
stream
|
stream
|
||||||
.on("close", () => {
|
.on("close", () => {
|
||||||
writeStream.write("Connection closed ✅");
|
|
||||||
client.end();
|
client.end();
|
||||||
resolve();
|
resolve();
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export const runMariadbBackup = async (
|
|||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
databaseType: "mariadb",
|
databaseType: "mariadb",
|
||||||
type: "success",
|
type: "success",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -59,6 +60,7 @@ export const runMariadbBackup = async (
|
|||||||
type: "error",
|
type: "error",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
|||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
databaseType: "mongodb",
|
databaseType: "mongodb",
|
||||||
type: "success",
|
type: "success",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -56,6 +57,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
|||||||
type: "error",
|
type: "error",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
|||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
databaseType: "mysql",
|
databaseType: "mysql",
|
||||||
type: "success",
|
type: "success",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -56,6 +57,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
|||||||
type: "error",
|
type: "error",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export const runPostgresBackup = async (
|
|||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
databaseType: "postgres",
|
databaseType: "postgres",
|
||||||
type: "success",
|
type: "success",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await sendDatabaseBackupNotifications({
|
await sendDatabaseBackupNotifications({
|
||||||
@@ -58,6 +59,7 @@ export const runPostgresBackup = async (
|
|||||||
type: "error",
|
type: "error",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
errorMessage: error?.message || "Error message not provided",
|
errorMessage: error?.message || "Error message not provided",
|
||||||
|
adminId: project.adminId,
|
||||||
});
|
});
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { createWriteStream } from "node:fs";
|
import { createWriteStream } from "node:fs";
|
||||||
|
import { join } from "node:path";
|
||||||
import type { InferResultType } from "@dokploy/server/types/with";
|
import type { InferResultType } from "@dokploy/server/types/with";
|
||||||
import type { CreateServiceOptions } from "dockerode";
|
import type { CreateServiceOptions } from "dockerode";
|
||||||
import { uploadImage } from "../cluster/upload";
|
import { uploadImage, uploadImageRemoteCommand } from "../cluster/upload";
|
||||||
import {
|
import {
|
||||||
calculateResources,
|
calculateResources,
|
||||||
generateBindMounts,
|
generateBindMounts,
|
||||||
@@ -69,19 +70,30 @@ export const getBuildCommand = (
|
|||||||
application: ApplicationNested,
|
application: ApplicationNested,
|
||||||
logPath: string,
|
logPath: string,
|
||||||
) => {
|
) => {
|
||||||
const { buildType } = application;
|
let command = "";
|
||||||
|
const { buildType, registry } = application;
|
||||||
switch (buildType) {
|
switch (buildType) {
|
||||||
case "nixpacks":
|
case "nixpacks":
|
||||||
return getNixpacksCommand(application, logPath);
|
command = getNixpacksCommand(application, logPath);
|
||||||
|
break;
|
||||||
case "heroku_buildpacks":
|
case "heroku_buildpacks":
|
||||||
return getHerokuCommand(application, logPath);
|
command = getHerokuCommand(application, logPath);
|
||||||
|
break;
|
||||||
case "paketo_buildpacks":
|
case "paketo_buildpacks":
|
||||||
return getPaketoCommand(application, logPath);
|
command = getPaketoCommand(application, logPath);
|
||||||
|
break;
|
||||||
case "static":
|
case "static":
|
||||||
return getStaticCommand(application, logPath);
|
command = getStaticCommand(application, logPath);
|
||||||
|
break;
|
||||||
case "dockerfile":
|
case "dockerfile":
|
||||||
return getDockerCommand(application, logPath);
|
command = getDockerCommand(application, logPath);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (registry) {
|
||||||
|
command += uploadImageRemoteCommand(application, logPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return command;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mechanizeDockerContainer = async (
|
export const mechanizeDockerContainer = async (
|
||||||
@@ -186,11 +198,11 @@ const getImageName = (application: ApplicationNested) => {
|
|||||||
return dockerImage || "ERROR-NO-IMAGE-PROVIDED";
|
return dockerImage || "ERROR-NO-IMAGE-PROVIDED";
|
||||||
}
|
}
|
||||||
|
|
||||||
const registryUrl = registry?.registryUrl || "";
|
if (registry) {
|
||||||
const imagePrefix = registry?.imagePrefix ? `${registry.imagePrefix}/` : "";
|
return join(registry.imagePrefix || "", appName);
|
||||||
return registry
|
}
|
||||||
? `${registryUrl}/${imagePrefix}${appName}`
|
|
||||||
: `${appName}:latest`;
|
return `${appName}:latest`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAuthConfig = (application: ApplicationNested) => {
|
const getAuthConfig = (application: ApplicationNested) => {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { WriteStream } from "node:fs";
|
import type { WriteStream } from "node:fs";
|
||||||
|
import { join } from "node:path";
|
||||||
import type { ApplicationNested } from "../builders";
|
import type { ApplicationNested } from "../builders";
|
||||||
import { spawnAsync } from "../process/spawnAsync";
|
import { spawnAsync } from "../process/spawnAsync";
|
||||||
|
|
||||||
@@ -16,23 +17,14 @@ export const uploadImage = async (
|
|||||||
const { appName } = application;
|
const { appName } = application;
|
||||||
const imageName = `${appName}:latest`;
|
const imageName = `${appName}:latest`;
|
||||||
|
|
||||||
const finalURL =
|
const finalURL = registryUrl;
|
||||||
registryType === "selfHosted"
|
|
||||||
? process.env.NODE_ENV === "development"
|
|
||||||
? "localhost:5000"
|
|
||||||
: registryUrl
|
|
||||||
: registryUrl;
|
|
||||||
|
|
||||||
const registryTag = imagePrefix
|
const registryTag = join(imagePrefix || "", imageName);
|
||||||
? `${finalURL}/${imagePrefix}/${imageName}`
|
|
||||||
: `${finalURL}/${imageName}`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(finalURL, registryTag);
|
|
||||||
writeStream.write(
|
writeStream.write(
|
||||||
`📦 [Enabled Registry] Uploading image to ${registry.registryType} | ${registryTag} | ${finalURL}\n`,
|
`📦 [Enabled Registry] Uploading image to ${registry.registryType} | ${registryTag} | ${finalURL}\n`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await spawnAsync(
|
await spawnAsync(
|
||||||
"docker",
|
"docker",
|
||||||
["login", finalURL, "-u", registry.username, "-p", registry.password],
|
["login", finalURL, "-u", registry.username, "-p", registry.password],
|
||||||
@@ -59,7 +51,48 @@ export const uploadImage = async (
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// docker:
|
|
||||||
// endpoint: "unix:///var/run/docker.sock"
|
export const uploadImageRemoteCommand = (
|
||||||
// exposedByDefault: false
|
application: ApplicationNested,
|
||||||
// swarmMode: true
|
logPath: string,
|
||||||
|
) => {
|
||||||
|
const registry = application.registry;
|
||||||
|
|
||||||
|
if (!registry) {
|
||||||
|
throw new Error("Registry not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const { registryUrl, imagePrefix } = registry;
|
||||||
|
const { appName } = application;
|
||||||
|
const imageName = `${appName}:latest`;
|
||||||
|
|
||||||
|
const finalURL = registryUrl;
|
||||||
|
|
||||||
|
const registryTag = join(imagePrefix || "", imageName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const command = `
|
||||||
|
echo "📦 [Enabled Registry] Uploading image to '${registry.registryType}' | '${registryTag}'" >> ${logPath};
|
||||||
|
docker login ${finalURL} -u ${registry.username} -p ${registry.password} >> ${logPath} 2>> ${logPath} || {
|
||||||
|
echo "❌ DockerHub Failed" >> ${logPath};
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
echo "✅ DockerHub Login Success" >> ${logPath};
|
||||||
|
docker tag ${imageName} ${registryTag} >> ${logPath} 2>> ${logPath} || {
|
||||||
|
echo "❌ Error tagging image" >> ${logPath};
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
echo "✅ Image Tagged" >> ${logPath};
|
||||||
|
|
||||||
|
docker push ${registryTag} 2>> ${logPath} || {
|
||||||
|
echo "❌ Error pushing image" >> ${logPath};
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
echo "✅ Image Pushed" >> ${logPath};
|
||||||
|
`;
|
||||||
|
return command;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { db } from "@dokploy/server/db";
|
|||||||
import { notifications } from "@dokploy/server/db/schema";
|
import { notifications } from "@dokploy/server/db/schema";
|
||||||
import BuildFailedEmail from "@dokploy/server/emails/emails/build-failed";
|
import BuildFailedEmail from "@dokploy/server/emails/emails/build-failed";
|
||||||
import { renderAsync } from "@react-email/components";
|
import { renderAsync } from "@react-email/components";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
sendDiscordNotification,
|
sendDiscordNotification,
|
||||||
sendEmailNotification,
|
sendEmailNotification,
|
||||||
@@ -16,6 +16,7 @@ interface Props {
|
|||||||
applicationType: string;
|
applicationType: string;
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
buildLink: string;
|
buildLink: string;
|
||||||
|
adminId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendBuildErrorNotifications = async ({
|
export const sendBuildErrorNotifications = async ({
|
||||||
@@ -24,10 +25,14 @@ export const sendBuildErrorNotifications = async ({
|
|||||||
applicationType,
|
applicationType,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const notificationList = await db.query.notifications.findMany({
|
const notificationList = await db.query.notifications.findMany({
|
||||||
where: eq(notifications.appBuildError, true),
|
where: and(
|
||||||
|
eq(notifications.appBuildError, true),
|
||||||
|
eq(notifications.adminId, adminId),
|
||||||
|
),
|
||||||
with: {
|
with: {
|
||||||
email: true,
|
email: true,
|
||||||
discord: true,
|
discord: true,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { db } from "@dokploy/server/db";
|
|||||||
import { notifications } from "@dokploy/server/db/schema";
|
import { notifications } from "@dokploy/server/db/schema";
|
||||||
import BuildSuccessEmail from "@dokploy/server/emails/emails/build-success";
|
import BuildSuccessEmail from "@dokploy/server/emails/emails/build-success";
|
||||||
import { renderAsync } from "@react-email/components";
|
import { renderAsync } from "@react-email/components";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
sendDiscordNotification,
|
sendDiscordNotification,
|
||||||
sendEmailNotification,
|
sendEmailNotification,
|
||||||
@@ -15,6 +15,7 @@ interface Props {
|
|||||||
applicationName: string;
|
applicationName: string;
|
||||||
applicationType: string;
|
applicationType: string;
|
||||||
buildLink: string;
|
buildLink: string;
|
||||||
|
adminId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendBuildSuccessNotifications = async ({
|
export const sendBuildSuccessNotifications = async ({
|
||||||
@@ -22,10 +23,14 @@ export const sendBuildSuccessNotifications = async ({
|
|||||||
applicationName,
|
applicationName,
|
||||||
applicationType,
|
applicationType,
|
||||||
buildLink,
|
buildLink,
|
||||||
|
adminId,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const notificationList = await db.query.notifications.findMany({
|
const notificationList = await db.query.notifications.findMany({
|
||||||
where: eq(notifications.appDeploy, true),
|
where: and(
|
||||||
|
eq(notifications.appDeploy, true),
|
||||||
|
eq(notifications.adminId, adminId),
|
||||||
|
),
|
||||||
with: {
|
with: {
|
||||||
email: true,
|
email: true,
|
||||||
discord: true,
|
discord: true,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { db } from "@dokploy/server/db";
|
|||||||
import { notifications } from "@dokploy/server/db/schema";
|
import { notifications } from "@dokploy/server/db/schema";
|
||||||
import DatabaseBackupEmail from "@dokploy/server/emails/emails/database-backup";
|
import DatabaseBackupEmail from "@dokploy/server/emails/emails/database-backup";
|
||||||
import { renderAsync } from "@react-email/components";
|
import { renderAsync } from "@react-email/components";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
sendDiscordNotification,
|
sendDiscordNotification,
|
||||||
sendEmailNotification,
|
sendEmailNotification,
|
||||||
@@ -16,16 +16,21 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
databaseType,
|
databaseType,
|
||||||
type,
|
type,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
|
adminId,
|
||||||
}: {
|
}: {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
applicationName: string;
|
applicationName: string;
|
||||||
databaseType: "postgres" | "mysql" | "mongodb" | "mariadb";
|
databaseType: "postgres" | "mysql" | "mongodb" | "mariadb";
|
||||||
type: "error" | "success";
|
type: "error" | "success";
|
||||||
|
adminId: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const notificationList = await db.query.notifications.findMany({
|
const notificationList = await db.query.notifications.findMany({
|
||||||
where: eq(notifications.databaseBackup, true),
|
where: and(
|
||||||
|
eq(notifications.databaseBackup, true),
|
||||||
|
eq(notifications.adminId, adminId),
|
||||||
|
),
|
||||||
with: {
|
with: {
|
||||||
email: true,
|
email: true,
|
||||||
discord: true,
|
discord: true,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { db } from "@dokploy/server/db";
|
|||||||
import { notifications } from "@dokploy/server/db/schema";
|
import { notifications } from "@dokploy/server/db/schema";
|
||||||
import DockerCleanupEmail from "@dokploy/server/emails/emails/docker-cleanup";
|
import DockerCleanupEmail from "@dokploy/server/emails/emails/docker-cleanup";
|
||||||
import { renderAsync } from "@react-email/components";
|
import { renderAsync } from "@react-email/components";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
sendDiscordNotification,
|
sendDiscordNotification,
|
||||||
sendEmailNotification,
|
sendEmailNotification,
|
||||||
@@ -11,11 +11,15 @@ import {
|
|||||||
} from "./utils";
|
} from "./utils";
|
||||||
|
|
||||||
export const sendDockerCleanupNotifications = async (
|
export const sendDockerCleanupNotifications = async (
|
||||||
|
adminId: string,
|
||||||
message = "Docker cleanup for dokploy",
|
message = "Docker cleanup for dokploy",
|
||||||
) => {
|
) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const notificationList = await db.query.notifications.findMany({
|
const notificationList = await db.query.notifications.findMany({
|
||||||
where: eq(notifications.dockerCleanup, true),
|
where: and(
|
||||||
|
eq(notifications.dockerCleanup, true),
|
||||||
|
eq(notifications.adminId, adminId),
|
||||||
|
),
|
||||||
with: {
|
with: {
|
||||||
email: true,
|
email: true,
|
||||||
discord: true,
|
discord: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user