mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge pull request #400 from iksaku/feat/docker-build-stage
feat(docker): Multi-stage Builds
This commit is contained in:
@@ -10,6 +10,7 @@ const baseApp: ApplicationNested = {
|
||||
appName: "",
|
||||
autoDeploy: true,
|
||||
branch: null,
|
||||
dockerBuildStage: "",
|
||||
buildArgs: null,
|
||||
buildPath: "/",
|
||||
gitlabPathNamespace: "",
|
||||
|
||||
@@ -37,6 +37,7 @@ const mySchema = z.discriminatedUnion("buildType", [
|
||||
})
|
||||
.min(1, "Dockerfile required"),
|
||||
dockerContextPath: z.string().nullable().default(""),
|
||||
dockerBuildStage: z.string().nullable().default(""),
|
||||
}),
|
||||
z.object({
|
||||
buildType: z.literal("heroku_buildpacks"),
|
||||
@@ -86,6 +87,7 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
...(data.buildType && {
|
||||
dockerfile: data.dockerfile || "",
|
||||
dockerContextPath: data.dockerContextPath || "",
|
||||
dockerBuildStage: data.dockerBuildStage || "",
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
@@ -106,6 +108,8 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
|
||||
dockerContextPath:
|
||||
data.buildType === "dockerfile" ? data.dockerContextPath : null,
|
||||
dockerBuildStage:
|
||||
data.buildType === "dockerfile" ? data.dockerBuildStage : null,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Build type saved");
|
||||
@@ -241,6 +245,32 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="dockerBuildStage"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem>
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel>Docker Build Stage</FormLabel>
|
||||
<FormDescription>
|
||||
Allows you to target a specific stage in a
|
||||
Multi-stage Dockerfile. If empty, Docker defaults to
|
||||
build the last defined stage.
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={"E.g. production"}
|
||||
{...field}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
1
apps/dokploy/drizzle/0034_aspiring_secret_warriors.sql
Normal file
1
apps/dokploy/drizzle/0034_aspiring_secret_warriors.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "application" ADD COLUMN "dockerBuildStage" text;
|
||||
3545
apps/dokploy/drizzle/meta/0034_snapshot.json
Normal file
3545
apps/dokploy/drizzle/meta/0034_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -239,6 +239,13 @@
|
||||
"when": 1725250322137,
|
||||
"tag": "0033_white_hawkeye",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 34,
|
||||
"version": "6",
|
||||
"when": 1725256397019,
|
||||
"tag": "0034_aspiring_secret_warriors",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -195,6 +195,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
dockerfile: input.dockerfile,
|
||||
publishDirectory: input.publishDirectory,
|
||||
dockerContextPath: input.dockerContextPath,
|
||||
dockerBuildStage: input.dockerBuildStage,
|
||||
});
|
||||
|
||||
return true;
|
||||
|
||||
@@ -156,6 +156,7 @@ export const applications = pgTable("application", {
|
||||
),
|
||||
dockerfile: text("dockerfile"),
|
||||
dockerContextPath: text("dockerContextPath"),
|
||||
dockerBuildStage: text("dockerBuildStage"),
|
||||
// Drop
|
||||
dropBuildPath: text("dropBuildPath"),
|
||||
// Docker swarm json
|
||||
@@ -393,6 +394,7 @@ export const apiSaveBuildType = createSchema
|
||||
buildType: true,
|
||||
dockerfile: true,
|
||||
dockerContextPath: true,
|
||||
dockerBuildStage: true,
|
||||
})
|
||||
.required()
|
||||
.merge(createSchema.pick({ publishDirectory: true }));
|
||||
|
||||
@@ -12,7 +12,8 @@ export const buildCustomDocker = async (
|
||||
application: ApplicationNested,
|
||||
writeStream: WriteStream,
|
||||
) => {
|
||||
const { appName, env, publishDirectory, buildArgs } = application;
|
||||
const { appName, env, publishDirectory, buildArgs, dockerBuildStage } =
|
||||
application;
|
||||
const dockerFilePath = getBuildAppDirectory(application);
|
||||
try {
|
||||
const image = `${appName}`;
|
||||
@@ -25,6 +26,10 @@ export const buildCustomDocker = async (
|
||||
|
||||
const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."];
|
||||
|
||||
if (dockerBuildStage) {
|
||||
commandArgs.push("--target", dockerBuildStage);
|
||||
}
|
||||
|
||||
for (const arg of args) {
|
||||
commandArgs.push("--build-arg", arg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user