v3: fix prod worker node_modules permissions (#1008)

* set node user prior to npm install

* changeset

* add ffmpeg and ffprobe catalog entries
This commit is contained in:
nicktrn
2024-04-08 14:05:05 +01:00
committed by GitHub
parent 9be1557bb7
commit 624ddce32f
5 changed files with 325 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---
Fix permissions inside node_modules
+2
View File
@@ -12,6 +12,8 @@ WORKDIR /app
# copy all the files just in case anything is needed in postinstall
COPY --chown=node:node . .
USER node
RUN npm ci --no-fund --no-audit && npm cache clean --force
# Development or production stage builds upon the base stage
+177 -1
View File
@@ -3050,6 +3050,12 @@ importers:
references/v3-catalog:
dependencies:
'@ffmpeg-installer/ffmpeg':
specifier: ^1.1.0
version: 1.1.0
'@ffprobe-installer/ffprobe':
specifier: ^2.1.2
version: 2.1.2
'@opentelemetry/api':
specifier: ^1.8.0
version: 1.8.0
@@ -3065,6 +3071,9 @@ importers:
'@trigger.dev/sdk':
specifier: workspace:^3.0.0-beta.0
version: link:../../packages/trigger-sdk
execa:
specifier: ^8.0.1
version: 8.0.1
msw:
specifier: ^2.2.1
version: 2.2.1(typescript@5.3.3)
@@ -7297,6 +7306,161 @@ packages:
fast-json-stringify: 5.8.0
dev: true
/@ffmpeg-installer/darwin-arm64@4.1.5:
resolution: {integrity: sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/darwin-x64@4.1.0:
resolution: {integrity: sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/ffmpeg@1.1.0:
resolution: {integrity: sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==}
optionalDependencies:
'@ffmpeg-installer/darwin-arm64': 4.1.5
'@ffmpeg-installer/darwin-x64': 4.1.0
'@ffmpeg-installer/linux-arm': 4.1.3
'@ffmpeg-installer/linux-arm64': 4.1.4
'@ffmpeg-installer/linux-ia32': 4.1.0
'@ffmpeg-installer/linux-x64': 4.1.0
'@ffmpeg-installer/win32-ia32': 4.1.0
'@ffmpeg-installer/win32-x64': 4.1.0
dev: false
/@ffmpeg-installer/linux-arm64@4.1.4:
resolution: {integrity: sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/linux-arm@4.1.3:
resolution: {integrity: sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/linux-ia32@4.1.0:
resolution: {integrity: sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/linux-x64@4.1.0:
resolution: {integrity: sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/win32-ia32@4.1.0:
resolution: {integrity: sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@ffmpeg-installer/win32-x64@4.1.0:
resolution: {integrity: sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/darwin-arm64@5.0.1:
resolution: {integrity: sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/darwin-x64@5.1.0:
resolution: {integrity: sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/ffprobe@2.1.2:
resolution: {integrity: sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==}
engines: {node: '>=14.21.2'}
optionalDependencies:
'@ffprobe-installer/darwin-arm64': 5.0.1
'@ffprobe-installer/darwin-x64': 5.1.0
'@ffprobe-installer/linux-arm': 5.2.0
'@ffprobe-installer/linux-arm64': 5.2.0
'@ffprobe-installer/linux-ia32': 5.2.0
'@ffprobe-installer/linux-x64': 5.2.0
'@ffprobe-installer/win32-ia32': 5.1.0
'@ffprobe-installer/win32-x64': 5.1.0
dev: false
/@ffprobe-installer/linux-arm64@5.2.0:
resolution: {integrity: sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/linux-arm@5.2.0:
resolution: {integrity: sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/linux-ia32@5.2.0:
resolution: {integrity: sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/linux-x64@5.2.0:
resolution: {integrity: sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/win32-ia32@5.1.0:
resolution: {integrity: sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@ffprobe-installer/win32-x64@5.1.0:
resolution: {integrity: sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@floating-ui/core@0.7.3:
resolution: {integrity: sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==}
dev: false
@@ -17711,6 +17875,18 @@ packages:
dependencies:
ms: 2.1.2
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: false
/debug@4.3.4(supports-color@8.1.1):
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@@ -28765,7 +28941,7 @@ packages:
resolution: {integrity: sha512-OScOjQjrrjhAdFpQmnkE/qbIBGCRFhQB/YaJhcC3CPOlmhe7llnW46Ac1J5+EjcNXOTnDdpF96Erw/yedsGksQ==}
engines: {node: '>=8.6.0'}
dependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4
module-details-from-path: 1.0.3
resolve: 1.22.4
transitivePeerDependencies:
+3
View File
@@ -6,11 +6,14 @@
"dev:trigger": "triggerdev dev"
},
"dependencies": {
"@ffmpeg-installer/ffmpeg": "^1.1.0",
"@ffprobe-installer/ffprobe": "^2.1.2",
"@opentelemetry/api": "^1.8.0",
"@sindresorhus/slugify": "^2.2.1",
"@traceloop/instrumentation-openai": "^0.3.9",
"@trigger.dev/core": "workspace:^3.0.0-beta.0",
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
"execa": "^8.0.1",
"msw": "^2.2.1",
"openai": "^4.28.0",
"stripe": "^12.14.0",
+138 -1
View File
@@ -1,6 +1,10 @@
import { logger, task } from "@trigger.dev/sdk/v3";
import { chmod } from "node:fs/promises";
import { chmod, writeFile } from "node:fs/promises";
import { Readable } from "node:stream";
import { ReadableStream } from "stream/web";
import { basename } from "node:path";
import YTDlpWrap from "yt-dlp-wrap";
import ffmpeg from "@ffmpeg-installer/ffmpeg";
export const ytDlp = task({
id: "yt-dlp",
@@ -20,3 +24,136 @@ export const ytDlp = task({
logger.log("version", { version });
},
});
async function getFfprobe() {
const ffprobe = await import("@ffprobe-installer/ffprobe");
logger.log("ffprobeInstaller", ffprobe);
return ffprobe;
}
async function ffprobeVersion() {
const ffprobe = await getFfprobe();
const childProcess = await execute(ffprobe.path, ["-version"]);
logger.log("ffprobe -version", {
output: childProcess.stdout.split("\n")[0],
});
}
async function ffmpegVersion() {
logger.log("ffmpegInstaller", ffmpeg);
const childProcess = await execute(ffmpeg.path, ["-version"]);
logger.log("ffmpeg -version", {
output: childProcess.stdout.split("\n")[0],
});
}
export const ffprobeInstaller = task({
id: "ffprobe-installer",
run: async () => {
await ffprobeVersion();
},
});
export const ffmpegInstaller = task({
id: "ffmpeg-installer",
run: async () => {
await ffmpegVersion();
},
});
const videoUrl =
"https://upload.wikimedia.org/wikipedia/commons/0/07/Fractal-zoom-1-03-Mandelbrot_Buzzsaw.ogv";
const videoPath = "./video.ogv";
async function downloadVideo() {
logger.log("downloading video", { url: videoUrl });
const response = await fetch(videoUrl);
if (!response.body) {
throw new Error("No readable stream");
}
const readStream = Readable.fromWeb(response.body as ReadableStream);
await writeFile(videoPath, readStream);
logger.log("finished downloading", { outputPath: videoPath });
}
async function execute(file: string, args?: readonly string[]) {
const { execa } = await import("execa");
logger.log(`execute: ${basename(file)}`, { args });
const childProcess = await execa(file, args);
if (childProcess.exitCode !== 0) {
logger.error("Non-zero exit code", {
stderr: childProcess.stderr,
stdout: childProcess.stdout,
});
throw new Error("Non-zero exit code");
}
return childProcess;
}
async function probeVideo() {
const ffprobe = await getFfprobe();
const args = ["-hide_banner", "-print_format", "json", "-show_format", videoPath];
logger.log("probing video", { videoPath });
const childProcess = await execute(ffprobe.path, args);
logger.log("video info", {
output: JSON.parse(childProcess.stdout),
});
}
export const ffprobeInfo = task({
id: "ffprobe-info",
run: async () => {
await ffprobeVersion();
await downloadVideo();
await probeVideo();
},
});
async function convertVideo() {
const outputPath = "./video.webm";
logger.log("converting video", { input: videoPath, output: outputPath });
const childProcess = await execute(ffmpeg.path, [
"-hide_banner",
"-y", // overwrite output, don't prompt
"-i",
videoPath,
// seek to 25s
"-ss",
"25",
// stop after 5s
"-t",
"5",
outputPath,
]);
logger.log("video converted", {
input: videoPath,
output: outputPath,
stderr: childProcess.stderr,
stdout: childProcess.stdout,
});
}
export const ffmpegConvert = task({
id: "ffmpeg-convert",
run: async () => {
await ffmpegVersion();
await downloadVideo();
await convertVideo();
},
});