fix(docker): install system ffmpeg on Alpine, drop broken bundled binary
Video uploads on production fail with "missing ffmpeg" because the
backend container ships nothing usable for the video pipeline.
Two compounding causes:
1. **Alpine + glibc mismatch.** The npm `@ffmpeg-installer/ffmpeg`
dependency added with the video-support PR (commit 68a9dc5)
ships per-platform binaries via optionalDependencies. The Linux
binaries are built against glibc, but the backend image runs on
`node:22-alpine` (musl libc) — known to either fail to execute
or fail on shared-library lookups on Alpine.
2. **`ffprobe` missing entirely.** `@ffmpeg-installer/ffmpeg`
bundles only the `ffmpeg` binary. There's a separate
`@ffprobe-installer/ffprobe` package that the codebase never
depended on. But `videoProcessor.js:21` calls
`ffmpeg.ffprobe(videoPath, …)` — the very first step of the
video pipeline shells out to a `ffprobe` binary that doesn't
exist in the image. Even if (1) worked, every video upload
would 500 here.
The fix is to install Alpine's `ffmpeg` package via apk. It ships
both `ffmpeg` and `ffprobe` built natively against musl, ~70MB
extra image size, single line in the Dockerfile, no per-arch
handling needed (apk pulls the right binary for both linux/amd64
and linux/arm64 — works with the multi-arch infra from #349).
- `backend/Dockerfile`: add `ffmpeg` to the apk install line.
- `backend/Dockerfile.dev`: same for dev parity.
- `backend/src/services/videoProcessor.js`: remove the
`setFfmpegPath(require('@ffmpeg-installer/ffmpeg').path)` line
— without removing it, fluent-ffmpeg would prefer the broken
bundled binary over the working apk one. Letting fluent-ffmpeg
fall back to PATH lookup picks up the apk binary in the
container and the developer's locally-installed binary on dev
hosts (Homebrew on macOS, apt on Debian).
- `backend/package.json`: drop the now-unused
`@ffmpeg-installer/ffmpeg` dependency. `npm install` removes
2 packages from the lockfile.
Verified: `videoProcessor.js` still loads cleanly (`node -e
"require('./src/services/videoProcessor')"`); lint clean.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
|
||||
const path = require('path');
|
||||
const fs = require('fs').promises;
|
||||
const fsSync = require('fs');
|
||||
@@ -8,8 +7,12 @@ const crypto = require('crypto');
|
||||
const logger = require('../utils/logger');
|
||||
const { getStorage } = require('./storage');
|
||||
|
||||
// Set FFmpeg path
|
||||
ffmpeg.setFfmpegPath(ffmpegPath);
|
||||
// Use system ffmpeg/ffprobe (apk-installed in the Docker image, brew/apt on
|
||||
// dev hosts). The npm `@ffmpeg-installer/ffmpeg` binary is glibc-built and
|
||||
// (a) doesn't run reliably on Alpine and (b) only ships ffmpeg, not ffprobe
|
||||
// — but `ffmpeg.ffprobe()` below needs both. Letting fluent-ffmpeg fall
|
||||
// back to PATH lookup picks up the apk-installed binaries inside the
|
||||
// container and the developer's locally-installed ones outside it.
|
||||
|
||||
/**
|
||||
* Extract video metadata using FFmpeg
|
||||
|
||||
Reference in New Issue
Block a user