Merge pull request #310 from Dokploy/fix/docker-context

fix(docker-context): add docker context path #284
This commit is contained in:
Mauricio Siu
2024-08-02 09:52:27 -06:00
committed by GitHub
10 changed files with 3101 additions and 26 deletions
@@ -55,6 +55,7 @@ const baseApp: ApplicationNested = {
title: null, title: null,
updateConfigSwarm: null, updateConfigSwarm: null,
username: null, username: null,
dockerContextPath: null,
}; };
const baseDomain: Domain = { const baseDomain: Domain = {
@@ -36,6 +36,7 @@ const mySchema = z.discriminatedUnion("buildType", [
invalid_type_error: "Dockerfile path is required", invalid_type_error: "Dockerfile path is required",
}) })
.min(1, "Dockerfile required"), .min(1, "Dockerfile required"),
dockerContextPath: z.string().nullable(),
}), }),
z.object({ z.object({
buildType: z.literal("heroku_buildpacks"), buildType: z.literal("heroku_buildpacks"),
@@ -79,12 +80,12 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
const buildType = form.watch("buildType"); const buildType = form.watch("buildType");
useEffect(() => { useEffect(() => {
if (data) { if (data) {
// TODO: refactor this
if (data.buildType === "dockerfile") { if (data.buildType === "dockerfile") {
form.reset({ form.reset({
buildType: data.buildType, buildType: data.buildType,
...(data.buildType && { ...(data.buildType && {
dockerfile: data.dockerfile || "", dockerfile: data.dockerfile || "",
dockerContextPath: data.dockerContextPath || "",
}), }),
}); });
} else { } else {
@@ -103,6 +104,8 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
publishDirectory: publishDirectory:
data.buildType === "nixpacks" ? data.publishDirectory : null, data.buildType === "nixpacks" ? data.publishDirectory : null,
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null, dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
dockerContextPath:
data.buildType === "dockerfile" ? data.dockerContextPath : null,
}) })
.then(async () => { .then(async () => {
toast.success("Build type saved"); toast.success("Build type saved");
@@ -194,26 +197,51 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => {
}} }}
/> />
{buildType === "dockerfile" && ( {buildType === "dockerfile" && (
<FormField <>
control={form.control} <FormField
name="dockerfile" control={form.control}
render={({ field }) => { name="dockerfile"
return ( render={({ field }) => {
<FormItem> return (
<FormLabel>Docker File</FormLabel> <FormItem>
<FormControl> <FormLabel>Docker File</FormLabel>
<Input <FormControl>
placeholder={"Path of your docker file"} <Input
{...field} placeholder={"Path of your docker file"}
value={field.value ?? ""} {...field}
/> value={field.value ?? ""}
</FormControl> />
</FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
); );
}} }}
/> />
<FormField
control={form.control}
name="dockerContextPath"
render={({ field }) => {
return (
<FormItem>
<FormLabel>Docker Context Path</FormLabel>
<FormControl>
<Input
placeholder={
"Path of your docker context default: ."
}
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
</>
)} )}
{buildType === "nixpacks" && ( {buildType === "nixpacks" && (
@@ -114,7 +114,7 @@ export const SaveDockerProvider = ({ applicationId }: Props) => {
<FormItem> <FormItem>
<FormLabel>Password</FormLabel> <FormLabel>Password</FormLabel>
<FormControl> <FormControl>
<Input placeholder="Password" {...field} /> <Input placeholder="Password" {...field} type="password" />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@@ -0,0 +1 @@
ALTER TABLE "application" ADD COLUMN "dockerContextPath" text;
File diff suppressed because it is too large Load Diff
+7
View File
@@ -204,6 +204,13 @@
"when": 1722503439951, "when": 1722503439951,
"tag": "0028_jittery_eternity", "tag": "0028_jittery_eternity",
"breakpoints": true "breakpoints": true
},
{
"idx": 29,
"version": "6",
"when": 1722578386823,
"tag": "0029_colossal_zodiak",
"breakpoints": true
} }
] ]
} }
@@ -192,6 +192,7 @@ export const applicationRouter = createTRPCRouter({
buildType: input.buildType, buildType: input.buildType,
dockerfile: input.dockerfile, dockerfile: input.dockerfile,
publishDirectory: input.publishDirectory, publishDirectory: input.publishDirectory,
dockerContextPath: input.dockerContextPath,
}); });
return true; return true;
@@ -141,6 +141,7 @@ export const applications = pgTable("application", {
}, },
), ),
dockerfile: text("dockerfile"), dockerfile: text("dockerfile"),
dockerContextPath: text("dockerContextPath"),
// Drop // Drop
dropBuildPath: text("dropBuildPath"), dropBuildPath: text("dropBuildPath"),
// Docker swarm json // Docker swarm json
@@ -356,6 +357,7 @@ export const apiSaveBuildType = createSchema
applicationId: true, applicationId: true,
buildType: true, buildType: true,
dockerfile: true, dockerfile: true,
dockerContextPath: true,
}) })
.required() .required()
.merge(createSchema.pick({ publishDirectory: true })); .merge(createSchema.pick({ publishDirectory: true }));
@@ -1,7 +1,10 @@
import type { WriteStream } from "node:fs"; import type { WriteStream } from "node:fs";
import { prepareEnvironmentVariables } from "@/server/utils/docker/utils"; import { prepareEnvironmentVariables } from "@/server/utils/docker/utils";
import type { ApplicationNested } from "."; import type { ApplicationNested } from ".";
import { getBuildAppDirectory } from "../filesystem/directory"; import {
getBuildAppDirectory,
getDockerContextPath,
} from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync"; import { spawnAsync } from "../process/spawnAsync";
import { createEnvFile } from "./utils"; import { createEnvFile } from "./utils";
@@ -14,21 +17,21 @@ export const buildCustomDocker = async (
try { try {
const image = `${appName}`; const image = `${appName}`;
const contextPath = const defaultContextPath =
dockerFilePath.substring(0, dockerFilePath.lastIndexOf("/") + 1) || "."; dockerFilePath.substring(0, dockerFilePath.lastIndexOf("/") + 1) || ".";
const args = prepareEnvironmentVariables(buildArgs); const args = prepareEnvironmentVariables(buildArgs);
const dockerContextPath = getDockerContextPath(application);
const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."]; const commandArgs = ["build", "-t", image, "-f", dockerFilePath, "."];
for (const arg of args) { for (const arg of args) {
commandArgs.push("--build-arg", arg); commandArgs.push("--build-arg", arg);
} }
/* /*
Do not generate an environment file when publishDirectory is specified, Do not generate an environment file when publishDirectory is specified,
as it could be publicly exposed. as it could be publicly exposed.
*/ */
if (!publishDirectory) { if (!publishDirectory) {
createEnvFile(dockerFilePath, env); createEnvFile(dockerFilePath, env);
} }
@@ -42,7 +45,7 @@ export const buildCustomDocker = async (
} }
}, },
{ {
cwd: contextPath, cwd: dockerContextPath || defaultContextPath,
}, },
); );
} catch (error) { } catch (error) {
@@ -89,3 +89,12 @@ export const getBuildAppDirectory = (application: Application) => {
return path.join(APPLICATIONS_PATH, appName, "code", buildPath ?? ""); return path.join(APPLICATIONS_PATH, appName, "code", buildPath ?? "");
}; };
export const getDockerContextPath = (application: Application) => {
const { appName, dockerContextPath } = application;
if (!dockerContextPath) {
return null;
}
return path.join(APPLICATIONS_PATH, appName, "code", dockerContextPath);
};