Merge branch 'canary' into 1853-external-volume-should-not-be-isolated

This commit is contained in:
Mauricio Siu
2025-07-06 18:29:00 -06:00
254 changed files with 67652 additions and 8043 deletions

View File

@@ -117,7 +117,7 @@ export const loadDockerComposeRemote = async (
if (!stdout) return null;
const parsedConfig = load(stdout) as ComposeSpecification;
return parsedConfig;
} catch (_err) {
} catch {
return null;
}
};
@@ -301,6 +301,8 @@ export const createDomainLabels = (
certificateType,
path,
customCertResolver,
stripPath,
internalPath,
} = domain;
const routerName = `${appName}-${uniqueConfigKey}-${entrypoint}`;
const labels = [
@@ -310,6 +312,34 @@ export const createDomainLabels = (
`traefik.http.routers.${routerName}.service=${routerName}`,
];
// Validate stripPath - it should only be used when path is defined and not "/"
if (stripPath) {
if (!path || path === "/") {
console.warn(
`stripPath is enabled but path is not defined or is "/" for domain ${host}`,
);
} else {
const middlewareName = `stripprefix-${appName}-${uniqueConfigKey}`;
labels.push(
`traefik.http.middlewares.${middlewareName}.stripprefix.prefixes=${path}`,
);
}
}
// Validate internalPath - ensure it's a valid path format
if (internalPath && internalPath !== "/") {
if (!internalPath.startsWith("/")) {
console.warn(
`internalPath "${internalPath}" should start with "/" and not be empty for domain ${host}`,
);
} else {
const middlewareName = `addprefix-${appName}-${uniqueConfigKey}`;
labels.push(
`traefik.http.middlewares.${middlewareName}.addprefix.prefix=${internalPath}`,
);
}
}
if (entrypoint === "web" && https) {
labels.push(
`traefik.http.routers.${routerName}.middlewares=redirect-to-https@file`,

View File

@@ -2,6 +2,7 @@ import fs from "node:fs";
import path from "node:path";
import type { Readable } from "node:stream";
import { docker, paths } from "@dokploy/server/constants";
import type { Compose } from "@dokploy/server/services/compose";
import type { ContainerInfo, ResourceRequirements } from "dockerode";
import { parse } from "dotenv";
import type { ApplicationNested } from "../builders";
@@ -13,7 +14,6 @@ import type { RedisNested } from "../databases/redis";
import { execAsync, execAsyncRemote } from "../process/execAsync";
import { spawnAsync } from "../process/spawnAsync";
import { getRemoteDocker } from "../servers/remote-docker";
import type { Compose } from "@dokploy/server/services/compose";
interface RegistryAuth {
username: string;
@@ -101,7 +101,7 @@ export const containerExists = async (containerName: string) => {
try {
await container.inspect();
return true;
} catch (_error) {
} catch {
return false;
}
};
@@ -212,7 +212,7 @@ export const cleanUpDockerBuilder = async (serverId?: string) => {
};
export const cleanUpSystemPrune = async (serverId?: string) => {
const command = "docker system prune --all --force --volumes";
const command = "docker system prune --force --volumes";
if (serverId) {
await execAsyncRemote(serverId, command);
} else {
@@ -279,6 +279,17 @@ export const prepareEnvironmentVariables = (
return resolvedVars;
};
export const parseEnvironmentKeyValuePair = (
pair: string,
): [string, string] => {
const [key, ...valueParts] = pair.split("=");
if (!key || !valueParts.length) {
throw new Error(`Invalid environment variable pair: ${pair}`);
}
return [key, valueParts.join("=")];
};
export const getEnviromentVariablesObject = (
input: string | null,
projectEnv?: string | null,
@@ -288,7 +299,7 @@ export const getEnviromentVariablesObject = (
const jsonObject: Record<string, string> = {};
for (const pair of envs) {
const [key, value] = pair.split("=");
const [key, value] = parseEnvironmentKeyValuePair(pair);
if (key && value) {
jsonObject[key] = value;
}