Skip to content

Commit 1207efb

Browse files
authored
v3: prod image upgrade and fixes (#1003)
* fix shutdown after final attempt * fix workdir permissions * correctly handle self-hosted deploy errors * switch to node:20-bookworm-slim * add binaries catalog file * changeset * skip recommended packages * post start hook retries * comment and improve lifecycle retry
1 parent 7ea8532 commit 1207efb

File tree

9 files changed

+67
-14
lines changed

9 files changed

+67
-14
lines changed

.changeset/light-dragons-complain.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+
Correctly handle self-hosted deploy command errors

apps/kubernetes-provider/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,11 @@ class KubernetesTaskOperations implements TaskOperations {
404404
type: THookType,
405405
cause: THookType extends "postStart" ? PostStartCauses : PreStopCauses
406406
) {
407-
return ["/bin/sh", "-c", `sleep 1; wget -q -O- 127.0.0.1:8000/${type}?cause=${cause}`];
407+
const retries = 5
408+
409+
// This will retry sending the lifecycle hook up to `retries` times
410+
// The sleep is required as this may start running before the HTTP server is up
411+
return ["/bin/sh", "-c", `for i in $(seq ${retries}); do sleep 1; wget -q -O- 127.0.0.1:8000/${type}?cause=${cause} && break; done`];
408412
}
409413

410414
#getIndexContainerName(suffix: string) {

packages/cli-v3/src/Containerfile.prod

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
FROM node:20-alpine@sha256:bf77dc26e48ea95fca9d1aceb5acfa69d2e546b765ec2abfb502975f1a2d4def AS base
1+
FROM node:20-bookworm-slim@sha256:d4cdfc305abe5ea78da7167bf78263c22596dc332f2654b662890777ea166224 AS base
22

3-
RUN apk add --no-cache dumb-init
3+
ENV DEBIAN_FRONTEND=noninteractive
4+
RUN apt-get update && apt-get install -y --no-install-recommends dumb-init && rm -rf /var/lib/apt/lists/*
45

6+
# Create and set workdir with appropriate permissions
7+
RUN mkdir /app && chown node:node /app
58
WORKDIR /app
69

710
# copy all the files just in case anything is needed in postinstall

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ async function buildAndPushSelfHostedImage(
792792
let digest: string | undefined;
793793

794794
try {
795-
await new Promise<void>((res, rej) => {
795+
const processCode = await new Promise<number | null>((res, rej) => {
796796
// For some reason everything is output on stderr, not stdout
797797
buildProcess.stderr?.on("data", (data: Buffer) => {
798798
const text = data.toString();
@@ -802,9 +802,17 @@ async function buildAndPushSelfHostedImage(
802802
});
803803

804804
buildProcess.on("error", (e) => rej(e));
805-
buildProcess.on("close", () => res());
805+
buildProcess.on("close", (code) => res(code));
806806
});
807807

808+
if (processCode !== 0) {
809+
return {
810+
ok: false as const,
811+
error: "Error building image",
812+
logs: extractLogs(errors),
813+
};
814+
}
815+
808816
digest = extractImageDigest(errors);
809817

810818
span.setAttributes({
@@ -835,7 +843,7 @@ async function buildAndPushSelfHostedImage(
835843
});
836844

837845
try {
838-
await new Promise<void>((res, rej) => {
846+
const processCode = await new Promise<number | null>((res, rej) => {
839847
pushProcess.stdout?.on("data", (data: Buffer) => {
840848
const text = data.toString();
841849

@@ -849,9 +857,17 @@ async function buildAndPushSelfHostedImage(
849857
});
850858

851859
pushProcess.on("error", (e) => rej(e));
852-
pushProcess.on("close", () => res());
860+
pushProcess.on("close", (code) => res(code));
853861
});
854862

863+
if (processCode !== 0) {
864+
return {
865+
ok: false as const,
866+
error: "Error pushing image",
867+
logs: extractLogs(errors),
868+
};
869+
}
870+
855871
span.end();
856872
} catch (e) {
857873
recordSpanException(span, e);

packages/cli-v3/src/workers/prod/backgroundWorker.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,6 @@ export class ProdBackgroundWorker {
267267

268268
const result = await taskRunProcess.executeTaskRun(payload);
269269

270-
// Kill the worker if the task was successful or if it's not going to be retried);
271-
await taskRunProcess.cleanup(result.ok || result.retry === undefined);
272-
273270
if (result.ok) {
274271
return result;
275272
}

packages/cli-v3/src/workers/prod/entry-point.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,6 @@ class ProdWorker {
358358

359359
this.completed.add(executionPayload.execution.attempt.id);
360360

361-
await this.#backgroundWorker.flushTelemetry();
362-
363361
const { willCheckpointAndRestore, shouldExit } =
364362
await this.#coordinatorSocket.socket.emitWithAck("TASK_RUN_COMPLETED", {
365363
version: "v1",

pnpm-lock.yaml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

references/v3-catalog/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
"@opentelemetry/api": "^1.8.0",
1010
"@sindresorhus/slugify": "^2.2.1",
1111
"@traceloop/instrumentation-openai": "^0.3.9",
12-
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
1312
"@trigger.dev/core": "workspace:^3.0.0-beta.0",
13+
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
1414
"msw": "^2.2.1",
1515
"openai": "^4.28.0",
16-
"stripe": "^12.14.0"
16+
"stripe": "^12.14.0",
17+
"yt-dlp-wrap": "^2.3.12"
1718
},
1819
"devDependencies": {
1920
"@trigger.dev/tsconfig": "workspace:*",
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { logger, task } from "@trigger.dev/sdk/v3";
2+
import { chmod } from "node:fs/promises";
3+
import YTDlpWrap from "yt-dlp-wrap";
4+
5+
export const ytDlp = task({
6+
id: "yt-dlp",
7+
run: async () => {
8+
const releaseArtifact = "yt-dlp_linux";
9+
const filePath = `./${releaseArtifact}`;
10+
const fileURL = `https://github.com/yt-dlp/yt-dlp/releases/latest/download/${releaseArtifact}`;
11+
12+
await YTDlpWrap.downloadFile(fileURL, filePath);
13+
await chmod(filePath, "777");
14+
15+
logger.log("downloaded", { filePath, fileURL });
16+
17+
const ytDlpWrap = new YTDlpWrap(filePath);
18+
const version = await ytDlpWrap.getVersion();
19+
20+
logger.log("version", { version });
21+
},
22+
});

0 commit comments

Comments
 (0)