mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-26 17:45:49 +02:00
Merge branch 'canary' into bitbucket-api-token
This commit is contained in:
@@ -89,7 +89,7 @@ export const getMariadbBackupCommand = (
|
||||
databaseUser: string,
|
||||
databasePassword: string,
|
||||
) => {
|
||||
return `docker exec -i $CONTAINER_ID bash -c "set -o pipefail; mariadb-dump --user='${databaseUser}' --password='${databasePassword}' --databases ${database} | gzip"`;
|
||||
return `docker exec -i $CONTAINER_ID bash -c "set -o pipefail; mariadb-dump --user='${databaseUser}' --password='${databasePassword}' --single-transaction --quick --databases ${database} | gzip"`;
|
||||
};
|
||||
|
||||
export const getMysqlBackupCommand = (
|
||||
|
||||
@@ -220,8 +220,8 @@ const getImageName = (application: ApplicationNested) => {
|
||||
if (registry) {
|
||||
const { registryUrl, imagePrefix, username } = registry;
|
||||
const registryTag = imagePrefix
|
||||
? `${registryUrl}/${imagePrefix}/${imageName}`
|
||||
: `${registryUrl}/${username}/${imageName}`;
|
||||
? `${registryUrl ? `${registryUrl}/` : ""}${imagePrefix}/${imageName}`
|
||||
: `${registryUrl ? `${registryUrl}/` : ""}${username}/${imageName}`;
|
||||
return registryTag;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ export const uploadImage = async (
|
||||
// For ghcr.io: ghcr.io/username/image:tag
|
||||
// For docker.io: docker.io/username/image:tag
|
||||
const registryTag = imagePrefix
|
||||
? `${registryUrl}/${imagePrefix}/${imageName}`
|
||||
: `${registryUrl}/${username}/${imageName}`;
|
||||
? `${registryUrl ? `${registryUrl}/` : ""}${imagePrefix}/${imageName}`
|
||||
: `${registryUrl ? `${registryUrl}/` : ""}${username}/${imageName}`;
|
||||
|
||||
try {
|
||||
writeStream.write(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { findComposeById } from "@dokploy/server/services/compose";
|
||||
import { dump } from "js-yaml";
|
||||
import { stringify } from "yaml";
|
||||
import { addAppNameToAllServiceNames } from "./collision/root-network";
|
||||
import { generateRandomHash } from "./compose";
|
||||
import { addSuffixToAllVolumes } from "./compose/volume";
|
||||
@@ -59,7 +59,7 @@ export const randomizeIsolatedDeploymentComposeFile = async (
|
||||
)
|
||||
: composeData;
|
||||
|
||||
return dump(newComposeFile);
|
||||
return stringify(newComposeFile);
|
||||
};
|
||||
|
||||
export const randomizeDeployableSpecificationFile = (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import crypto from "node:crypto";
|
||||
import { findComposeById } from "@dokploy/server/services/compose";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { parse, stringify } from "yaml";
|
||||
import { addSuffixToAllConfigs } from "./compose/configs";
|
||||
import { addSuffixToAllNetworks } from "./compose/network";
|
||||
import { addSuffixToAllSecrets } from "./compose/secrets";
|
||||
@@ -18,13 +18,13 @@ export const randomizeComposeFile = async (
|
||||
) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
const composeFile = compose.composeFile;
|
||||
const composeData = load(composeFile) as ComposeSpecification;
|
||||
const composeData = parse(composeFile) as ComposeSpecification;
|
||||
|
||||
const randomSuffix = suffix || generateRandomHash();
|
||||
|
||||
const newComposeFile = addSuffixToAllProperties(composeData, randomSuffix);
|
||||
|
||||
return dump(newComposeFile);
|
||||
return stringify(newComposeFile);
|
||||
};
|
||||
|
||||
export const randomizeSpecificationFile = (
|
||||
|
||||
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
||||
import { paths } from "@dokploy/server/constants";
|
||||
import type { Compose } from "@dokploy/server/services/compose";
|
||||
import type { Domain } from "@dokploy/server/services/domain";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { parse, stringify } from "yaml";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
import {
|
||||
cloneRawBitbucketRepository,
|
||||
@@ -92,7 +92,7 @@ export const loadDockerCompose = async (
|
||||
|
||||
if (existsSync(path)) {
|
||||
const yamlStr = readFileSync(path, "utf8");
|
||||
const parsedConfig = load(yamlStr) as ComposeSpecification;
|
||||
const parsedConfig = parse(yamlStr) as ComposeSpecification;
|
||||
return parsedConfig;
|
||||
}
|
||||
return null;
|
||||
@@ -115,7 +115,7 @@ export const loadDockerComposeRemote = async (
|
||||
return null;
|
||||
}
|
||||
if (!stdout) return null;
|
||||
const parsedConfig = load(stdout) as ComposeSpecification;
|
||||
const parsedConfig = parse(stdout) as ComposeSpecification;
|
||||
return parsedConfig;
|
||||
} catch {
|
||||
return null;
|
||||
@@ -141,7 +141,7 @@ export const writeDomainsToCompose = async (
|
||||
const composeConverted = await addDomainToCompose(compose, domains);
|
||||
|
||||
const path = getComposePath(compose);
|
||||
const composeString = dump(composeConverted, { lineWidth: 1000 });
|
||||
const composeString = stringify(composeConverted, { lineWidth: 1000 });
|
||||
try {
|
||||
await writeFile(path, composeString, "utf8");
|
||||
} catch (error) {
|
||||
@@ -169,7 +169,7 @@ exit 1;
|
||||
`;
|
||||
}
|
||||
if (compose.serverId) {
|
||||
const composeString = dump(composeConverted, { lineWidth: 1000 });
|
||||
const composeString = stringify(composeConverted, { lineWidth: 1000 });
|
||||
const encodedContent = encodeBase64(composeString);
|
||||
return `echo "${encodedContent}" | base64 -d > "${path}";`;
|
||||
}
|
||||
@@ -251,11 +251,15 @@ export const addDomainToCompose = async (
|
||||
}
|
||||
labels.unshift(...httpLabels);
|
||||
if (!compose.isolatedDeployment) {
|
||||
if (!labels.includes("traefik.docker.network=dokploy-network")) {
|
||||
labels.unshift("traefik.docker.network=dokploy-network");
|
||||
}
|
||||
if (!labels.includes("traefik.swarm.network=dokploy-network")) {
|
||||
labels.unshift("traefik.swarm.network=dokploy-network");
|
||||
if (compose.composeType === "docker-compose") {
|
||||
if (!labels.includes("traefik.docker.network=dokploy-network")) {
|
||||
labels.unshift("traefik.docker.network=dokploy-network");
|
||||
}
|
||||
} else {
|
||||
// Stack Case
|
||||
if (!labels.includes("traefik.swarm.network=dokploy-network")) {
|
||||
labels.unshift("traefik.swarm.network=dokploy-network");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,7 +287,7 @@ export const writeComposeFile = async (
|
||||
const path = getComposePath(compose);
|
||||
|
||||
try {
|
||||
const composeFile = dump(composeSpec, {
|
||||
const composeFile = stringify(composeSpec, {
|
||||
lineWidth: 1000,
|
||||
});
|
||||
fs.writeFileSync(path, composeFile, "utf8");
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
sendGotifyNotification,
|
||||
sendNtfyNotification,
|
||||
sendSlackNotification,
|
||||
sendTelegramNotification,
|
||||
} from "./utils";
|
||||
@@ -42,11 +43,12 @@ export const sendBuildErrorNotifications = async ({
|
||||
telegram: true,
|
||||
slack: true,
|
||||
gotify: true,
|
||||
ntfy: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const notification of notificationList) {
|
||||
const { email, discord, telegram, slack, gotify } = notification;
|
||||
const { email, discord, telegram, slack, gotify, ntfy } = notification;
|
||||
if (email) {
|
||||
const template = await renderAsync(
|
||||
BuildFailedEmail({
|
||||
@@ -132,6 +134,20 @@ export const sendBuildErrorNotifications = async ({
|
||||
);
|
||||
}
|
||||
|
||||
if (ntfy) {
|
||||
await sendNtfyNotification(
|
||||
ntfy,
|
||||
"Build Failed",
|
||||
"warning",
|
||||
`view, Build details, ${buildLink}, clear=true;`,
|
||||
`🛠️Project: ${projectName}\n` +
|
||||
`⚙️Application: ${applicationName}\n` +
|
||||
`❔Type: ${applicationType}\n` +
|
||||
`🕒Date: ${date.toLocaleString()}\n` +
|
||||
`⚠️Error:\n${errorMessage}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (telegram) {
|
||||
const inlineButton = [
|
||||
[
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
sendGotifyNotification,
|
||||
sendNtfyNotification,
|
||||
sendSlackNotification,
|
||||
sendTelegramNotification,
|
||||
} from "./utils";
|
||||
@@ -43,11 +44,12 @@ export const sendBuildSuccessNotifications = async ({
|
||||
telegram: true,
|
||||
slack: true,
|
||||
gotify: true,
|
||||
ntfy: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const notification of notificationList) {
|
||||
const { email, discord, telegram, slack, gotify } = notification;
|
||||
const { email, discord, telegram, slack, gotify, ntfy } = notification;
|
||||
|
||||
if (email) {
|
||||
const template = await renderAsync(
|
||||
@@ -126,6 +128,19 @@ export const sendBuildSuccessNotifications = async ({
|
||||
);
|
||||
}
|
||||
|
||||
if (ntfy) {
|
||||
await sendNtfyNotification(
|
||||
ntfy,
|
||||
"Build Success",
|
||||
"white_check_mark",
|
||||
`view, Build details, ${buildLink}, clear=true;`,
|
||||
`🛠Project: ${projectName}\n` +
|
||||
`⚙️Application: ${applicationName}\n` +
|
||||
`❔Type: ${applicationType}\n` +
|
||||
`🕒Date: ${date.toLocaleString()}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (telegram) {
|
||||
const chunkArray = <T>(array: T[], chunkSize: number): T[][] =>
|
||||
Array.from({ length: Math.ceil(array.length / chunkSize) }, (_, i) =>
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
sendGotifyNotification,
|
||||
sendNtfyNotification,
|
||||
sendSlackNotification,
|
||||
sendTelegramNotification,
|
||||
} from "./utils";
|
||||
@@ -42,11 +43,12 @@ export const sendDatabaseBackupNotifications = async ({
|
||||
telegram: true,
|
||||
slack: true,
|
||||
gotify: true,
|
||||
ntfy: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const notification of notificationList) {
|
||||
const { email, discord, telegram, slack, gotify } = notification;
|
||||
const { email, discord, telegram, slack, gotify, ntfy } = notification;
|
||||
|
||||
if (email) {
|
||||
const template = await renderAsync(
|
||||
@@ -149,6 +151,21 @@ export const sendDatabaseBackupNotifications = async ({
|
||||
);
|
||||
}
|
||||
|
||||
if (ntfy) {
|
||||
await sendNtfyNotification(
|
||||
ntfy,
|
||||
`Database Backup ${type === "success" ? "Successful" : "Failed"}`,
|
||||
`${type === "success" ? "white_check_mark" : "x"}`,
|
||||
"",
|
||||
`🛠Project: ${projectName}\n` +
|
||||
`⚙️Application: ${applicationName}\n` +
|
||||
`❔Type: ${databaseType}\n` +
|
||||
`📂Database Name: ${databaseName}` +
|
||||
`🕒Date: ${date.toLocaleString()}\n` +
|
||||
`${type === "error" && errorMessage ? `❌Error:\n${errorMessage}` : ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (telegram) {
|
||||
const isError = type === "error" && errorMessage;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
sendGotifyNotification,
|
||||
sendNtfyNotification,
|
||||
sendSlackNotification,
|
||||
sendTelegramNotification,
|
||||
} from "./utils";
|
||||
@@ -29,11 +30,12 @@ export const sendDockerCleanupNotifications = async (
|
||||
telegram: true,
|
||||
slack: true,
|
||||
gotify: true,
|
||||
ntfy: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const notification of notificationList) {
|
||||
const { email, discord, telegram, slack, gotify } = notification;
|
||||
const { email, discord, telegram, slack, gotify, ntfy } = notification;
|
||||
|
||||
if (email) {
|
||||
const template = await renderAsync(
|
||||
@@ -93,6 +95,16 @@ export const sendDockerCleanupNotifications = async (
|
||||
);
|
||||
}
|
||||
|
||||
if (ntfy) {
|
||||
await sendNtfyNotification(
|
||||
ntfy,
|
||||
"Docker Cleanup",
|
||||
"white_check_mark",
|
||||
"",
|
||||
`🕒Date: ${date.toLocaleString()}\n` + `📜Message:\n${message}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (telegram) {
|
||||
await sendTelegramNotification(
|
||||
telegram,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
sendGotifyNotification,
|
||||
sendNtfyNotification,
|
||||
sendSlackNotification,
|
||||
sendTelegramNotification,
|
||||
} from "./utils";
|
||||
@@ -23,11 +24,12 @@ export const sendDokployRestartNotifications = async () => {
|
||||
telegram: true,
|
||||
slack: true,
|
||||
gotify: true,
|
||||
ntfy: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const notification of notificationList) {
|
||||
const { email, discord, telegram, slack, gotify } = notification;
|
||||
const { email, discord, telegram, slack, gotify, ntfy } = notification;
|
||||
|
||||
if (email) {
|
||||
const template = await renderAsync(
|
||||
@@ -85,6 +87,20 @@ export const sendDokployRestartNotifications = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (ntfy) {
|
||||
try {
|
||||
await sendNtfyNotification(
|
||||
ntfy,
|
||||
"Dokploy Server Restarted",
|
||||
"white_check_mark",
|
||||
"",
|
||||
`🕒Date: ${date.toLocaleString()}`,
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (telegram) {
|
||||
try {
|
||||
await sendTelegramNotification(
|
||||
|
||||
@@ -2,6 +2,7 @@ import type {
|
||||
discord,
|
||||
email,
|
||||
gotify,
|
||||
ntfy,
|
||||
slack,
|
||||
telegram,
|
||||
} from "@dokploy/server/db/schema";
|
||||
@@ -126,3 +127,27 @@ export const sendGotifyNotification = async (
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const sendNtfyNotification = async (
|
||||
connection: typeof ntfy.$inferInsert,
|
||||
title: string,
|
||||
tags: string,
|
||||
actions: string,
|
||||
message: string,
|
||||
) => {
|
||||
const response = await fetch(`${connection.serverUrl}/${connection.topic}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${connection.accessToken}`,
|
||||
"X-Priority": connection.priority?.toString() || "3",
|
||||
"X-Title": title,
|
||||
"X-Tags": tags,
|
||||
"X-Actions": actions,
|
||||
},
|
||||
body: message,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to send ntfy notification: ${response.statusText}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -171,7 +171,7 @@ export const cloneGithubRepository = async ({
|
||||
const cloneUrl = `https://oauth2:${token}@${repoclone}`;
|
||||
|
||||
try {
|
||||
writeStream.write(`\nClonning Repo ${repoclone} to ${outputPath}: ✅\n`);
|
||||
writeStream.write(`\nCloning Repo ${repoclone} to ${outputPath}: ✅\n`);
|
||||
const cloneArgs = [
|
||||
"clone",
|
||||
"--branch",
|
||||
|
||||
@@ -401,7 +401,7 @@ export const cloneRawGitlabRepositoryRemote = async (compose: Compose) => {
|
||||
const {
|
||||
appName,
|
||||
gitlabPathNamespace,
|
||||
branch,
|
||||
gitlabBranch,
|
||||
gitlabId,
|
||||
serverId,
|
||||
enableSubmodules,
|
||||
@@ -429,7 +429,7 @@ export const cloneRawGitlabRepositoryRemote = async (compose: Compose) => {
|
||||
try {
|
||||
const command = `
|
||||
rm -rf ${outputPath};
|
||||
git clone --branch ${branch} --depth 1 ${enableSubmodules ? "--recurse-submodules" : ""} ${cloneUrl} ${outputPath}
|
||||
git clone --branch ${gitlabBranch} --depth 1 ${enableSubmodules ? "--recurse-submodules" : ""} ${cloneUrl} ${outputPath}
|
||||
`;
|
||||
await execAsyncRemote(serverId, command);
|
||||
} catch (error) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "node:path";
|
||||
import { createInterface } from "node:readline";
|
||||
import { paths } from "@dokploy/server/constants";
|
||||
import type { Domain } from "@dokploy/server/services/domain";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { parse, stringify } from "yaml";
|
||||
import { encodeBase64 } from "../docker/utils";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
import type { FileConfig, HttpLoadBalancerService } from "./file-types";
|
||||
@@ -40,7 +40,7 @@ export const createTraefikConfig = (appName: string) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
const yamlStr = dump(config);
|
||||
const yamlStr = stringify(config);
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
fs.mkdirSync(DYNAMIC_TRAEFIK_PATH, { recursive: true });
|
||||
writeFileSync(
|
||||
@@ -87,7 +87,7 @@ export const loadOrCreateConfig = (appName: string): FileConfig => {
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
if (fs.existsSync(configPath)) {
|
||||
const yamlStr = fs.readFileSync(configPath, "utf8");
|
||||
const parsedConfig = (load(yamlStr) as FileConfig) || {
|
||||
const parsedConfig = (parse(yamlStr) as FileConfig) || {
|
||||
http: { routers: {}, services: {} },
|
||||
};
|
||||
return parsedConfig;
|
||||
@@ -107,7 +107,7 @@ export const loadOrCreateConfigRemote = async (
|
||||
|
||||
if (!stdout) return fileConfig;
|
||||
|
||||
const parsedConfig = (load(stdout) as FileConfig) || {
|
||||
const parsedConfig = (parse(stdout) as FileConfig) || {
|
||||
http: { routers: {}, services: {} },
|
||||
};
|
||||
return parsedConfig;
|
||||
@@ -248,7 +248,7 @@ export const writeTraefikConfig = (
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
const yamlStr = dump(traefikConfig);
|
||||
const yamlStr = stringify(traefikConfig);
|
||||
fs.writeFileSync(configPath, yamlStr, "utf8");
|
||||
} catch (e) {
|
||||
console.error("Error saving the YAML config file:", e);
|
||||
@@ -263,7 +263,7 @@ export const writeTraefikConfigRemote = async (
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
const yamlStr = dump(traefikConfig);
|
||||
const yamlStr = stringify(traefikConfig);
|
||||
await execAsyncRemote(serverId, `echo '${yamlStr}' > ${configPath}`);
|
||||
} catch (e) {
|
||||
console.error("Error saving the YAML config file:", e);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { paths } from "@dokploy/server/constants";
|
||||
import type { Domain } from "@dokploy/server/services/domain";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { parse, stringify } from "yaml";
|
||||
import type { ApplicationNested } from "../builders";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
import { writeTraefikConfigRemote } from "./application";
|
||||
@@ -76,7 +76,7 @@ export const loadMiddlewares = <T>() => {
|
||||
throw new Error(`File not found: ${configPath}`);
|
||||
}
|
||||
const yamlStr = readFileSync(configPath, "utf8");
|
||||
const config = load(yamlStr) as T;
|
||||
const config = parse(yamlStr) as T;
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -94,7 +94,7 @@ export const loadRemoteMiddlewares = async (serverId: string) => {
|
||||
console.error(`Error: ${stderr}`);
|
||||
throw new Error(`File not found: ${configPath}`);
|
||||
}
|
||||
const config = load(stdout) as FileConfig;
|
||||
const config = parse(stdout) as FileConfig;
|
||||
return config;
|
||||
} catch (_) {
|
||||
throw new Error(`File not found: ${configPath}`);
|
||||
@@ -103,7 +103,7 @@ export const loadRemoteMiddlewares = async (serverId: string) => {
|
||||
export const writeMiddleware = <T>(config: T) => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = join(DYNAMIC_TRAEFIK_PATH, "middlewares.yml");
|
||||
const newYamlContent = dump(config);
|
||||
const newYamlContent = stringify(config);
|
||||
writeFileSync(configPath, newYamlContent, "utf8");
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { paths } from "@dokploy/server/constants";
|
||||
import type { User } from "@dokploy/server/services/user";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { parse, stringify } from "yaml";
|
||||
import {
|
||||
loadOrCreateConfig,
|
||||
removeTraefikConfig,
|
||||
@@ -79,13 +79,13 @@ export const updateLetsEncryptEmail = (newEmail: string | null) => {
|
||||
const { MAIN_TRAEFIK_PATH } = paths();
|
||||
const configPath = join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
||||
const configContent = readFileSync(configPath, "utf8");
|
||||
const config = load(configContent) as MainTraefikConfig;
|
||||
const config = parse(configContent) as MainTraefikConfig;
|
||||
if (config?.certificatesResolvers?.letsencrypt?.acme) {
|
||||
config.certificatesResolvers.letsencrypt.acme.email = newEmail;
|
||||
} else {
|
||||
throw new Error("Invalid Let's Encrypt configuration structure.");
|
||||
}
|
||||
const newYamlContent = dump(config);
|
||||
const newYamlContent = stringify(config);
|
||||
writeFileSync(configPath, newYamlContent, "utf8");
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { findVolumeBackupById } from "@dokploy/server/services/volume-backups";
|
||||
import { scheduledJobs, scheduleJob } from "node-schedule";
|
||||
import path from "node:path";
|
||||
import { paths } from "@dokploy/server/constants";
|
||||
import {
|
||||
createDeploymentVolumeBackup,
|
||||
updateDeploymentStatus,
|
||||
} from "@dokploy/server/services/deployment";
|
||||
import { findVolumeBackupById } from "@dokploy/server/services/volume-backups";
|
||||
import {
|
||||
execAsync,
|
||||
execAsyncRemote,
|
||||
} from "@dokploy/server/utils/process/execAsync";
|
||||
import { backupVolume } from "./backup";
|
||||
import { scheduledJobs, scheduleJob } from "node-schedule";
|
||||
import { getS3Credentials, normalizeS3Path } from "../backups/utils";
|
||||
import { backupVolume } from "./backup";
|
||||
|
||||
export const scheduleVolumeBackup = async (volumeBackupId: string) => {
|
||||
const volumeBackup = await findVolumeBackupById(volumeBackupId);
|
||||
@@ -76,7 +78,20 @@ export const runVolumeBackup = async (volumeBackupId: string) => {
|
||||
|
||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||
} catch (error) {
|
||||
const { VOLUME_BACKUPS_PATH } = paths(!!serverId);
|
||||
const volumeBackupPath = path.join(
|
||||
VOLUME_BACKUPS_PATH,
|
||||
volumeBackup.appName,
|
||||
);
|
||||
// delete all the .tar files
|
||||
const command = `rm -rf ${volumeBackupPath}/*.tar`;
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
} else {
|
||||
await execAsync(command);
|
||||
}
|
||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user