diff --git a/packages/cli-v3/src/build/extensions.ts b/packages/cli-v3/src/build/extensions.ts index e38fe903d84..9ad544f128c 100644 --- a/packages/cli-v3/src/build/extensions.ts +++ b/packages/cli-v3/src/build/extensions.ts @@ -208,6 +208,10 @@ function applyLayerToManifest(layer: BuildLayer, manifest: BuildManifest): Build $manifest.image.pkgs = $manifest.image.pkgs.concat(layer.image.pkgs); $manifest.image.pkgs = Array.from(new Set($manifest.image.pkgs)); } + + if (layer.image.entrypointPrefix) { + $manifest.image.entrypointPrefix = [...layer.image.entrypointPrefix]; + } } if (layer.conditions) { diff --git a/packages/cli-v3/src/deploy/buildImage.ts b/packages/cli-v3/src/deploy/buildImage.ts index 2225d7db056..26247787dd6 100644 --- a/packages/cli-v3/src/deploy/buildImage.ts +++ b/packages/cli-v3/src/deploy/buildImage.ts @@ -727,14 +727,26 @@ const parseGenerateOptions = (options: GenerateContainerfileOptions) => { baseInstructions, buildArgs, buildEnvVars, + entrypointPrefix: options.image?.entrypointPrefix ?? [], packages, postInstallCommands, }; }; +function serializeEntrypoint(entrypointPrefix: string[], entrypoint: string) { + return JSON.stringify(["dumb-init", ...entrypointPrefix, "node", entrypoint]); +} + async function generateBunContainerfile(options: GenerateContainerfileOptions) { - const { baseImage, buildArgs, buildEnvVars, postInstallCommands, baseInstructions, packages } = - parseGenerateOptions(options); + const { + baseImage, + buildArgs, + buildEnvVars, + entrypointPrefix, + postInstallCommands, + baseInstructions, + packages, + } = parseGenerateOptions(options); return `# syntax=docker/dockerfile:1 # check=skip=SecretsUsedInArgOrEnv @@ -829,14 +841,21 @@ COPY --from=build --chown=bun:bun /app ./ # Copy the index.json file from the indexer stage COPY --from=indexer --chown=bun:bun /app/index.json ./ -ENTRYPOINT [ "dumb-init", "node", "${options.entrypoint}" ] +ENTRYPOINT ${serializeEntrypoint(entrypointPrefix, options.entrypoint)} CMD [] `; } async function generateNodeContainerfile(options: GenerateContainerfileOptions) { - const { baseImage, buildArgs, buildEnvVars, postInstallCommands, baseInstructions, packages } = - parseGenerateOptions(options); + const { + baseImage, + buildArgs, + buildEnvVars, + entrypointPrefix, + postInstallCommands, + baseInstructions, + packages, + } = parseGenerateOptions(options); return `# syntax=docker/dockerfile:1 # check=skip=SecretsUsedInArgOrEnv @@ -939,7 +958,7 @@ COPY --from=build --chown=node:node /app ./ # Copy the index.json file from the indexer stage COPY --from=indexer --chown=node:node /app/index.json ./ -ENTRYPOINT [ "dumb-init", "node", "${options.entrypoint}" ] +ENTRYPOINT ${serializeEntrypoint(entrypointPrefix, options.entrypoint)} CMD [] `; } diff --git a/packages/core/src/v3/build/extensions.ts b/packages/core/src/v3/build/extensions.ts index 3b809040eaa..341af08f80f 100644 --- a/packages/core/src/v3/build/extensions.ts +++ b/packages/core/src/v3/build/extensions.ts @@ -56,6 +56,7 @@ export interface BuildLayer { image?: { pkgs?: string[]; instructions?: string[]; + entrypointPrefix?: string[]; }; build?: { env?: Record; diff --git a/packages/core/src/v3/schemas/build.ts b/packages/core/src/v3/schemas/build.ts index 8eb97f0f358..eb0d5dd121f 100644 --- a/packages/core/src/v3/schemas/build.ts +++ b/packages/core/src/v3/schemas/build.ts @@ -60,6 +60,7 @@ export const BuildManifest = z.object({ .object({ pkgs: z.array(z.string()).optional(), instructions: z.array(z.string()).optional(), + entrypointPrefix: z.array(z.string()).optional(), }) .optional(), otelImportHook: z