fix(docker-context): add docker context path #284

This commit is contained in:
Mauricio Siu 2024-08-02 00:22:37 -06:00
parent 95ecf4fe21
commit abc6906349
8 changed files with 3099 additions and 25 deletions

View File

@ -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" && (

View File

@ -0,0 +1 @@
ALTER TABLE "application" ADD COLUMN "dockerContextPath" text;

File diff suppressed because it is too large Load Diff

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
} }
] ]
} }

View File

@ -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;

View File

@ -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 }));

View File

@ -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) {

View File

@ -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);
};