Merge branch 'canary' into kucherenko/canary

This commit is contained in:
Mauricio Siu
2025-01-18 18:29:12 -06:00
335 changed files with 20594 additions and 17450 deletions

View File

@@ -213,6 +213,7 @@ export const deployApplication = async ({
applicationType: "application",
buildLink,
adminId: application.project.adminId,
domains: application.domains
});
} catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error");
@@ -332,6 +333,7 @@ export const deployRemoteApplication = async ({
applicationType: "application",
buildLink,
adminId: application.project.adminId,
domains: application.domains
});
} catch (error) {
// @ts-ignore

View File

@@ -243,6 +243,7 @@ export const deployCompose = async ({
applicationType: "compose",
buildLink,
adminId: compose.project.adminId,
domains: compose.domains,
});
} catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error");
@@ -366,6 +367,7 @@ export const deployRemoteCompose = async ({
applicationType: "compose",
buildLink,
adminId: compose.project.adminId,
domains: compose.domains,
});
} catch (error) {
// @ts-ignore

View File

@@ -120,23 +120,33 @@ export const findMariadbByBackupId = async (backupId: string) => {
return result[0];
};
export const deployMariadb = async (mariadbId: string) => {
export const deployMariadb = async (
mariadbId: string,
onData?: (data: any) => void,
) => {
const mariadb = await findMariadbById(mariadbId);
try {
await updateMariadbById(mariadbId, {
applicationStatus: "running",
});
onData?.("Starting mariadb deployment...");
if (mariadb.serverId) {
await execAsyncRemote(
mariadb.serverId,
`docker pull ${mariadb.dockerImage}`,
onData,
);
} else {
await pullImage(mariadb.dockerImage);
await pullImage(mariadb.dockerImage, onData);
}
await buildMariadb(mariadb);
await updateMariadbById(mariadbId, {
applicationStatus: "done",
});
onData?.("Deployment completed successfully!");
} catch (error) {
onData?.(`Error: ${error}`);
await updateMariadbById(mariadbId, {
applicationStatus: "error",
});

View File

@@ -112,20 +112,34 @@ export const removeMongoById = async (mongoId: string) => {
return result[0];
};
export const deployMongo = async (mongoId: string) => {
export const deployMongo = async (
mongoId: string,
onData?: (data: any) => void,
) => {
const mongo = await findMongoById(mongoId);
try {
await updateMongoById(mongoId, {
applicationStatus: "running",
});
onData?.("Starting mongo deployment...");
if (mongo.serverId) {
await execAsyncRemote(mongo.serverId, `docker pull ${mongo.dockerImage}`);
await execAsyncRemote(
mongo.serverId,
`docker pull ${mongo.dockerImage}`,
onData,
);
} else {
await pullImage(mongo.dockerImage);
await pullImage(mongo.dockerImage, onData);
}
await buildMongo(mongo);
await updateMongoById(mongoId, {
applicationStatus: "done",
});
onData?.("Deployment completed successfully!");
} catch (error) {
onData?.(`Error: ${error}`);
await updateMongoById(mongoId, {
applicationStatus: "error",
});

View File

@@ -1,6 +1,6 @@
import { db } from "@dokploy/server/db";
import { type apiCreateMySql, backups, mysql } from "@dokploy/server/db/schema";
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
import { buildAppName } from "@dokploy/server/db/schema";
import { generatePassword } from "@dokploy/server/templates/utils";
import { buildMysql } from "@dokploy/server/utils/databases/mysql";
import { pullImage } from "@dokploy/server/utils/docker/utils";
@@ -116,20 +116,33 @@ export const removeMySqlById = async (mysqlId: string) => {
return result[0];
};
export const deployMySql = async (mysqlId: string) => {
export const deployMySql = async (
mysqlId: string,
onData?: (data: any) => void,
) => {
const mysql = await findMySqlById(mysqlId);
try {
await updateMySqlById(mysqlId, {
applicationStatus: "running",
});
onData?.("Starting mysql deployment...");
if (mysql.serverId) {
await execAsyncRemote(mysql.serverId, `docker pull ${mysql.dockerImage}`);
await execAsyncRemote(
mysql.serverId,
`docker pull ${mysql.dockerImage}`,
onData,
);
} else {
await pullImage(mysql.dockerImage);
await pullImage(mysql.dockerImage, onData);
}
await buildMysql(mysql);
await updateMySqlById(mysqlId, {
applicationStatus: "done",
});
onData?.("Deployment completed successfully!");
} catch (error) {
onData?.(`Error: ${error}`);
await updateMySqlById(mysqlId, {
applicationStatus: "error",
});

View File

@@ -2,14 +2,17 @@ import { db } from "@dokploy/server/db";
import {
type apiCreateDiscord,
type apiCreateEmail,
type apiCreateGotify,
type apiCreateSlack,
type apiCreateTelegram,
type apiUpdateDiscord,
type apiUpdateEmail,
type apiUpdateGotify,
type apiUpdateSlack,
type apiUpdateTelegram,
discord,
email,
gotify,
notifications,
slack,
telegram,
@@ -379,6 +382,96 @@ export const updateEmailNotification = async (
});
};
export const createGotifyNotification = async (
input: typeof apiCreateGotify._type,
adminId: string,
) => {
await db.transaction(async (tx) => {
const newGotify = await tx
.insert(gotify)
.values({
serverUrl: input.serverUrl,
appToken: input.appToken,
priority: input.priority,
decoration: input.decoration,
})
.returning()
.then((value) => value[0]);
if (!newGotify) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Error input: Inserting gotify",
});
}
const newDestination = await tx
.insert(notifications)
.values({
gotifyId: newGotify.gotifyId,
name: input.name,
appDeploy: input.appDeploy,
appBuildError: input.appBuildError,
databaseBackup: input.databaseBackup,
dokployRestart: input.dokployRestart,
dockerCleanup: input.dockerCleanup,
notificationType: "gotify",
adminId: adminId,
})
.returning()
.then((value) => value[0]);
if (!newDestination) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Error input: Inserting notification",
});
}
return newDestination;
});
};
export const updateGotifyNotification = async (
input: typeof apiUpdateGotify._type,
) => {
await db.transaction(async (tx) => {
const newDestination = await tx
.update(notifications)
.set({
name: input.name,
appDeploy: input.appDeploy,
appBuildError: input.appBuildError,
databaseBackup: input.databaseBackup,
dokployRestart: input.dokployRestart,
dockerCleanup: input.dockerCleanup,
adminId: input.adminId,
})
.where(eq(notifications.notificationId, input.notificationId))
.returning()
.then((value) => value[0]);
if (!newDestination) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Error Updating notification",
});
}
await tx
.update(gotify)
.set({
serverUrl: input.serverUrl,
appToken: input.appToken,
priority: input.priority,
decoration: input.decoration,
})
.where(eq(gotify.gotifyId, input.gotifyId));
return newDestination;
});
};
export const findNotificationById = async (notificationId: string) => {
const notification = await db.query.notifications.findFirst({
where: eq(notifications.notificationId, notificationId),
@@ -387,6 +480,7 @@ export const findNotificationById = async (notificationId: string) => {
telegram: true,
discord: true,
email: true,
gotify: true,
},
});
if (!notification) {

View File

@@ -115,24 +115,37 @@ export const removePostgresById = async (postgresId: string) => {
return result[0];
};
export const deployPostgres = async (postgresId: string) => {
export const deployPostgres = async (
postgresId: string,
onData?: (data: any) => void,
) => {
const postgres = await findPostgresById(postgresId);
try {
const promises = [];
await updatePostgresById(postgresId, {
applicationStatus: "running",
});
onData?.("Starting postgres deployment...");
if (postgres.serverId) {
const result = await execAsyncRemote(
await execAsyncRemote(
postgres.serverId,
`docker pull ${postgres.dockerImage}`,
onData,
);
} else {
await pullImage(postgres.dockerImage);
await pullImage(postgres.dockerImage, onData);
}
await buildPostgres(postgres);
await updatePostgresById(postgresId, {
applicationStatus: "done",
});
onData?.("Deployment completed successfully!");
} catch (error) {
onData?.(`Error: ${error}`);
await updatePostgresById(postgresId, {
applicationStatus: "error",
});

View File

@@ -89,20 +89,34 @@ export const removeRedisById = async (redisId: string) => {
return result[0];
};
export const deployRedis = async (redisId: string) => {
export const deployRedis = async (
redisId: string,
onData?: (data: any) => void,
) => {
const redis = await findRedisById(redisId);
try {
await updateRedisById(redisId, {
applicationStatus: "running",
});
onData?.("Starting redis deployment...");
if (redis.serverId) {
await execAsyncRemote(redis.serverId, `docker pull ${redis.dockerImage}`);
await execAsyncRemote(
redis.serverId,
`docker pull ${redis.dockerImage}`,
onData,
);
} else {
await pullImage(redis.dockerImage);
await pullImage(redis.dockerImage, onData);
}
await buildRedis(redis);
await updateRedisById(redisId, {
applicationStatus: "done",
});
onData?.("Deployment completed successfully!");
} catch (error) {
onData?.(`Error: ${error}`);
await updateRedisById(redisId, {
applicationStatus: "error",
});

View File

@@ -54,7 +54,7 @@ export const addNewProject = async (authId: string, projectId: string) => {
await db
.update(users)
.set({
accesedProjects: [...user.accesedProjects, projectId],
accessedProjects: [...user.accessedProjects, projectId],
})
.where(eq(users.authId, authId));
};
@@ -64,7 +64,7 @@ export const addNewService = async (authId: string, serviceId: string) => {
await db
.update(users)
.set({
accesedServices: [...user.accesedServices, serviceId],
accessedServices: [...user.accessedServices, serviceId],
})
.where(eq(users.authId, authId));
};
@@ -73,8 +73,8 @@ export const canPerformCreationService = async (
userId: string,
projectId: string,
) => {
const { accesedProjects, canCreateServices } = await findUserByAuthId(userId);
const haveAccessToProject = accesedProjects.includes(projectId);
const { accessedProjects, canCreateServices } = await findUserByAuthId(userId);
const haveAccessToProject = accessedProjects.includes(projectId);
if (canCreateServices && haveAccessToProject) {
return true;
@@ -87,8 +87,8 @@ export const canPerformAccessService = async (
userId: string,
serviceId: string,
) => {
const { accesedServices } = await findUserByAuthId(userId);
const haveAccessToService = accesedServices.includes(serviceId);
const { accessedServices } = await findUserByAuthId(userId);
const haveAccessToService = accessedServices.includes(serviceId);
if (haveAccessToService) {
return true;
@@ -101,8 +101,8 @@ export const canPeformDeleteService = async (
authId: string,
serviceId: string,
) => {
const { accesedServices, canDeleteServices } = await findUserByAuthId(authId);
const haveAccessToService = accesedServices.includes(serviceId);
const { accessedServices, canDeleteServices } = await findUserByAuthId(authId);
const haveAccessToService = accessedServices.includes(serviceId);
if (canDeleteServices && haveAccessToService) {
return true;
@@ -135,9 +135,9 @@ export const canPerformAccessProject = async (
authId: string,
projectId: string,
) => {
const { accesedProjects } = await findUserByAuthId(authId);
const { accessedProjects } = await findUserByAuthId(authId);
const haveAccessToProject = accesedProjects.includes(projectId);
const haveAccessToProject = accessedProjects.includes(projectId);
if (haveAccessToProject) {
return true;