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: "",
|
appName: "",
|
||||||
autoDeploy: true,
|
autoDeploy: true,
|
||||||
branch: null,
|
branch: null,
|
||||||
|
dockerBuildStage: "",
|
||||||
buildArgs: null,
|
buildArgs: null,
|
||||||
buildPath: "/",
|
buildPath: "/",
|
||||||
gitlabPathNamespace: "",
|
gitlabPathNamespace: "",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const mySchema = z.discriminatedUnion("buildType", [
|
|||||||
})
|
})
|
||||||
.min(1, "Dockerfile required"),
|
.min(1, "Dockerfile required"),
|
||||||
dockerContextPath: z.string().nullable().default(""),
|
dockerContextPath: z.string().nullable().default(""),
|
||||||
|
dockerBuildStage: z.string().nullable().default(""),
|
||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
buildType: z.literal("heroku_buildpacks"),
|
buildType: z.literal("heroku_buildpacks"),
|
||||||
@@ -86,6 +87,7 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
|||||||
...(data.buildType && {
|
...(data.buildType && {
|
||||||
dockerfile: data.dockerfile || "",
|
dockerfile: data.dockerfile || "",
|
||||||
dockerContextPath: data.dockerContextPath || "",
|
dockerContextPath: data.dockerContextPath || "",
|
||||||
|
dockerBuildStage: data.dockerBuildStage || "",
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -106,6 +108,8 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
|
|||||||
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
|
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
|
||||||
dockerContextPath:
|
dockerContextPath:
|
||||||
data.buildType === "dockerfile" ? data.dockerContextPath : null,
|
data.buildType === "dockerfile" ? data.dockerContextPath : null,
|
||||||
|
dockerBuildStage:
|
||||||
|
data.buildType === "dockerfile" ? data.dockerBuildStage : null,
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
toast.success("Build type saved");
|
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,
|
"when": 1725250322137,
|
||||||
"tag": "0033_white_hawkeye",
|
"tag": "0033_white_hawkeye",
|
||||||
"breakpoints": true
|
"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,
|
dockerfile: input.dockerfile,
|
||||||
publishDirectory: input.publishDirectory,
|
publishDirectory: input.publishDirectory,
|
||||||
dockerContextPath: input.dockerContextPath,
|
dockerContextPath: input.dockerContextPath,
|
||||||
|
dockerBuildStage: input.dockerBuildStage,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ export const applications = pgTable("application", {
|
|||||||
),
|
),
|
||||||
dockerfile: text("dockerfile"),
|
dockerfile: text("dockerfile"),
|
||||||
dockerContextPath: text("dockerContextPath"),
|
dockerContextPath: text("dockerContextPath"),
|
||||||
|
dockerBuildStage: text("dockerBuildStage"),
|
||||||
// Drop
|
// Drop
|
||||||
dropBuildPath: text("dropBuildPath"),
|
dropBuildPath: text("dropBuildPath"),
|
||||||
// Docker swarm json
|
// Docker swarm json
|
||||||
@@ -393,6 +394,7 @@ export const apiSaveBuildType = createSchema
|
|||||||
buildType: true,
|
buildType: true,
|
||||||
dockerfile: true,
|
dockerfile: true,
|
||||||
dockerContextPath: true,
|
dockerContextPath: true,
|
||||||
|
dockerBuildStage: true,
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
.merge(createSchema.pick({ publishDirectory: true }));
|
.merge(createSchema.pick({ publishDirectory: true }));
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ export const buildCustomDocker = async (
|
|||||||
application: ApplicationNested,
|
application: ApplicationNested,
|
||||||
writeStream: WriteStream,
|
writeStream: WriteStream,
|
||||||
) => {
|
) => {
|
||||||
const { appName, env, publishDirectory, buildArgs } = application;
|
const { appName, env, publishDirectory, buildArgs, dockerBuildStage } =
|
||||||
|
application;
|
||||||
const dockerFilePath = getBuildAppDirectory(application);
|
const dockerFilePath = getBuildAppDirectory(application);
|
||||||
try {
|
try {
|
||||||
const image = `${appName}`;
|
const image = `${appName}`;
|
||||||
@@ -25,6 +26,10 @@ export const buildCustomDocker = async (
|
|||||||
|
|
||||||
const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."];
|
const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."];
|
||||||
|
|
||||||
|
if (dockerBuildStage) {
|
||||||
|
commandArgs.push("--target", dockerBuildStage);
|
||||||
|
}
|
||||||
|
|
||||||
for (const arg of args) {
|
for (const arg of args) {
|
||||||
commandArgs.push("--build-arg", arg);
|
commandArgs.push("--build-arg", arg);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user