Merge pull request #1402 from Dokploy/feat/add-railpack

feat(application): add Railpack as a new build type
This commit is contained in:
Mauricio Siu
2025-03-05 00:24:37 -06:00
committed by GitHub
13 changed files with 5290 additions and 2 deletions

View File

@@ -42,6 +42,7 @@ export const buildType = pgEnum("buildType", [
"paketo_buildpacks",
"nixpacks",
"static",
"railpack",
]);
export interface HealthCheckSwarm {
@@ -383,6 +384,7 @@ const createSchema = createInsertSchema(applications, {
"paketo_buildpacks",
"nixpacks",
"static",
"railpack",
]),
herokuVersion: z.string().optional(),
publishDirectory: z.string().optional(),

View File

@@ -170,6 +170,9 @@ ${installNixpacks()}
echo -e "12. Installing Buildpacks"
${installBuildpacks()}
echo -e "13. Installing Railpack"
${installRailpack()}
`;
return bashCommand;
@@ -573,6 +576,16 @@ const installNixpacks = () => `
fi
`;
const installRailpack = () => `
if command_exists railpack; then
echo "Railpack already installed ✅"
else
export RAILPACK_VERSION=0.0.37
bash -c "$(curl -fsSL https://railpack.com/install.sh)"
echo "Railpack version $RAILPACK_VERSION installed ✅"
fi
`;
const installBuildpacks = () => `
SUFFIX=""
if [ "$SYS_ARCH" = "aarch64" ] || [ "$SYS_ARCH" = "arm64" ]; then

View File

@@ -38,6 +38,18 @@ export const validateNixpacks = () => `
fi
`;
export const validateRailpack = () => `
if command_exists railpack; then
version=$(railpack --version | awk '{print $3}')
if [ -n "$version" ]; then
echo "$version true"
else
echo "0.0.0 false"
fi
else
echo "0.0.0 false"
fi
`;
export const validateBuildpacks = () => `
if command_exists pack; then
version=$(pack --version | awk '{print $1}')
@@ -86,7 +98,7 @@ export const serverValidate = async (serverId: string) => {
rcloneVersionEnabled=$(${validateRClone()})
nixpacksVersionEnabled=$(${validateNixpacks()})
buildpacksVersionEnabled=$(${validateBuildpacks()})
railpackVersionEnabled=$(${validateRailpack()})
dockerVersion=$(echo $dockerVersionEnabled | awk '{print $1}')
dockerEnabled=$(echo $dockerVersionEnabled | awk '{print $2}')
@@ -96,6 +108,9 @@ export const serverValidate = async (serverId: string) => {
nixpacksVersion=$(echo $nixpacksVersionEnabled | awk '{print $1}')
nixpacksEnabled=$(echo $nixpacksVersionEnabled | awk '{print $2}')
railpackVersion=$(echo $railpackVersionEnabled | awk '{print $1}')
railpackEnabled=$(echo $railpackVersionEnabled | awk '{print $2}')
buildpacksVersion=$(echo $buildpacksVersionEnabled | awk '{print $1}')
buildpacksEnabled=$(echo $buildpacksVersionEnabled | awk '{print $2}')
@@ -103,7 +118,7 @@ export const serverValidate = async (serverId: string) => {
isSwarmInstalled=$(${validateSwarm()})
isMainDirectoryInstalled=$(${validateMainDirectory()})
echo "{\\"docker\\": {\\"version\\": \\"$dockerVersion\\", \\"enabled\\": $dockerEnabled}, \\"rclone\\": {\\"version\\": \\"$rcloneVersion\\", \\"enabled\\": $rcloneEnabled}, \\"nixpacks\\": {\\"version\\": \\"$nixpacksVersion\\", \\"enabled\\": $nixpacksEnabled}, \\"buildpacks\\": {\\"version\\": \\"$buildpacksVersion\\", \\"enabled\\": $buildpacksEnabled}, \\"isDokployNetworkInstalled\\": $isDokployNetworkInstalled, \\"isSwarmInstalled\\": $isSwarmInstalled, \\"isMainDirectoryInstalled\\": $isMainDirectoryInstalled}"
echo "{\\"docker\\": {\\"version\\": \\"$dockerVersion\\", \\"enabled\\": $dockerEnabled}, \\"rclone\\": {\\"version\\": \\"$rcloneVersion\\", \\"enabled\\": $rcloneEnabled}, \\"nixpacks\\": {\\"version\\": \\"$nixpacksVersion\\", \\"enabled\\": $nixpacksEnabled}, \\"buildpacks\\": {\\"version\\": \\"$buildpacksVersion\\", \\"enabled\\": $buildpacksEnabled}, \\"railpack\\": {\\"version\\": \\"$railpackVersion\\", \\"enabled\\": $railpackEnabled}, \\"isDokployNetworkInstalled\\": $isDokployNetworkInstalled, \\"isSwarmInstalled\\": $isSwarmInstalled, \\"isMainDirectoryInstalled\\": $isMainDirectoryInstalled}"
`;
client.exec(bashCommand, (err, stream) => {
if (err) {

View File

@@ -16,6 +16,7 @@ import { buildCustomDocker, getDockerCommand } from "./docker-file";
import { buildHeroku, getHerokuCommand } from "./heroku";
import { buildNixpacks, getNixpacksCommand } from "./nixpacks";
import { buildPaketo, getPaketoCommand } from "./paketo";
import { buildRailpack, getRailpackCommand } from "./railpack";
import { buildStatic, getStaticCommand } from "./static";
// NIXPACKS codeDirectory = where is the path of the code directory
@@ -55,6 +56,8 @@ export const buildApplication = async (
await buildCustomDocker(application, writeStream);
} else if (buildType === "static") {
await buildStatic(application, writeStream);
} else if (buildType === "railpack") {
await buildRailpack(application, writeStream);
}
if (application.registryId) {
@@ -96,6 +99,9 @@ export const getBuildCommand = (
case "dockerfile":
command = getDockerCommand(application, logPath);
break;
case "railpack":
command = getRailpackCommand(application, logPath);
break;
}
if (registry) {
command += uploadImageRemoteCommand(application, logPath);

View File

@@ -0,0 +1,87 @@
import type { WriteStream } from "node:fs";
import type { ApplicationNested } from ".";
import { prepareEnvironmentVariables } from "../docker/utils";
import { getBuildAppDirectory } from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
import { execAsync } from "../process/execAsync";
export const buildRailpack = async (
application: ApplicationNested,
writeStream: WriteStream,
) => {
const { env, appName } = application;
const buildAppDirectory = getBuildAppDirectory(application);
const envVariables = prepareEnvironmentVariables(
env,
application.project.env,
);
try {
// Ensure buildkit container is running, create if it doesn't exist
await execAsync(
"docker container inspect buildkit >/dev/null 2>&1 || docker run --rm --privileged -d --name buildkit moby/buildkit",
);
// Build the application using railpack
const args = ["build", buildAppDirectory, "--name", appName];
// Add environment variables
for (const env of envVariables) {
args.push("--env", env);
}
await spawnAsync(
"railpack",
args,
(data) => {
if (writeStream.writable) {
writeStream.write(data);
}
},
{
env: {
...process.env,
BUILDKIT_HOST: "docker-container://buildkit",
},
},
);
return true;
} catch (e) {
throw e;
}
};
export const getRailpackCommand = (
application: ApplicationNested,
logPath: string,
) => {
const { env, appName } = application;
const buildAppDirectory = getBuildAppDirectory(application);
const envVariables = prepareEnvironmentVariables(
env,
application.project.env,
);
// Build the application using railpack
const args = ["build", buildAppDirectory, "--name", appName];
// Add environment variables
for (const env of envVariables) {
args.push("--env", env);
}
const command = `railpack ${args.join(" ")}`;
const bashCommand = `
echo "Building with Railpack..." >> "${logPath}";
docker container inspect buildkit >/dev/null 2>&1 || docker run --rm --privileged -d --name buildkit moby/buildkit;
export BUILDKIT_HOST=docker-container://buildkit;
${command} >> ${logPath} 2>> ${logPath} || {
echo "❌ Railpack build failed" >> ${logPath};
exit 1;
}
echo "✅ Railpack build completed." >> ${logPath};
`;
return bashCommand;
};