Install ffmpeg in the image that actually ships - #276
Merged
Merged
Conversation
Package B added ffmpeg to worker/Dockerfile. That image is only built when the worker runs as its own Railway service, and on this project it does not: the worker is colocated with the Next.js app and started by start.sh inside the container built from the ROOT Dockerfile, which railway.json names explicitly. So the binaries the renderer needs were installed into an image nobody builds, and every video render job would have died at the first ffmpeg spawn with the job row left `failed`. Nothing in CI could catch this — the test suite installs its own ffmpeg on the runner, and typechecks and unit tests say nothing about which Dockerfile Railway uses. Adds ffmpeg to the runtime stage of the root Dockerfile, next to the pandoc the worker already needed for the same reason. worker/Dockerfile keeps its copy so the separate-service deployment stays correct if it is ever used. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ThreatCrush Security Scan48 finding(s) HIGH/CRITICAL: 2 | MEDIUM: 31 | LOW: 15
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The render pipeline would have failed on every job in production. One line, but it's the difference between the feature working and every render dying at the first spawn.
What was wrong
Package B added ffmpeg to
worker/Dockerfile. That image is only built when the worker runs as its own Railway service — and on this project it doesn't. There is exactly one service (crawlproof.com); the worker is colocated with the Next.js app, launched bystart.shinside the container built from the rootDockerfile, whichrailway.jsonnames explicitly:That root image installs
pandoc tiniand no ffmpeg. So the binaries the renderer needs were installed into an image nobody builds, and everyad_video_jobsrow would have gone straight tofailedwith an ffmpeg spawn error.Why CI couldn't catch it
Nothing in the test suite or typechecks says anything about which Dockerfile Railway builds. The CI job installs its own ffmpeg on the runner (added in package B, and genuinely useful — it's what proves the encoder works), which makes the green check actively misleading here: the pipeline passes on a machine that has ffmpeg while shipping to one that doesn't.
The fix
Adds ffmpeg to the runtime stage of the root Dockerfile, next to the pandoc the worker already needed for the same reason.
worker/Dockerfilekeeps its copy so the separate-service deployment stays correct if it's ever used.Verified alongside this:
REDIS_URLis set on the service, so the BullMQ consumer will actually pick up queued jobs once the image ships;start.shruns the worker in-container; and the runtime stage already copieslib/,worker/,tsconfig.jsonandnode_modules, so the@/alias the render modules use resolves under tsx.No code change, no test change — this is purely the deployed image.