mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(application): add Railpack as a new build type
- Introduce Railpack as a new build method for applications - Update database schema to include 'railpack' in buildType enum - Add Railpack installation and validation scripts for servers - Implement Railpack build and command generation utilities - Update UI to include Railpack as a build option with a 'New' badge
This commit is contained in:
parent
5db7508530
commit
5489e3b0a5
@ -138,11 +138,18 @@ curl -sSL https://nixpacks.com/install.sh -o install.sh \
|
||||
&& ./install.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
# Install Railpack
|
||||
curl -sSL https://railpack.com/install.sh | sh
|
||||
```
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Pull Request
|
||||
|
||||
- The `main` branch is the source of truth and should always reflect the latest stable release.
|
||||
|
@ -55,6 +55,10 @@ RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \
|
||||
&& ./install.sh \
|
||||
&& pnpm install -g tsx
|
||||
|
||||
# Install Railpack
|
||||
ARG RAILPACK_VERSION=0.0.37
|
||||
RUN curl -sSL https://railpack.com/install.sh | sh
|
||||
|
||||
# Install buildpacks
|
||||
COPY --from=buildpacksio/pack:0.35.0 /usr/local/bin/pack /usr/local/bin/pack
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
@ -25,6 +26,7 @@ enum BuildType {
|
||||
paketo_buildpacks = "paketo_buildpacks",
|
||||
nixpacks = "nixpacks",
|
||||
static = "static",
|
||||
railpack = "railpack",
|
||||
}
|
||||
|
||||
const mySchema = z.discriminatedUnion("buildType", [
|
||||
@ -53,6 +55,9 @@ const mySchema = z.discriminatedUnion("buildType", [
|
||||
z.object({
|
||||
buildType: z.literal("static"),
|
||||
}),
|
||||
z.object({
|
||||
buildType: z.literal("railpack"),
|
||||
}),
|
||||
]);
|
||||
|
||||
type AddTemplate = z.infer<typeof mySchema>;
|
||||
@ -173,6 +178,15 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
Dockerfile
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="railpack" />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
Railpack{" "}
|
||||
<Badge className="ml-1 text-xs px-1">New</Badge>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
<RadioGroupItem value="nixpacks" />
|
||||
|
@ -139,6 +139,15 @@ export const ValidateServer = ({ serverId }: Props) => {
|
||||
: "Not Created"
|
||||
}
|
||||
/>
|
||||
<StatusRow
|
||||
label="Railpack Installed"
|
||||
isEnabled={data?.railpack?.enabled}
|
||||
description={
|
||||
data?.railpack?.enabled
|
||||
? `Installed: ${data?.railpack?.version}`
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
1
apps/dokploy/drizzle/0069_legal_bill_hollister.sql
Normal file
1
apps/dokploy/drizzle/0069_legal_bill_hollister.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TYPE "public"."buildType" ADD VALUE 'railpack';
|
5119
apps/dokploy/drizzle/meta/0069_snapshot.json
Normal file
5119
apps/dokploy/drizzle/meta/0069_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -484,6 +484,13 @@
|
||||
"when": 1740897756774,
|
||||
"tag": "0068_complex_rhino",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 69,
|
||||
"version": "7",
|
||||
"when": 1741152916611,
|
||||
"tag": "0069_legal_bill_hollister",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
@ -206,6 +206,10 @@ export const serverRouter = createTRPCRouter({
|
||||
enabled: boolean;
|
||||
version: string;
|
||||
};
|
||||
railpack: {
|
||||
enabled: boolean;
|
||||
version: string;
|
||||
};
|
||||
isDokployNetworkInstalled: boolean;
|
||||
isSwarmInstalled: boolean;
|
||||
isMainDirectoryInstalled: boolean;
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
87
packages/server/src/utils/builders/railpack.ts
Normal file
87
packages/server/src/utils/builders/railpack.ts
Normal 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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user