mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-15 10:55:23 +02:00
refactor(multi-server): adapt paths on server and in dokploy ui
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { findAdmin, updateAdmin } from "@/server/api/services/admin";
|
||||
import { DYNAMIC_TRAEFIK_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { type RotatingFileStream, createStream } from "rotating-file-stream";
|
||||
import { execAsync } from "../process/execAsync";
|
||||
|
||||
@@ -39,6 +39,7 @@ class LogRotationManager {
|
||||
}
|
||||
|
||||
private async activateStream(): Promise<void> {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
if (this.stream) {
|
||||
await this.deactivateStream();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { COMPOSE_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
import boxen from "boxen";
|
||||
import {
|
||||
@@ -24,6 +24,7 @@ export const buildCompose = async (compose: ComposeNested, logPath: string) => {
|
||||
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||
const { sourceType, appName, mounts, composeType, domains } = compose;
|
||||
try {
|
||||
const { COMPOSE_PATH } = paths();
|
||||
const command = createCommand(compose);
|
||||
await writeDomainsToCompose(compose, domains);
|
||||
createEnvFile(compose);
|
||||
@@ -73,6 +74,7 @@ export const getBuildComposeCommand = async (
|
||||
compose: ComposeNested,
|
||||
logPath: string,
|
||||
) => {
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
const { sourceType, appName, mounts, composeType, domains, composePath } =
|
||||
compose;
|
||||
const command = createCommand(compose);
|
||||
@@ -158,6 +160,7 @@ export const createCommand = (compose: ComposeNested) => {
|
||||
};
|
||||
|
||||
const createEnvFile = (compose: ComposeNested) => {
|
||||
const { COMPOSE_PATH } = paths();
|
||||
const { env, composePath, appName } = compose;
|
||||
const composeFilePath =
|
||||
join(COMPOSE_PATH, appName, "code", composePath) ||
|
||||
@@ -182,6 +185,7 @@ const createEnvFile = (compose: ComposeNested) => {
|
||||
};
|
||||
|
||||
export const getCreateEnvFileCommand = (compose: ComposeNested) => {
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
const { env, composePath, appName } = compose;
|
||||
const composeFilePath =
|
||||
join(COMPOSE_PATH, appName, "code", composePath) ||
|
||||
|
||||
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
|
||||
import path, { join } from "node:path";
|
||||
import type { Application } from "@/server/api/services/application";
|
||||
import { findServerById } from "@/server/api/services/server";
|
||||
import { APPLICATIONS_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import AdmZip from "adm-zip";
|
||||
import { Client, type SFTPWrapper } from "ssh2";
|
||||
import {
|
||||
@@ -17,6 +17,7 @@ export const unzipDrop = async (zipFile: File, application: Application) => {
|
||||
|
||||
try {
|
||||
const { appName } = application;
|
||||
const { APPLICATIONS_PATH } = paths(!!application.serverId);
|
||||
const outputPath = join(APPLICATIONS_PATH, appName, "code");
|
||||
if (application.serverId) {
|
||||
await recreateDirectoryRemote(outputPath, application.serverId);
|
||||
|
||||
@@ -120,7 +120,7 @@ export const mechanizeDockerContainer = async (
|
||||
} = generateConfigContainer(application);
|
||||
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const filesMount = generateFileMounts(appName, mounts);
|
||||
const filesMount = generateFileMounts(appName, application);
|
||||
const envVariables = prepareEnvironmentVariables(env);
|
||||
|
||||
const image = getImageName(application);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import type { Mariadb } from "@/server/api/services/mariadb";
|
||||
import type { Mount } from "@/server/api/services/mount";
|
||||
import type { CreateServiceOptions } from "dockerode";
|
||||
import {
|
||||
calculateResources,
|
||||
@@ -9,11 +7,10 @@ import {
|
||||
prepareEnvironmentVariables,
|
||||
} from "../docker/utils";
|
||||
import { getRemoteDocker } from "../servers/remote-docker";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
|
||||
type MariadbWithMounts = Mariadb & {
|
||||
mounts: Mount[];
|
||||
};
|
||||
export const buildMariadb = async (mariadb: MariadbWithMounts) => {
|
||||
export type MariadbNested = InferResultType<"mariadb", { mounts: true }>;
|
||||
export const buildMariadb = async (mariadb: MariadbNested) => {
|
||||
const {
|
||||
appName,
|
||||
env,
|
||||
@@ -43,7 +40,7 @@ export const buildMariadb = async (mariadb: MariadbWithMounts) => {
|
||||
const envVariables = prepareEnvironmentVariables(defaultMariadbEnv);
|
||||
const volumesMount = generateVolumeMounts(mounts);
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const filesMount = generateFileMounts(appName, mounts);
|
||||
const filesMount = generateFileMounts(appName, mariadb);
|
||||
|
||||
const docker = await getRemoteDocker(mariadb.serverId);
|
||||
|
||||
|
||||
@@ -9,12 +9,11 @@ import {
|
||||
prepareEnvironmentVariables,
|
||||
} from "../docker/utils";
|
||||
import { getRemoteDocker } from "../servers/remote-docker";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
|
||||
type MongoWithMounts = Mongo & {
|
||||
mounts: Mount[];
|
||||
};
|
||||
export type MongoNested = InferResultType<"mongo", { mounts: true }>;
|
||||
|
||||
export const buildMongo = async (mongo: MongoWithMounts) => {
|
||||
export const buildMongo = async (mongo: MongoNested) => {
|
||||
const {
|
||||
appName,
|
||||
env,
|
||||
@@ -42,7 +41,7 @@ export const buildMongo = async (mongo: MongoWithMounts) => {
|
||||
const envVariables = prepareEnvironmentVariables(defaultMongoEnv);
|
||||
const volumesMount = generateVolumeMounts(mounts);
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const filesMount = generateFileMounts(appName, mounts);
|
||||
const filesMount = generateFileMounts(appName, mongo);
|
||||
|
||||
const docker = await getRemoteDocker(mongo.serverId);
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import type { Mount } from "@/server/api/services/mount";
|
||||
import type { MySql } from "@/server/api/services/mysql";
|
||||
import { docker } from "@/server/constants";
|
||||
import type { CreateServiceOptions } from "dockerode";
|
||||
import {
|
||||
calculateResources,
|
||||
@@ -10,12 +7,11 @@ import {
|
||||
prepareEnvironmentVariables,
|
||||
} from "../docker/utils";
|
||||
import { getRemoteDocker } from "../servers/remote-docker";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
|
||||
type MysqlWithMounts = MySql & {
|
||||
mounts: Mount[];
|
||||
};
|
||||
export type MysqlNested = InferResultType<"mysql", { mounts: true }>;
|
||||
|
||||
export const buildMysql = async (mysql: MysqlWithMounts) => {
|
||||
export const buildMysql = async (mysql: MysqlNested) => {
|
||||
const {
|
||||
appName,
|
||||
env,
|
||||
@@ -50,7 +46,7 @@ export const buildMysql = async (mysql: MysqlWithMounts) => {
|
||||
const envVariables = prepareEnvironmentVariables(defaultMysqlEnv);
|
||||
const volumesMount = generateVolumeMounts(mounts);
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const filesMount = generateFileMounts(appName, mounts);
|
||||
const filesMount = generateFileMounts(appName, mysql);
|
||||
|
||||
const docker = await getRemoteDocker(mysql.serverId);
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import type { Mount } from "@/server/api/services/mount";
|
||||
import type { Postgres } from "@/server/api/services/postgres";
|
||||
import type { CreateServiceOptions } from "dockerode";
|
||||
import {
|
||||
calculateResources,
|
||||
@@ -9,12 +7,10 @@ import {
|
||||
prepareEnvironmentVariables,
|
||||
} from "../docker/utils";
|
||||
import { getRemoteDocker } from "../servers/remote-docker";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
|
||||
type PostgresWithMounts = Postgres & {
|
||||
mounts: Mount[];
|
||||
};
|
||||
|
||||
export const buildPostgres = async (postgres: PostgresWithMounts) => {
|
||||
export type PostgresNested = InferResultType<"postgres", { mounts: true }>;
|
||||
export const buildPostgres = async (postgres: PostgresNested) => {
|
||||
const {
|
||||
appName,
|
||||
env,
|
||||
@@ -43,7 +39,7 @@ export const buildPostgres = async (postgres: PostgresWithMounts) => {
|
||||
const envVariables = prepareEnvironmentVariables(defaultPostgresEnv);
|
||||
const volumesMount = generateVolumeMounts(mounts);
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const filesMount = generateFileMounts(appName, mounts);
|
||||
const filesMount = generateFileMounts(appName, postgres);
|
||||
|
||||
const docker = await getRemoteDocker(postgres.serverId);
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import type { Mount } from "@/server/api/services/mount";
|
||||
import type { Redis } from "@/server/api/services/redis";
|
||||
import { docker } from "@/server/constants";
|
||||
import type { CreateServiceOptions } from "dockerode";
|
||||
import {
|
||||
calculateResources,
|
||||
@@ -10,12 +7,10 @@ import {
|
||||
prepareEnvironmentVariables,
|
||||
} from "../docker/utils";
|
||||
import { getRemoteDocker } from "../servers/remote-docker";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
|
||||
type RedisWithMounts = Redis & {
|
||||
mounts: Mount[];
|
||||
};
|
||||
|
||||
export const buildRedis = async (redis: RedisWithMounts) => {
|
||||
export type RedisNested = InferResultType<"redis", { mounts: true }>;
|
||||
export const buildRedis = async (redis: RedisNested) => {
|
||||
const {
|
||||
appName,
|
||||
env,
|
||||
@@ -42,7 +37,7 @@ export const buildRedis = async (redis: RedisWithMounts) => {
|
||||
const envVariables = prepareEnvironmentVariables(defaultRedisEnv);
|
||||
const volumesMount = generateVolumeMounts(mounts);
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const filesMount = generateFileMounts(appName, mounts);
|
||||
const filesMount = generateFileMounts(appName, redis);
|
||||
|
||||
const docker = await getRemoteDocker(redis.serverId);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import type { Compose } from "@/server/api/services/compose";
|
||||
import type { Domain } from "@/server/api/services/domain";
|
||||
import { COMPOSE_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
import {
|
||||
@@ -63,6 +63,7 @@ export const cloneComposeRemote = async (compose: Compose) => {
|
||||
};
|
||||
|
||||
export const getComposePath = (compose: Compose) => {
|
||||
const { COMPOSE_PATH } = paths(!!compose.serverId);
|
||||
const { appName, sourceType, composePath } = compose;
|
||||
let path = "";
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { Readable } from "node:stream";
|
||||
import { APPLICATIONS_PATH, docker } from "@/server/constants";
|
||||
import { docker, paths } from "@/server/constants";
|
||||
import type { ContainerInfo, ResourceRequirements } from "dockerode";
|
||||
import { parse } from "dotenv";
|
||||
import type { ApplicationNested } from "../builders";
|
||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||
import { getRemoteDocker } from "../servers/remote-docker";
|
||||
import type { MongoNested } from "../databases/mongo";
|
||||
import type { MariadbNested } from "../databases/mariadb";
|
||||
import type { MysqlNested } from "../databases/mysql";
|
||||
import type { PostgresNested } from "../databases/postgres";
|
||||
import type { RedisNested } from "../databases/redis";
|
||||
|
||||
interface RegistryAuth {
|
||||
username: string;
|
||||
@@ -378,8 +383,16 @@ export const generateBindMounts = (mounts: ApplicationNested["mounts"]) => {
|
||||
|
||||
export const generateFileMounts = (
|
||||
appName: string,
|
||||
mounts: ApplicationNested["mounts"],
|
||||
service:
|
||||
| ApplicationNested
|
||||
| MongoNested
|
||||
| MariadbNested
|
||||
| MysqlNested
|
||||
| PostgresNested
|
||||
| RedisNested,
|
||||
) => {
|
||||
const { mounts } = service;
|
||||
const { APPLICATIONS_PATH } = paths(!!service.serverId);
|
||||
if (!mounts || mounts.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import fs, { promises as fsPromises } from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { Application } from "@/server/api/services/application";
|
||||
import {
|
||||
APPLICATIONS_PATH,
|
||||
COMPOSE_PATH,
|
||||
MONITORING_PATH,
|
||||
} from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||
|
||||
export const recreateDirectory = async (pathFolder: string): Promise<void> => {
|
||||
@@ -52,6 +48,7 @@ export const removeDirectoryCode = async (
|
||||
appName: string,
|
||||
serverId?: string | null,
|
||||
) => {
|
||||
const { APPLICATIONS_PATH } = paths(!!serverId);
|
||||
const directoryPath = path.join(APPLICATIONS_PATH, appName);
|
||||
const command = `rm -rf ${directoryPath}`;
|
||||
try {
|
||||
@@ -70,6 +67,7 @@ export const removeComposeDirectory = async (
|
||||
appName: string,
|
||||
serverId?: string | null,
|
||||
) => {
|
||||
const { COMPOSE_PATH } = paths(!!serverId);
|
||||
const directoryPath = path.join(COMPOSE_PATH, appName);
|
||||
const command = `rm -rf ${directoryPath}`;
|
||||
try {
|
||||
@@ -88,6 +86,7 @@ export const removeMonitoringDirectory = async (
|
||||
appName: string,
|
||||
serverId?: string | null,
|
||||
) => {
|
||||
const { MONITORING_PATH } = paths(!!serverId);
|
||||
const directoryPath = path.join(MONITORING_PATH, appName);
|
||||
const command = `rm -rf ${directoryPath}`;
|
||||
try {
|
||||
@@ -103,6 +102,7 @@ export const removeMonitoringDirectory = async (
|
||||
};
|
||||
|
||||
export const getBuildAppDirectory = (application: Application) => {
|
||||
const { APPLICATIONS_PATH } = paths(!!application.serverId);
|
||||
const { appName, buildType, sourceType, customGitBuildPath, dockerfile } =
|
||||
application;
|
||||
let buildPath = "";
|
||||
@@ -132,6 +132,7 @@ export const getBuildAppDirectory = (application: Application) => {
|
||||
};
|
||||
|
||||
export const getDockerContextPath = (application: Application) => {
|
||||
const { APPLICATIONS_PATH } = paths(!!application.serverId);
|
||||
const { appName, dockerContextPath } = application;
|
||||
|
||||
if (!dockerContextPath) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import { SSH_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { spawnAsync } from "../process/spawnAsync";
|
||||
|
||||
export const readSSHKey = async (id: string) => {
|
||||
const { SSH_PATH } = paths();
|
||||
try {
|
||||
if (!fs.existsSync(SSH_PATH)) {
|
||||
fs.mkdirSync(SSH_PATH, { recursive: true });
|
||||
@@ -27,6 +28,7 @@ export const saveSSHKey = async (
|
||||
publicKey: string,
|
||||
privateKey: string,
|
||||
) => {
|
||||
const { SSH_PATH } = paths();
|
||||
const applicationDirectory = SSH_PATH;
|
||||
|
||||
const privateKeyPath = path.join(applicationDirectory, `${id}_rsa`);
|
||||
@@ -42,6 +44,7 @@ export const saveSSHKey = async (
|
||||
};
|
||||
|
||||
export const generateSSHKey = async (type: "rsa" | "ed25519" = "rsa") => {
|
||||
const { SSH_PATH } = paths();
|
||||
const applicationDirectory = SSH_PATH;
|
||||
|
||||
if (!fs.existsSync(applicationDirectory)) {
|
||||
@@ -85,6 +88,7 @@ export const generateSSHKey = async (type: "rsa" | "ed25519" = "rsa") => {
|
||||
|
||||
export const removeSSHKey = async (id: string) => {
|
||||
try {
|
||||
const { SSH_PATH } = paths();
|
||||
const publicKeyPath = path.join(SSH_PATH, `${id}_rsa.pub`);
|
||||
const privateKeyPath = path.join(SSH_PATH, `${id}_rsa`);
|
||||
await fs.promises.unlink(publicKeyPath);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createWriteStream } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { findBitbucketById } from "@/server/api/services/bitbucket";
|
||||
import type { Compose } from "@/server/api/services/compose";
|
||||
import { APPLICATIONS_PATH, COMPOSE_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import type {
|
||||
apiBitbucketTestConnection,
|
||||
apiFindBitbucketBranches,
|
||||
@@ -28,6 +28,7 @@ export const cloneBitbucketRepository = async (
|
||||
logPath: string,
|
||||
isCompose = false,
|
||||
) => {
|
||||
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths();
|
||||
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||
const {
|
||||
appName,
|
||||
@@ -80,6 +81,7 @@ export const cloneBitbucketRepository = async (
|
||||
};
|
||||
|
||||
export const cloneRawBitbucketRepository = async (entity: Compose) => {
|
||||
const { COMPOSE_PATH } = paths();
|
||||
const {
|
||||
appName,
|
||||
bitbucketRepository,
|
||||
@@ -119,6 +121,7 @@ export const cloneRawBitbucketRepository = async (entity: Compose) => {
|
||||
};
|
||||
|
||||
export const cloneRawBitbucketRepositoryRemote = async (compose: Compose) => {
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
const {
|
||||
appName,
|
||||
bitbucketRepository,
|
||||
@@ -163,6 +166,7 @@ export const getBitbucketCloneCommand = async (
|
||||
logPath: string,
|
||||
isCompose = false,
|
||||
) => {
|
||||
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths(true);
|
||||
const {
|
||||
appName,
|
||||
bitbucketRepository,
|
||||
@@ -193,7 +197,7 @@ export const getBitbucketCloneCommand = async (
|
||||
}
|
||||
|
||||
const bitbucketProvider = await findBitbucketById(bitbucketId);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
await recreateDirectory(outputPath);
|
||||
const repoclone = `bitbucket.org/${bitbucketOwner}/${bitbucketRepository}.git`;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createWriteStream } from "node:fs";
|
||||
import path, { join } from "node:path";
|
||||
import type { Compose } from "@/server/api/services/compose";
|
||||
import { updateSSHKeyById } from "@/server/api/services/ssh-key";
|
||||
import { APPLICATIONS_PATH, COMPOSE_PATH, SSH_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { recreateDirectory } from "../filesystem/directory";
|
||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||
@@ -18,6 +18,7 @@ export const cloneGitRepository = async (
|
||||
logPath: string,
|
||||
isCompose = false,
|
||||
) => {
|
||||
const { SSH_PATH, COMPOSE_PATH, APPLICATIONS_PATH } = paths();
|
||||
const { appName, customGitUrl, customGitBranch, customGitSSHKeyId } = entity;
|
||||
|
||||
if (!customGitUrl || !customGitBranch) {
|
||||
@@ -99,6 +100,7 @@ export const getCustomGitCloneCommand = async (
|
||||
logPath: string,
|
||||
isCompose = false,
|
||||
) => {
|
||||
const { SSH_PATH, COMPOSE_PATH, APPLICATIONS_PATH } = paths(true);
|
||||
const {
|
||||
appName,
|
||||
customGitUrl,
|
||||
@@ -168,6 +170,7 @@ const isHttpOrHttps = (url: string): boolean => {
|
||||
};
|
||||
|
||||
const addHostToKnownHosts = async (repositoryURL: string) => {
|
||||
const { SSH_PATH } = paths();
|
||||
const { domain, port } = sanitizeRepoPathSSH(repositoryURL);
|
||||
const knownHostsPath = path.join(SSH_PATH, "known_hosts");
|
||||
|
||||
@@ -181,6 +184,7 @@ const addHostToKnownHosts = async (repositoryURL: string) => {
|
||||
};
|
||||
|
||||
const addHostToKnownHostsCommand = (repositoryURL: string) => {
|
||||
const { SSH_PATH } = paths();
|
||||
const { domain, port } = sanitizeRepoPathSSH(repositoryURL);
|
||||
const knownHostsPath = path.join(SSH_PATH, "known_hosts");
|
||||
|
||||
@@ -237,6 +241,7 @@ export const cloneGitRawRepository = async (entity: {
|
||||
});
|
||||
}
|
||||
|
||||
const { SSH_PATH, COMPOSE_PATH } = paths();
|
||||
const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
@@ -302,6 +307,7 @@ export const cloneRawGitRepositoryRemote = async (compose: Compose) => {
|
||||
});
|
||||
}
|
||||
|
||||
const { SSH_PATH, COMPOSE_PATH } = paths(true);
|
||||
const keyPath = path.join(SSH_PATH, `${customGitSSHKeyId}_rsa`);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createWriteStream } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { APPLICATIONS_PATH, COMPOSE_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
import { createAppAuth } from "@octokit/auth-app";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
@@ -79,6 +79,7 @@ export const cloneGithubRepository = async (
|
||||
logPath: string,
|
||||
isCompose = false,
|
||||
) => {
|
||||
const { APPLICATIONS_PATH, COMPOSE_PATH } = paths();
|
||||
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||
const { appName, repository, owner, branch, githubId } = entity;
|
||||
|
||||
@@ -191,7 +192,7 @@ export const getGithubCloneCommand = async (
|
||||
await execAsyncRemote(serverId, bashCommand);
|
||||
return;
|
||||
}
|
||||
|
||||
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths(true);
|
||||
const githubProvider = await findGithubById(githubId);
|
||||
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
@@ -222,6 +223,7 @@ export const cloneRawGithubRepository = async (entity: Compose) => {
|
||||
message: "GitHub Provider not found",
|
||||
});
|
||||
}
|
||||
const { COMPOSE_PATH } = paths();
|
||||
const githubProvider = await findGithubById(githubId);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
@@ -261,6 +263,8 @@ export const cloneRawGithubRepositoryRemote = async (compose: Compose) => {
|
||||
message: "GitHub Provider not found",
|
||||
});
|
||||
}
|
||||
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
const githubProvider = await findGithubById(githubId);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
findGitlabById,
|
||||
updateGitlab,
|
||||
} from "@/server/api/services/gitlab";
|
||||
import { APPLICATIONS_PATH, COMPOSE_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import type { apiGitlabTestConnection } from "@/server/db/schema";
|
||||
import type { InferResultType } from "@/server/types/with";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
@@ -119,6 +119,8 @@ export const cloneGitlabRepository = async (
|
||||
message: "Error: GitLab repository information is incomplete.",
|
||||
});
|
||||
}
|
||||
|
||||
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths();
|
||||
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
await recreateDirectory(outputPath);
|
||||
@@ -212,6 +214,7 @@ export const getGitlabCloneCommand = async (
|
||||
return;
|
||||
}
|
||||
|
||||
const { COMPOSE_PATH, APPLICATIONS_PATH } = paths(true);
|
||||
await refreshGitlabToken(gitlabId);
|
||||
const basePath = isCompose ? COMPOSE_PATH : APPLICATIONS_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
@@ -343,7 +346,7 @@ export const cloneRawGitlabRepository = async (entity: Compose) => {
|
||||
}
|
||||
|
||||
const gitlabProvider = await findGitlabById(gitlabId);
|
||||
|
||||
const { COMPOSE_PATH } = paths();
|
||||
await refreshGitlabToken(gitlabId);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
@@ -383,7 +386,7 @@ export const cloneRawGitlabRepositoryRemote = async (compose: Compose) => {
|
||||
});
|
||||
}
|
||||
const gitlabProvider = await findGitlabById(gitlabId);
|
||||
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
await refreshGitlabToken(gitlabId);
|
||||
const basePath = COMPOSE_PATH;
|
||||
const outputPath = join(basePath, appName, "code");
|
||||
|
||||
@@ -2,12 +2,13 @@ import { createWriteStream } from "node:fs";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import type { Compose } from "@/server/api/services/compose";
|
||||
import { COMPOSE_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { encodeBase64 } from "../docker/utils";
|
||||
import { recreateDirectory } from "../filesystem/directory";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
|
||||
export const createComposeFile = async (compose: Compose, logPath: string) => {
|
||||
const { COMPOSE_PATH } = paths();
|
||||
const { appName, composeFile } = compose;
|
||||
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||
const outputPath = join(COMPOSE_PATH, appName, "code");
|
||||
@@ -33,6 +34,7 @@ export const getCreateComposeFileCommand = (
|
||||
compose: Compose,
|
||||
logPath: string,
|
||||
) => {
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
const { appName, composeFile } = compose;
|
||||
const outputPath = join(COMPOSE_PATH, appName, "code");
|
||||
const filePath = join(outputPath, "docker-compose.yml");
|
||||
@@ -47,6 +49,7 @@ export const getCreateComposeFileCommand = (
|
||||
};
|
||||
|
||||
export const createComposeFileRaw = async (compose: Compose) => {
|
||||
const { COMPOSE_PATH } = paths();
|
||||
const { appName, composeFile } = compose;
|
||||
const outputPath = join(COMPOSE_PATH, appName, "code");
|
||||
const filePath = join(outputPath, "docker-compose.yml");
|
||||
@@ -59,6 +62,7 @@ export const createComposeFileRaw = async (compose: Compose) => {
|
||||
};
|
||||
|
||||
export const createComposeFileRawRemote = async (compose: Compose) => {
|
||||
const { COMPOSE_PATH } = paths(true);
|
||||
const { appName, composeFile, serverId } = compose;
|
||||
const outputPath = join(COMPOSE_PATH, appName, "code");
|
||||
const filePath = join(outputPath, "docker-compose.yml");
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
updateDeploymentStatus,
|
||||
} from "@/server/api/services/deployment";
|
||||
import { findServerById } from "@/server/api/services/server";
|
||||
import { LOGS_PATH, SSH_PATH, getPaths } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import {
|
||||
getDefaultMiddlewares,
|
||||
getDefaultServerTraefikConfig,
|
||||
@@ -17,6 +17,7 @@ import { readSSHKey } from "../filesystem/ssh";
|
||||
|
||||
export const setupServer = async (serverId: string) => {
|
||||
const server = await findServerById(serverId);
|
||||
const { LOGS_PATH } = paths();
|
||||
|
||||
const slugifyName = slugify(`server ${server.name}`);
|
||||
|
||||
@@ -29,8 +30,8 @@ export const setupServer = async (serverId: string) => {
|
||||
title: "Setup Server",
|
||||
description: "Setup Server",
|
||||
});
|
||||
const writeStream = createWriteStream(deployment.logPath, { flags: "a" });
|
||||
|
||||
const writeStream = createWriteStream(deployment.logPath, { flags: "a" });
|
||||
try {
|
||||
writeStream.write("\nInstalling Server Dependencies: ✅\n");
|
||||
await connectToServer(serverId, deployment.logPath);
|
||||
@@ -50,8 +51,18 @@ const connectToServer = async (serverId: string, logPath: string) => {
|
||||
const writeStream = createWriteStream(logPath, { flags: "a" });
|
||||
const client = new Client();
|
||||
const server = await findServerById(serverId);
|
||||
if (!server.sshKeyId) return;
|
||||
if (!server.sshKeyId) {
|
||||
writeStream.write("❌ No SSH Key found");
|
||||
writeStream.close();
|
||||
throw new Error("No SSH Key found");
|
||||
}
|
||||
const keys = await readSSHKey(server.sshKeyId);
|
||||
|
||||
if (!keys.privateKey) {
|
||||
writeStream.write("❌ No SSH Key found");
|
||||
writeStream.close();
|
||||
throw new Error("No SSH Key found");
|
||||
}
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
client
|
||||
.once("ready", () => {
|
||||
@@ -106,23 +117,12 @@ const connectToServer = async (serverId: string, logPath: string) => {
|
||||
};
|
||||
|
||||
const setupDirectories = () => {
|
||||
// const directories = [
|
||||
// BASE_PATH,
|
||||
// MAIN_TRAEFIK_PATH,
|
||||
// DYNAMIC_TRAEFIK_PATH,
|
||||
// LOGS_PATH,
|
||||
// APPLICATIONS_PATH,
|
||||
// SSH_PATH,
|
||||
// CERTIFICATES_PATH,
|
||||
// MONITORING_PATH,
|
||||
// ];
|
||||
|
||||
const directories = getPaths("/etc/dokploy");
|
||||
const { SSH_PATH } = paths(true);
|
||||
const directories = Object.values(paths(true));
|
||||
|
||||
const createDirsCommand = directories
|
||||
.map((dir) => `mkdir -p "${dir}"`)
|
||||
.join(" && ");
|
||||
|
||||
const chmodCommand = `chmod 700 "${SSH_PATH}"`;
|
||||
|
||||
const command = `
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs, { writeFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { Domain } from "@/server/api/services/domain";
|
||||
import { DYNAMIC_TRAEFIK_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
import type { FileConfig, HttpLoadBalancerService } from "./file-types";
|
||||
@@ -39,6 +39,7 @@ export const createTraefikConfig = (appName: string) => {
|
||||
},
|
||||
};
|
||||
const yamlStr = dump(config);
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
fs.mkdirSync(DYNAMIC_TRAEFIK_PATH, { recursive: true });
|
||||
writeFileSync(
|
||||
path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`),
|
||||
@@ -52,6 +53,7 @@ export const removeTraefikConfig = async (
|
||||
serverId?: string | null,
|
||||
) => {
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(!!serverId);
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
|
||||
if (serverId) {
|
||||
@@ -72,12 +74,14 @@ export const removeTraefikConfigRemote = async (
|
||||
serverId: string,
|
||||
) => {
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
await execAsyncRemote(serverId, `rm ${configPath}`);
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const loadOrCreateConfig = (appName: string): FileConfig => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
if (fs.existsSync(configPath)) {
|
||||
const yamlStr = fs.readFileSync(configPath, "utf8");
|
||||
@@ -93,6 +97,7 @@ export const loadOrCreateConfigRemote = async (
|
||||
serverId: string,
|
||||
appName: string,
|
||||
) => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const fileConfig: FileConfig = { http: { routers: {}, services: {} } };
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
try {
|
||||
@@ -110,6 +115,7 @@ export const loadOrCreateConfigRemote = async (
|
||||
};
|
||||
|
||||
export const readConfig = (appName: string) => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
if (fs.existsSync(configPath)) {
|
||||
const yamlStr = fs.readFileSync(configPath, "utf8");
|
||||
@@ -119,6 +125,7 @@ export const readConfig = (appName: string) => {
|
||||
};
|
||||
|
||||
export const readRemoteConfig = async (serverId: string, appName: string) => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
try {
|
||||
const { stdout } = await execAsyncRemote(serverId, `cat ${configPath}`);
|
||||
@@ -130,6 +137,7 @@ export const readRemoteConfig = async (serverId: string, appName: string) => {
|
||||
};
|
||||
|
||||
export const readMonitoringConfig = () => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, "access.log");
|
||||
if (fs.existsSync(configPath)) {
|
||||
const yamlStr = fs.readFileSync(configPath, "utf8");
|
||||
@@ -149,6 +157,7 @@ export const readConfigInPath = (pathFile: string) => {
|
||||
|
||||
export const writeConfig = (appName: string, traefikConfig: string) => {
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
fs.writeFileSync(configPath, traefikConfig, "utf8");
|
||||
} catch (e) {
|
||||
@@ -162,6 +171,7 @@ export const writeConfigRemote = async (
|
||||
traefikConfig: string,
|
||||
) => {
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
await execAsyncRemote(serverId, `echo '${traefikConfig}' > ${configPath}`);
|
||||
} catch (e) {
|
||||
@@ -186,6 +196,7 @@ export const writeTraefikConfig = (
|
||||
appName: string,
|
||||
) => {
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
const yamlStr = dump(traefikConfig);
|
||||
fs.writeFileSync(configPath, yamlStr, "utf8");
|
||||
@@ -200,6 +211,7 @@ export const writeTraefikConfigRemote = async (
|
||||
serverId: string,
|
||||
) => {
|
||||
try {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const configPath = path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`);
|
||||
const yamlStr = dump(traefikConfig);
|
||||
await execAsyncRemote(serverId, `echo '${yamlStr}' > ${configPath}`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { DYNAMIC_TRAEFIK_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { dump, load } from "js-yaml";
|
||||
import type { ApplicationNested } from "../builders";
|
||||
import { execAsyncRemote } from "../process/execAsync";
|
||||
@@ -69,6 +69,7 @@ export const deleteAllMiddlewares = async (application: ApplicationNested) => {
|
||||
};
|
||||
|
||||
export const loadMiddlewares = <T>() => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||
const configPath = join(DYNAMIC_TRAEFIK_PATH, "middlewares.yml");
|
||||
if (!existsSync(configPath)) {
|
||||
throw new Error(`File not found: ${configPath}`);
|
||||
@@ -79,6 +80,7 @@ export const loadMiddlewares = <T>() => {
|
||||
};
|
||||
|
||||
export const loadRemoteMiddlewares = async (serverId: string) => {
|
||||
const { DYNAMIC_TRAEFIK_PATH } = paths(true);
|
||||
const configPath = join(DYNAMIC_TRAEFIK_PATH, "middlewares.yml");
|
||||
|
||||
try {
|
||||
@@ -98,6 +100,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);
|
||||
writeFileSync(configPath, newYamlContent, "utf8");
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import type { Registry } from "@/server/api/services/registry";
|
||||
import { REGISTRY_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { removeDirectoryIfExistsContent } from "../filesystem/directory";
|
||||
import type { FileConfig, HttpRouter } from "./file-types";
|
||||
|
||||
export const manageRegistry = async (registry: Registry) => {
|
||||
const { REGISTRY_PATH } = paths();
|
||||
if (!existsSync(REGISTRY_PATH)) {
|
||||
mkdirSync(REGISTRY_PATH, { recursive: true });
|
||||
}
|
||||
@@ -36,6 +37,7 @@ export const manageRegistry = async (registry: Registry) => {
|
||||
};
|
||||
|
||||
export const removeSelfHostedRegistry = async () => {
|
||||
const { REGISTRY_PATH } = paths();
|
||||
await removeDirectoryIfExistsContent(REGISTRY_PATH);
|
||||
};
|
||||
|
||||
@@ -60,6 +62,7 @@ const createRegistryRouterConfig = async (registry: Registry) => {
|
||||
};
|
||||
|
||||
const loadOrCreateConfig = (): FileConfig => {
|
||||
const { REGISTRY_PATH } = paths();
|
||||
const configPath = join(REGISTRY_PATH, "registry.yml");
|
||||
if (existsSync(configPath)) {
|
||||
const yamlStr = readFileSync(configPath, "utf8");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import type { Admin } from "@/server/api/services/admin";
|
||||
import { MAIN_TRAEFIK_PATH } from "@/server/constants";
|
||||
import { paths } from "@/server/constants";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { loadOrCreateConfig, writeTraefikConfig } from "./application";
|
||||
import type { FileConfig } from "./file-types";
|
||||
@@ -42,6 +42,7 @@ export const updateServerTraefik = (
|
||||
export const updateLetsEncryptEmail = (newEmail: string | null) => {
|
||||
try {
|
||||
if (!newEmail) return;
|
||||
const { MAIN_TRAEFIK_PATH } = paths();
|
||||
const configPath = join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
||||
const configContent = readFileSync(configPath, "utf8");
|
||||
const config = load(configContent) as MainTraefikConfig;
|
||||
@@ -58,6 +59,7 @@ export const updateLetsEncryptEmail = (newEmail: string | null) => {
|
||||
};
|
||||
|
||||
export const readMainConfig = () => {
|
||||
const { MAIN_TRAEFIK_PATH } = paths();
|
||||
const configPath = join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
||||
if (existsSync(configPath)) {
|
||||
const yamlStr = readFileSync(configPath, "utf8");
|
||||
@@ -68,6 +70,7 @@ export const readMainConfig = () => {
|
||||
|
||||
export const writeMainConfig = (traefikConfig: string) => {
|
||||
try {
|
||||
const { MAIN_TRAEFIK_PATH } = paths();
|
||||
const configPath = join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
||||
writeFileSync(configPath, traefikConfig, "utf8");
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user