mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: update
This commit is contained in:
@@ -9,325 +9,325 @@ import type { FileConfig } from "../utils/traefik/file-types";
|
|||||||
import type { MainTraefikConfig } from "../utils/traefik/types";
|
import type { MainTraefikConfig } from "../utils/traefik/types";
|
||||||
|
|
||||||
export const TRAEFIK_SSL_PORT =
|
export const TRAEFIK_SSL_PORT =
|
||||||
Number.parseInt(process.env.TRAEFIK_SSL_PORT!, 10) || 443;
|
Number.parseInt(process.env.TRAEFIK_SSL_PORT!, 10) || 443;
|
||||||
export const TRAEFIK_PORT =
|
export const TRAEFIK_PORT =
|
||||||
Number.parseInt(process.env.TRAEFIK_PORT!, 10) || 80;
|
Number.parseInt(process.env.TRAEFIK_PORT!, 10) || 80;
|
||||||
export const TRAEFIK_VERSION = process.env.TRAEFIK_VERSION || "3.1.2";
|
export const TRAEFIK_VERSION = process.env.TRAEFIK_VERSION || "3.1.2";
|
||||||
|
|
||||||
interface TraefikOptions {
|
interface TraefikOptions {
|
||||||
enableDashboard?: boolean;
|
enableDashboard?: boolean;
|
||||||
env?: string[];
|
env?: string[];
|
||||||
serverId?: string;
|
serverId?: string;
|
||||||
additionalPorts?: {
|
additionalPorts?: {
|
||||||
targetPort: number;
|
targetPort: number;
|
||||||
publishedPort: number;
|
publishedPort: number;
|
||||||
publishMode?: "ingress" | "host";
|
publishMode?: "ingress" | "host";
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initializeTraefik = async ({
|
export const initializeTraefik = async ({
|
||||||
enableDashboard = false,
|
enableDashboard = false,
|
||||||
env,
|
env,
|
||||||
serverId,
|
serverId,
|
||||||
additionalPorts = [],
|
additionalPorts = [],
|
||||||
}: TraefikOptions = {}) => {
|
}: TraefikOptions = {}) => {
|
||||||
const { MAIN_TRAEFIK_PATH, DYNAMIC_TRAEFIK_PATH } = paths(!!serverId);
|
const { MAIN_TRAEFIK_PATH, DYNAMIC_TRAEFIK_PATH } = paths(!!serverId);
|
||||||
const imageName = `traefik:v${TRAEFIK_VERSION}`;
|
const imageName = `traefik:v${TRAEFIK_VERSION}`;
|
||||||
const containerName = "dokploy-traefik";
|
const containerName = "dokploy-traefik";
|
||||||
const settings: CreateServiceOptions = {
|
const settings: CreateServiceOptions = {
|
||||||
Name: containerName,
|
Name: containerName,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
ContainerSpec: {
|
ContainerSpec: {
|
||||||
Image: imageName,
|
Image: imageName,
|
||||||
Env: env,
|
Env: env,
|
||||||
Mounts: [
|
Mounts: [
|
||||||
{
|
{
|
||||||
Type: "bind",
|
Type: "bind",
|
||||||
Source: `${MAIN_TRAEFIK_PATH}/traefik.yml`,
|
Source: `${MAIN_TRAEFIK_PATH}/traefik.yml`,
|
||||||
Target: "/etc/traefik/traefik.yml",
|
Target: "/etc/traefik/traefik.yml",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: "bind",
|
Type: "bind",
|
||||||
Source: DYNAMIC_TRAEFIK_PATH,
|
Source: DYNAMIC_TRAEFIK_PATH,
|
||||||
Target: "/etc/dokploy/traefik/dynamic",
|
Target: "/etc/dokploy/traefik/dynamic",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: "bind",
|
Type: "bind",
|
||||||
Source: "/var/run/docker.sock",
|
Source: "/var/run/docker.sock",
|
||||||
Target: "/var/run/docker.sock",
|
Target: "/var/run/docker.sock",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Networks: [{ Target: "dokploy-network" }],
|
Networks: [{ Target: "dokploy-network" }],
|
||||||
Placement: {
|
Placement: {
|
||||||
Constraints: ["node.role==manager"],
|
Constraints: ["node.role==manager"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Mode: {
|
Mode: {
|
||||||
Replicated: {
|
Replicated: {
|
||||||
Replicas: 1,
|
Replicas: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Labels: {
|
Labels: {
|
||||||
"traefik.enable": "true",
|
"traefik.enable": "true",
|
||||||
},
|
},
|
||||||
EndpointSpec: {
|
EndpointSpec: {
|
||||||
Ports: [
|
Ports: [
|
||||||
{
|
{
|
||||||
TargetPort: 443,
|
TargetPort: TRAEFIK_SSL_PORT,
|
||||||
PublishedPort: TRAEFIK_SSL_PORT,
|
PublishedPort: TRAEFIK_SSL_PORT,
|
||||||
PublishMode: "host",
|
PublishMode: "host",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
TargetPort: 80,
|
TargetPort: TRAEFIK_PORT,
|
||||||
PublishedPort: TRAEFIK_PORT,
|
PublishedPort: TRAEFIK_PORT,
|
||||||
PublishMode: "host",
|
PublishMode: "host",
|
||||||
},
|
},
|
||||||
...(enableDashboard
|
...(enableDashboard
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
TargetPort: 8080,
|
TargetPort: 8080,
|
||||||
PublishedPort: 8080,
|
PublishedPort: 8080,
|
||||||
PublishMode: "host" as const,
|
PublishMode: "host" as const,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
...additionalPorts.map((port) => ({
|
...additionalPorts.map((port) => ({
|
||||||
TargetPort: port.targetPort,
|
TargetPort: port.targetPort,
|
||||||
PublishedPort: port.publishedPort,
|
PublishedPort: port.publishedPort,
|
||||||
PublishMode: port.publishMode || ("host" as const),
|
PublishMode: port.publishMode || ("host" as const),
|
||||||
})),
|
})),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const docker = await getRemoteDocker(serverId);
|
const docker = await getRemoteDocker(serverId);
|
||||||
try {
|
try {
|
||||||
if (serverId) {
|
if (serverId) {
|
||||||
await pullRemoteImage(imageName, serverId);
|
await pullRemoteImage(imageName, serverId);
|
||||||
} else {
|
} else {
|
||||||
await pullImage(imageName);
|
await pullImage(imageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const service = docker.getService(containerName);
|
const service = docker.getService(containerName);
|
||||||
const inspect = await service.inspect();
|
const inspect = await service.inspect();
|
||||||
|
|
||||||
const existingEnv = inspect.Spec.TaskTemplate.ContainerSpec.Env || [];
|
const existingEnv = inspect.Spec.TaskTemplate.ContainerSpec.Env || [];
|
||||||
const updatedEnv = !env ? existingEnv : env;
|
const updatedEnv = !env ? existingEnv : env;
|
||||||
|
|
||||||
const updatedSettings = {
|
const updatedSettings = {
|
||||||
...settings,
|
...settings,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
...settings.TaskTemplate,
|
...settings.TaskTemplate,
|
||||||
ContainerSpec: {
|
ContainerSpec: {
|
||||||
...(settings?.TaskTemplate as ContainerTaskSpec).ContainerSpec,
|
...(settings?.TaskTemplate as ContainerTaskSpec).ContainerSpec,
|
||||||
Env: updatedEnv,
|
Env: updatedEnv,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
await service.update({
|
await service.update({
|
||||||
version: Number.parseInt(inspect.Version.Index),
|
version: Number.parseInt(inspect.Version.Index),
|
||||||
...updatedSettings,
|
...updatedSettings,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Traefik Started ✅");
|
console.log("Traefik Started ✅");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await docker.createService(settings);
|
await docker.createService(settings);
|
||||||
console.log("Traefik Not Found: Starting ✅");
|
console.log("Traefik Not Found: Starting ✅");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createDefaultServerTraefikConfig = () => {
|
export const createDefaultServerTraefikConfig = () => {
|
||||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||||
const configFilePath = path.join(DYNAMIC_TRAEFIK_PATH, "dokploy.yml");
|
const configFilePath = path.join(DYNAMIC_TRAEFIK_PATH, "dokploy.yml");
|
||||||
|
|
||||||
if (existsSync(configFilePath)) {
|
if (existsSync(configFilePath)) {
|
||||||
console.log("Default traefik config already exists");
|
console.log("Default traefik config already exists");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const appName = "dokploy";
|
const appName = "dokploy";
|
||||||
const serviceURLDefault = `http://${appName}:${process.env.PORT || 3000}`;
|
const serviceURLDefault = `http://${appName}:${process.env.PORT || 3000}`;
|
||||||
const config: FileConfig = {
|
const config: FileConfig = {
|
||||||
http: {
|
http: {
|
||||||
routers: {
|
routers: {
|
||||||
[`${appName}-router-app`]: {
|
[`${appName}-router-app`]: {
|
||||||
rule: `Host(\`${appName}.docker.localhost\`) && PathPrefix(\`/\`)`,
|
rule: `Host(\`${appName}.docker.localhost\`) && PathPrefix(\`/\`)`,
|
||||||
service: `${appName}-service-app`,
|
service: `${appName}-service-app`,
|
||||||
entryPoints: ["web"],
|
entryPoints: ["web"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
services: {
|
services: {
|
||||||
[`${appName}-service-app`]: {
|
[`${appName}-service-app`]: {
|
||||||
loadBalancer: {
|
loadBalancer: {
|
||||||
servers: [{ url: serviceURLDefault }],
|
servers: [{ url: serviceURLDefault }],
|
||||||
passHostHeader: true,
|
passHostHeader: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const yamlStr = dump(config);
|
const yamlStr = dump(config);
|
||||||
mkdirSync(DYNAMIC_TRAEFIK_PATH, { recursive: true });
|
mkdirSync(DYNAMIC_TRAEFIK_PATH, { recursive: true });
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`),
|
path.join(DYNAMIC_TRAEFIK_PATH, `${appName}.yml`),
|
||||||
yamlStr,
|
yamlStr,
|
||||||
"utf8",
|
"utf8"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDefaultTraefikConfig = () => {
|
export const getDefaultTraefikConfig = () => {
|
||||||
const configObject: MainTraefikConfig = {
|
const configObject: MainTraefikConfig = {
|
||||||
providers: {
|
providers: {
|
||||||
...(process.env.NODE_ENV === "development"
|
...(process.env.NODE_ENV === "development"
|
||||||
? {
|
? {
|
||||||
docker: {
|
docker: {
|
||||||
defaultRule:
|
defaultRule:
|
||||||
"Host(`{{ trimPrefix `/` .Name }}.docker.localhost`)",
|
"Host(`{{ trimPrefix `/` .Name }}.docker.localhost`)",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
swarm: {
|
swarm: {
|
||||||
exposedByDefault: false,
|
exposedByDefault: false,
|
||||||
watch: false,
|
watch: false,
|
||||||
},
|
},
|
||||||
docker: {
|
docker: {
|
||||||
exposedByDefault: false,
|
exposedByDefault: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
file: {
|
file: {
|
||||||
directory: "/etc/dokploy/traefik/dynamic",
|
directory: "/etc/dokploy/traefik/dynamic",
|
||||||
watch: true,
|
watch: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
entryPoints: {
|
entryPoints: {
|
||||||
web: {
|
web: {
|
||||||
address: `:${TRAEFIK_PORT}`,
|
address: `:${TRAEFIK_PORT}`,
|
||||||
},
|
},
|
||||||
websecure: {
|
websecure: {
|
||||||
address: `:${TRAEFIK_SSL_PORT}`,
|
address: `:${TRAEFIK_SSL_PORT}`,
|
||||||
...(process.env.NODE_ENV === "production" && {
|
...(process.env.NODE_ENV === "production" && {
|
||||||
http: {
|
http: {
|
||||||
tls: {
|
tls: {
|
||||||
certResolver: "letsencrypt",
|
certResolver: "letsencrypt",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
api: {
|
api: {
|
||||||
insecure: true,
|
insecure: true,
|
||||||
},
|
},
|
||||||
...(process.env.NODE_ENV === "production" && {
|
...(process.env.NODE_ENV === "production" && {
|
||||||
certificatesResolvers: {
|
certificatesResolvers: {
|
||||||
letsencrypt: {
|
letsencrypt: {
|
||||||
acme: {
|
acme: {
|
||||||
email: "test@localhost.com",
|
email: "test@localhost.com",
|
||||||
storage: "/etc/dokploy/traefik/dynamic/acme.json",
|
storage: "/etc/dokploy/traefik/dynamic/acme.json",
|
||||||
httpChallenge: {
|
httpChallenge: {
|
||||||
entryPoint: "web",
|
entryPoint: "web",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const yamlStr = dump(configObject);
|
const yamlStr = dump(configObject);
|
||||||
|
|
||||||
return yamlStr;
|
return yamlStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDefaultServerTraefikConfig = () => {
|
export const getDefaultServerTraefikConfig = () => {
|
||||||
const configObject: MainTraefikConfig = {
|
const configObject: MainTraefikConfig = {
|
||||||
providers: {
|
providers: {
|
||||||
swarm: {
|
swarm: {
|
||||||
exposedByDefault: false,
|
exposedByDefault: false,
|
||||||
watch: false,
|
watch: false,
|
||||||
},
|
},
|
||||||
docker: {
|
docker: {
|
||||||
exposedByDefault: false,
|
exposedByDefault: false,
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
directory: "/etc/dokploy/traefik/dynamic",
|
directory: "/etc/dokploy/traefik/dynamic",
|
||||||
watch: true,
|
watch: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
entryPoints: {
|
entryPoints: {
|
||||||
web: {
|
web: {
|
||||||
address: `:${TRAEFIK_PORT}`,
|
address: `:${TRAEFIK_PORT}`,
|
||||||
},
|
},
|
||||||
websecure: {
|
websecure: {
|
||||||
address: `:${TRAEFIK_SSL_PORT}`,
|
address: `:${TRAEFIK_SSL_PORT}`,
|
||||||
http: {
|
http: {
|
||||||
tls: {
|
tls: {
|
||||||
certResolver: "letsencrypt",
|
certResolver: "letsencrypt",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
api: {
|
api: {
|
||||||
insecure: true,
|
insecure: true,
|
||||||
},
|
},
|
||||||
certificatesResolvers: {
|
certificatesResolvers: {
|
||||||
letsencrypt: {
|
letsencrypt: {
|
||||||
acme: {
|
acme: {
|
||||||
email: "test@localhost.com",
|
email: "test@localhost.com",
|
||||||
storage: "/etc/dokploy/traefik/dynamic/acme.json",
|
storage: "/etc/dokploy/traefik/dynamic/acme.json",
|
||||||
httpChallenge: {
|
httpChallenge: {
|
||||||
entryPoint: "web",
|
entryPoint: "web",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const yamlStr = dump(configObject);
|
const yamlStr = dump(configObject);
|
||||||
|
|
||||||
return yamlStr;
|
return yamlStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createDefaultTraefikConfig = () => {
|
export const createDefaultTraefikConfig = () => {
|
||||||
const { MAIN_TRAEFIK_PATH, DYNAMIC_TRAEFIK_PATH } = paths();
|
const { MAIN_TRAEFIK_PATH, DYNAMIC_TRAEFIK_PATH } = paths();
|
||||||
const mainConfig = path.join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
const mainConfig = path.join(MAIN_TRAEFIK_PATH, "traefik.yml");
|
||||||
const acmeJsonPath = path.join(DYNAMIC_TRAEFIK_PATH, "acme.json");
|
const acmeJsonPath = path.join(DYNAMIC_TRAEFIK_PATH, "acme.json");
|
||||||
|
|
||||||
if (existsSync(acmeJsonPath)) {
|
if (existsSync(acmeJsonPath)) {
|
||||||
chmodSync(acmeJsonPath, "600");
|
chmodSync(acmeJsonPath, "600");
|
||||||
}
|
}
|
||||||
if (existsSync(mainConfig)) {
|
if (existsSync(mainConfig)) {
|
||||||
console.log("Main config already exists");
|
console.log("Main config already exists");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const yamlStr = getDefaultTraefikConfig();
|
const yamlStr = getDefaultTraefikConfig();
|
||||||
mkdirSync(MAIN_TRAEFIK_PATH, { recursive: true });
|
mkdirSync(MAIN_TRAEFIK_PATH, { recursive: true });
|
||||||
writeFileSync(mainConfig, yamlStr, "utf8");
|
writeFileSync(mainConfig, yamlStr, "utf8");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDefaultMiddlewares = () => {
|
export const getDefaultMiddlewares = () => {
|
||||||
const defaultMiddlewares = {
|
const defaultMiddlewares = {
|
||||||
http: {
|
http: {
|
||||||
middlewares: {
|
middlewares: {
|
||||||
"redirect-to-https": {
|
"redirect-to-https": {
|
||||||
redirectScheme: {
|
redirectScheme: {
|
||||||
scheme: "https",
|
scheme: "https",
|
||||||
permanent: true,
|
permanent: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const yamlStr = dump(defaultMiddlewares);
|
const yamlStr = dump(defaultMiddlewares);
|
||||||
return yamlStr;
|
return yamlStr;
|
||||||
};
|
};
|
||||||
export const createDefaultMiddlewares = () => {
|
export const createDefaultMiddlewares = () => {
|
||||||
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
const { DYNAMIC_TRAEFIK_PATH } = paths();
|
||||||
const middlewaresPath = path.join(DYNAMIC_TRAEFIK_PATH, "middlewares.yml");
|
const middlewaresPath = path.join(DYNAMIC_TRAEFIK_PATH, "middlewares.yml");
|
||||||
if (existsSync(middlewaresPath)) {
|
if (existsSync(middlewaresPath)) {
|
||||||
console.log("Default middlewares already exists");
|
console.log("Default middlewares already exists");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const yamlStr = getDefaultMiddlewares();
|
const yamlStr = getDefaultMiddlewares();
|
||||||
mkdirSync(DYNAMIC_TRAEFIK_PATH, { recursive: true });
|
mkdirSync(DYNAMIC_TRAEFIK_PATH, { recursive: true });
|
||||||
writeFileSync(middlewaresPath, yamlStr, "utf8");
|
writeFileSync(middlewaresPath, yamlStr, "utf8");
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user