Skip to content

Commit 53047ab

Browse files
authored
feat(deployments): external cache support for local builds (#2682)
* Add registry cache support for local builds * Add changeset
1 parent bb5cefa commit 53047ab

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

.changeset/funny-ligers-wonder.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
Added external cache support for local image builds

packages/cli-v3/src/commands/deploy.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const DeployCommandOptions = CommonCommandOptions.extend({
6464
envFile: z.string().optional(),
6565
// Local build options
6666
forceLocalBuild: z.boolean().optional(),
67+
useRegistryCache: z.boolean().default(false),
6768
network: z.enum(["default", "none", "host"]).optional(),
6869
push: z.boolean().optional(),
6970
builder: z.string().default("trigger"),
@@ -112,11 +113,19 @@ export function configureDeployCommand(program: Command) {
112113
"Skip promoting the deployment to the current deployment for the environment."
113114
)
114115
)
116+
.addOption(
117+
new CommandOption(
118+
"--use-registry-cache",
119+
"Use the registry cache when building the image. The registry must be supported as a cache storage backend."
120+
).hideHelp()
121+
)
115122
.addOption(
116123
new CommandOption(
117124
"--no-cache",
118125
"Do not use the cache when building the image. This will slow down the build process but can be useful if you are experiencing issues with the cache."
119-
).hideHelp()
126+
)
127+
.conflicts("useRegistryCache")
128+
.hideHelp()
120129
)
121130
.addOption(
122131
new CommandOption("--load", "Load the built image into your local docker").hideHelp()
@@ -418,6 +427,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
418427

419428
const buildResult = await buildImage({
420429
isLocalBuild,
430+
useRegistryCache: options.useRegistryCache,
421431
noCache: options.noCache,
422432
deploymentId: deployment.id,
423433
deploymentVersion: deployment.version,

packages/cli-v3/src/deploy/buildImage.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { CliApiClient } from "../apiClient.js";
1616
export interface BuildImageOptions {
1717
// Common options
1818
isLocalBuild: boolean;
19+
useRegistryCache?: boolean;
1920
imagePlatform: string;
2021
noCache?: boolean;
2122
load?: boolean;
@@ -53,6 +54,7 @@ export interface BuildImageOptions {
5354
export async function buildImage(options: BuildImageOptions): Promise<BuildImageResults> {
5455
const {
5556
isLocalBuild,
57+
useRegistryCache,
5658
imagePlatform,
5759
noCache,
5860
push,
@@ -94,6 +96,7 @@ export async function buildImage(options: BuildImageOptions): Promise<BuildImage
9496
authenticateToRegistry,
9597
load,
9698
noCache,
99+
useRegistryCache,
97100
extraCACerts,
98101
apiUrl,
99102
apiKey,
@@ -307,6 +310,7 @@ interface SelfHostedBuildImageOptions {
307310
apiClient: CliApiClient;
308311
branchName?: string;
309312
noCache?: boolean;
313+
useRegistryCache?: boolean;
310314
extraCACerts?: string;
311315
buildEnvVars?: Record<string, string | undefined>;
312316
network?: string;
@@ -316,7 +320,7 @@ interface SelfHostedBuildImageOptions {
316320
}
317321

318322
async function localBuildImage(options: SelfHostedBuildImageOptions): Promise<BuildImageResults> {
319-
const { builder, imageTag, deploymentId, apiClient } = options;
323+
const { builder, imageTag, deploymentId, apiClient, useRegistryCache } = options;
320324

321325
// Ensure multi-platform build is supported on the local machine
322326
let builderExists = false;
@@ -483,6 +487,8 @@ async function localBuildImage(options: SelfHostedBuildImageOptions): Promise<Bu
483487
options.onLog?.(`Successfully logged in to ${cloudRegistryHost}`);
484488
}
485489

490+
const projectCacheRef = getProjectCacheRefFromImageTag(imageTag);
491+
486492
const args = [
487493
"buildx",
488494
"build",
@@ -491,6 +497,14 @@ async function localBuildImage(options: SelfHostedBuildImageOptions): Promise<Bu
491497
"-f",
492498
"Containerfile",
493499
options.noCache ? "--no-cache" : undefined,
500+
...(useRegistryCache
501+
? [
502+
"--cache-to",
503+
`type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=${projectCacheRef}`,
504+
"--cache-from",
505+
`type=registry,ref=${projectCacheRef}`,
506+
]
507+
: []),
494508
"--platform",
495509
options.imagePlatform,
496510
options.network ? `--network=${options.network}` : undefined,
@@ -928,6 +942,11 @@ function extractRegistryHostFromImageTag(imageTag: string): string | undefined {
928942
return host;
929943
}
930944

945+
function getProjectCacheRefFromImageTag(imageTag: string): string {
946+
const lastColonIndex = imageTag.lastIndexOf(":");
947+
return `${imageTag.substring(0, lastColonIndex)}:cache`;
948+
}
949+
931950
async function getDockerUsernameAndPassword(
932951
apiClient: CliApiClient,
933952
deploymentId: string

0 commit comments

Comments
 (0)