mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
build: update nixpacks to 1.35.0
This commit is contained in:
@@ -52,7 +52,7 @@ feat: add new feature
|
|||||||
|
|
||||||
Before you start, please make the clone based on the `canary` branch, since the `main` branch is the source of truth and should always reflect the latest stable release, also the PRs will be merged to the `canary` branch.
|
Before you start, please make the clone based on the `canary` branch, since the `main` branch is the source of truth and should always reflect the latest stable release, also the PRs will be merged to the `canary` branch.
|
||||||
|
|
||||||
We use Node v20.9.0 and recommend this specific version. If you have nvm installed, you can run `nvm install 20.9.0 && nvm use` in the root directory.
|
We use Node v20.9.0 and recommend this specific version. If you have nvm installed, you can run `nvm install 20.9.0 && nvm use` in the root directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/dokploy/dokploy.git
|
git clone https://github.com/dokploy/dokploy.git
|
||||||
@@ -147,11 +147,9 @@ curl -sSL https://railpack.com/install.sh | sh
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install Buildpacks
|
# Install Buildpacks
|
||||||
curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.32.1/pack-v0.32.1-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack
|
curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.35.0/pack-v0.35.0-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Pull Request
|
## Pull Request
|
||||||
|
|
||||||
- The `main` branch is the source of truth and should always reflect the latest stable release.
|
- The `main` branch is the source of truth and should always reflect the latest stable release.
|
||||||
@@ -169,7 +167,6 @@ Thank you for your contribution!
|
|||||||
|
|
||||||
To add a new template, go to `https://github.com/Dokploy/templates` repository and read the README.md file.
|
To add a new template, go to `https://github.com/Dokploy/templates` repository and read the README.md file.
|
||||||
|
|
||||||
|
|
||||||
### Recommendations
|
### Recommendations
|
||||||
|
|
||||||
- Use the same name of the folder as the id of the template.
|
- Use the same name of the folder as the id of the template.
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && rm
|
|||||||
# Install Nixpacks and tsx
|
# Install Nixpacks and tsx
|
||||||
# | VERBOSE=1 VERSION=1.21.0 bash
|
# | VERBOSE=1 VERSION=1.21.0 bash
|
||||||
|
|
||||||
ARG NIXPACKS_VERSION=1.29.1
|
ARG NIXPACKS_VERSION=1.35.0
|
||||||
RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \
|
RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \
|
||||||
&& chmod +x install.sh \
|
&& chmod +x install.sh \
|
||||||
&& ./install.sh \
|
&& ./install.sh \
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { paths } from "@dokploy/server/constants";
|
import { paths } from "@dokploy/server/constants";
|
||||||
import {
|
import {
|
||||||
createServerDeployment,
|
createServerDeployment,
|
||||||
updateDeploymentStatus,
|
updateDeploymentStatus,
|
||||||
} from "@dokploy/server/services/deployment";
|
} from "@dokploy/server/services/deployment";
|
||||||
import { findServerById } from "@dokploy/server/services/server";
|
import { findServerById } from "@dokploy/server/services/server";
|
||||||
import {
|
import {
|
||||||
TRAEFIK_HTTP3_PORT,
|
TRAEFIK_HTTP3_PORT,
|
||||||
TRAEFIK_PORT,
|
TRAEFIK_PORT,
|
||||||
TRAEFIK_SSL_PORT,
|
TRAEFIK_SSL_PORT,
|
||||||
TRAEFIK_VERSION,
|
TRAEFIK_VERSION,
|
||||||
getDefaultMiddlewares,
|
getDefaultMiddlewares,
|
||||||
getDefaultServerTraefikConfig,
|
getDefaultServerTraefikConfig,
|
||||||
} from "@dokploy/server/setup/traefik-setup";
|
} from "@dokploy/server/setup/traefik-setup";
|
||||||
import { Client } from "ssh2";
|
import { Client } from "ssh2";
|
||||||
import { recreateDirectory } from "../utils/filesystem/directory";
|
import { recreateDirectory } from "../utils/filesystem/directory";
|
||||||
@@ -19,55 +19,55 @@ import { recreateDirectory } from "../utils/filesystem/directory";
|
|||||||
import slug from "slugify";
|
import slug from "slugify";
|
||||||
|
|
||||||
export const slugify = (text: string | undefined) => {
|
export const slugify = (text: string | undefined) => {
|
||||||
if (!text) {
|
if (!text) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanedText = text.trim().replace(/[^a-zA-Z0-9\s]/g, "");
|
const cleanedText = text.trim().replace(/[^a-zA-Z0-9\s]/g, "");
|
||||||
|
|
||||||
return slug(cleanedText, {
|
return slug(cleanedText, {
|
||||||
lower: true,
|
lower: true,
|
||||||
trim: true,
|
trim: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const serverSetup = async (
|
export const serverSetup = async (
|
||||||
serverId: string,
|
serverId: string,
|
||||||
onData?: (data: any) => void,
|
onData?: (data: any) => void
|
||||||
) => {
|
) => {
|
||||||
const server = await findServerById(serverId);
|
const server = await findServerById(serverId);
|
||||||
const { LOGS_PATH } = paths();
|
const { LOGS_PATH } = paths();
|
||||||
|
|
||||||
const slugifyName = slugify(`server ${server.name}`);
|
const slugifyName = slugify(`server ${server.name}`);
|
||||||
|
|
||||||
const fullPath = path.join(LOGS_PATH, slugifyName);
|
const fullPath = path.join(LOGS_PATH, slugifyName);
|
||||||
|
|
||||||
await recreateDirectory(fullPath);
|
await recreateDirectory(fullPath);
|
||||||
|
|
||||||
const deployment = await createServerDeployment({
|
const deployment = await createServerDeployment({
|
||||||
serverId: server.serverId,
|
serverId: server.serverId,
|
||||||
title: "Setup Server",
|
title: "Setup Server",
|
||||||
description: "Setup Server",
|
description: "Setup Server",
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
onData?.("\nInstalling Server Dependencies: ✅\n");
|
onData?.("\nInstalling Server Dependencies: ✅\n");
|
||||||
await installRequirements(serverId, onData);
|
await installRequirements(serverId, onData);
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
|
|
||||||
onData?.("\nSetup Server: ✅\n");
|
onData?.("\nSetup Server: ✅\n");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
onData?.(`${err} ❌\n`);
|
onData?.(`${err} ❌\n`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultCommand = () => {
|
export const defaultCommand = () => {
|
||||||
const bashCommand = `
|
const bashCommand = `
|
||||||
set -e;
|
set -e;
|
||||||
DOCKER_VERSION=27.0.3
|
DOCKER_VERSION=27.0.3
|
||||||
OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"')
|
OS_TYPE=$(grep -w "ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"')
|
||||||
@@ -76,7 +76,7 @@ CURRENT_USER=$USER
|
|||||||
|
|
||||||
echo "Installing requirements for: OS: $OS_TYPE"
|
echo "Installing requirements for: OS: $OS_TYPE"
|
||||||
if [ $EUID != 0 ]; then
|
if [ $EUID != 0 ]; then
|
||||||
echo "Please run this script as root or with sudo ❌"
|
echo "Please run this script as root or with sudo ❌"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -176,83 +176,83 @@ echo -e "13. Installing Railpack"
|
|||||||
${installRailpack()}
|
${installRailpack()}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return bashCommand;
|
return bashCommand;
|
||||||
};
|
};
|
||||||
|
|
||||||
const installRequirements = async (
|
const installRequirements = async (
|
||||||
serverId: string,
|
serverId: string,
|
||||||
onData?: (data: any) => void,
|
onData?: (data: any) => void
|
||||||
) => {
|
) => {
|
||||||
const client = new Client();
|
const client = new Client();
|
||||||
const server = await findServerById(serverId);
|
const server = await findServerById(serverId);
|
||||||
if (!server.sshKeyId) {
|
if (!server.sshKeyId) {
|
||||||
onData?.("❌ No SSH Key found, please assign one to this server");
|
onData?.("❌ No SSH Key found, please assign one to this server");
|
||||||
throw new Error("No SSH Key found");
|
throw new Error("No SSH Key found");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
client
|
client
|
||||||
.once("ready", () => {
|
.once("ready", () => {
|
||||||
const command = server.command || defaultCommand();
|
const command = server.command || defaultCommand();
|
||||||
client.exec(command, (err, stream) => {
|
client.exec(command, (err, stream) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
onData?.(err.message);
|
onData?.(err.message);
|
||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stream
|
stream
|
||||||
.on("close", () => {
|
.on("close", () => {
|
||||||
client.end();
|
client.end();
|
||||||
resolve();
|
resolve();
|
||||||
})
|
})
|
||||||
.on("data", (data: string) => {
|
.on("data", (data: string) => {
|
||||||
onData?.(data.toString());
|
onData?.(data.toString());
|
||||||
})
|
})
|
||||||
.stderr.on("data", (data) => {
|
.stderr.on("data", (data) => {
|
||||||
onData?.(data.toString());
|
onData?.(data.toString());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.on("error", (err) => {
|
.on("error", (err) => {
|
||||||
client.end();
|
client.end();
|
||||||
if (err.level === "client-authentication") {
|
if (err.level === "client-authentication") {
|
||||||
onData?.(
|
onData?.(
|
||||||
`Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`,
|
`Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`
|
||||||
);
|
);
|
||||||
reject(
|
reject(
|
||||||
new Error(
|
new Error(
|
||||||
`Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`,
|
`Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onData?.(`SSH connection error: ${err.message} ${err.level}`);
|
onData?.(`SSH connection error: ${err.message} ${err.level}`);
|
||||||
reject(new Error(`SSH connection error: ${err.message}`));
|
reject(new Error(`SSH connection error: ${err.message}`));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.connect({
|
.connect({
|
||||||
host: server.ipAddress,
|
host: server.ipAddress,
|
||||||
port: server.port,
|
port: server.port,
|
||||||
username: server.username,
|
username: server.username,
|
||||||
privateKey: server.sshKey?.privateKey,
|
privateKey: server.sshKey?.privateKey,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupDirectories = () => {
|
const setupDirectories = () => {
|
||||||
const { SSH_PATH } = paths(true);
|
const { SSH_PATH } = paths(true);
|
||||||
const directories = Object.values(paths(true));
|
const directories = Object.values(paths(true));
|
||||||
|
|
||||||
const createDirsCommand = directories
|
const createDirsCommand = directories
|
||||||
.map((dir) => `mkdir -p "${dir}"`)
|
.map((dir) => `mkdir -p "${dir}"`)
|
||||||
.join(" && ");
|
.join(" && ");
|
||||||
const chmodCommand = `chmod 700 "${SSH_PATH}"`;
|
const chmodCommand = `chmod 700 "${SSH_PATH}"`;
|
||||||
|
|
||||||
const command = `
|
const command = `
|
||||||
${createDirsCommand}
|
${createDirsCommand}
|
||||||
${chmodCommand}
|
${chmodCommand}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupMainDirectory = () => `
|
const setupMainDirectory = () => `
|
||||||
@@ -263,7 +263,7 @@ const setupMainDirectory = () => `
|
|||||||
# Create the /etc/dokploy directory
|
# Create the /etc/dokploy directory
|
||||||
mkdir -p /etc/dokploy
|
mkdir -p /etc/dokploy
|
||||||
chmod 777 /etc/dokploy
|
chmod 777 /etc/dokploy
|
||||||
|
|
||||||
echo "Directory /etc/dokploy created ✅"
|
echo "Directory /etc/dokploy created ✅"
|
||||||
fi
|
fi
|
||||||
`;
|
`;
|
||||||
@@ -276,16 +276,16 @@ export const setupSwarm = () => `
|
|||||||
# Get IP address
|
# Get IP address
|
||||||
get_ip() {
|
get_ip() {
|
||||||
local ip=""
|
local ip=""
|
||||||
|
|
||||||
# Try IPv4 with multiple services
|
# Try IPv4 with multiple services
|
||||||
# First attempt: ifconfig.io
|
# First attempt: ifconfig.io
|
||||||
ip=\$(curl -4s --connect-timeout 5 https://ifconfig.io 2>/dev/null)
|
ip=\$(curl -4s --connect-timeout 5 https://ifconfig.io 2>/dev/null)
|
||||||
|
|
||||||
# Second attempt: icanhazip.com
|
# Second attempt: icanhazip.com
|
||||||
if [ -z "\$ip" ]; then
|
if [ -z "\$ip" ]; then
|
||||||
ip=\$(curl -4s --connect-timeout 5 https://icanhazip.com 2>/dev/null)
|
ip=\$(curl -4s --connect-timeout 5 https://icanhazip.com 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Third attempt: ipecho.net
|
# Third attempt: ipecho.net
|
||||||
if [ -z "\$ip" ]; then
|
if [ -z "\$ip" ]; then
|
||||||
ip=\$(curl -4s --connect-timeout 5 https://ipecho.net/plain 2>/dev/null)
|
ip=\$(curl -4s --connect-timeout 5 https://ipecho.net/plain 2>/dev/null)
|
||||||
@@ -295,12 +295,12 @@ export const setupSwarm = () => `
|
|||||||
if [ -z "\$ip" ]; then
|
if [ -z "\$ip" ]; then
|
||||||
# Try IPv6 with ifconfig.io
|
# Try IPv6 with ifconfig.io
|
||||||
ip=\$(curl -6s --connect-timeout 5 https://ifconfig.io 2>/dev/null)
|
ip=\$(curl -6s --connect-timeout 5 https://ifconfig.io 2>/dev/null)
|
||||||
|
|
||||||
# Try IPv6 with icanhazip.com
|
# Try IPv6 with icanhazip.com
|
||||||
if [ -z "\$ip" ]; then
|
if [ -z "\$ip" ]; then
|
||||||
ip=\$(curl -6s --connect-timeout 5 https://icanhazip.com 2>/dev/null)
|
ip=\$(curl -6s --connect-timeout 5 https://icanhazip.com 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Try IPv6 with ipecho.net
|
# Try IPv6 with ipecho.net
|
||||||
if [ -z "\$ip" ]; then
|
if [ -z "\$ip" ]; then
|
||||||
ip=\$(curl -6s --connect-timeout 5 https://ipecho.net/plain 2>/dev/null)
|
ip=\$(curl -6s --connect-timeout 5 https://ipecho.net/plain 2>/dev/null)
|
||||||
@@ -502,9 +502,9 @@ fi
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const createTraefikConfig = () => {
|
const createTraefikConfig = () => {
|
||||||
const config = getDefaultServerTraefikConfig();
|
const config = getDefaultServerTraefikConfig();
|
||||||
|
|
||||||
const command = `
|
const command = `
|
||||||
if [ -f "/etc/dokploy/traefik/dynamic/acme.json" ]; then
|
if [ -f "/etc/dokploy/traefik/dynamic/acme.json" ]; then
|
||||||
chmod 600 "/etc/dokploy/traefik/dynamic/acme.json"
|
chmod 600 "/etc/dokploy/traefik/dynamic/acme.json"
|
||||||
fi
|
fi
|
||||||
@@ -515,19 +515,19 @@ const createTraefikConfig = () => {
|
|||||||
fi
|
fi
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
};
|
};
|
||||||
|
|
||||||
const createDefaultMiddlewares = () => {
|
const createDefaultMiddlewares = () => {
|
||||||
const config = getDefaultMiddlewares();
|
const config = getDefaultMiddlewares();
|
||||||
const command = `
|
const command = `
|
||||||
if [ -f "/etc/dokploy/traefik/dynamic/middlewares.yml" ]; then
|
if [ -f "/etc/dokploy/traefik/dynamic/middlewares.yml" ]; then
|
||||||
echo "Middlewares config already exists ✅"
|
echo "Middlewares config already exists ✅"
|
||||||
else
|
else
|
||||||
echo "${config}" > /etc/dokploy/traefik/dynamic/middlewares.yml
|
echo "${config}" > /etc/dokploy/traefik/dynamic/middlewares.yml
|
||||||
fi
|
fi
|
||||||
`;
|
`;
|
||||||
return command;
|
return command;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const installRClone = () => `
|
export const installRClone = () => `
|
||||||
@@ -541,7 +541,7 @@ export const installRClone = () => `
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const createTraefikInstance = () => {
|
export const createTraefikInstance = () => {
|
||||||
const command = `
|
const command = `
|
||||||
# Check if dokpyloy-traefik exists
|
# Check if dokpyloy-traefik exists
|
||||||
if docker service inspect dokploy-traefik > /dev/null 2>&1; then
|
if docker service inspect dokploy-traefik > /dev/null 2>&1; then
|
||||||
echo "Migrating Traefik to Standalone..."
|
echo "Migrating Traefik to Standalone..."
|
||||||
@@ -549,7 +549,7 @@ export const createTraefikInstance = () => {
|
|||||||
sleep 8
|
sleep 8
|
||||||
echo "Traefik migrated to Standalone ✅"
|
echo "Traefik migrated to Standalone ✅"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if docker inspect dokploy-traefik > /dev/null 2>&1; then
|
if docker inspect dokploy-traefik > /dev/null 2>&1; then
|
||||||
echo "Traefik already exists ✅"
|
echo "Traefik already exists ✅"
|
||||||
else
|
else
|
||||||
@@ -570,14 +570,14 @@ export const createTraefikInstance = () => {
|
|||||||
fi
|
fi
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
};
|
};
|
||||||
|
|
||||||
const installNixpacks = () => `
|
const installNixpacks = () => `
|
||||||
if command_exists nixpacks; then
|
if command_exists nixpacks; then
|
||||||
echo "Nixpacks already installed ✅"
|
echo "Nixpacks already installed ✅"
|
||||||
else
|
else
|
||||||
export NIXPACKS_VERSION=1.29.1
|
export NIXPACKS_VERSION=1.35.0
|
||||||
bash -c "$(curl -fsSL https://nixpacks.com/install.sh)"
|
bash -c "$(curl -fsSL https://nixpacks.com/install.sh)"
|
||||||
echo "Nixpacks version $NIXPACKS_VERSION installed ✅"
|
echo "Nixpacks version $NIXPACKS_VERSION installed ✅"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user