Files

73 lines
2.8 KiB
Docker
Raw Permalink Normal View History

# video-renderer sidecar — untars a motion/ composition source, renders one
# MP4 cut with HyperFrames, and streams the bytes back.
#
# Debian (not Alpine): musl slows renders past 10s and has known Chrome
# Headless Shell compatibility issues (verified against upstream
# headless-Chrome Docker guidance). HyperFrames' @hyperframes/producer
# encodes via a system ffmpeg binary — unlike @remotion/renderer (which
# bundled ffmpeg), the producer shells out to ffmpeg on PATH, so install
# it here.
#
# Build context is the project root, like every other service under
# docker/ — paths below are relative to the repo root.
FROM node:22-bookworm-slim
# Chrome/Puppeteer runtime libraries — the documented Debian dependency
# list for headless rendering (per Puppeteer/Chrome guidance). A missing
# one surfaces as an opaque Puppeteer "Target closed" crash, not a clear
# missing-library error.
# ffmpeg: required by @hyperframes/producer's local render mode — see top
# comment; without it renders fail with "FFmpeg not found".
RUN apt-get update && apt-get install -y --no-install-recommends \
libnss3 \
libdbus-1-3 \
libatk1.0-0 \
libgbm-dev \
libasound2 \
libxrandr2 \
libxkbcommon-dev \
libxfixes3 \
libxcomposite1 \
libxdamage1 \
libatk-bridge2.0-0 \
libpango-1.0-0 \
libcairo2 \
libcups2 \
ffmpeg \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Activate the exact version video-renderer/package.json pins
# (packageManager: pnpm@11.10.0) rather than trusting corepack's bundled
# default — a future node:22-alpine shipping a different pnpm would silently
# change the build's package manager.
RUN corepack enable pnpm && corepack prepare pnpm@11.10.0 --activate
WORKDIR /app
# pnpm 11 prompts for confirmation on modules-purge unless told this is CI
# (same gotcha as docker/panel.Dockerfile).
ENV CI=true
# Install dependencies first (layer caching). Unlike the panel image, every
# dependency here runs at request time — createRenderJob()/executeRenderJob()
# execute live per /render call — so there's no separate build output to discard
# and no multi-stage split.
# pnpm-workspace.yaml carries the `allowBuilds: esbuild: true` approval —
# without it pnpm 11 hard-errors with [ERR_PNPM_IGNORED_BUILDS] (exit 1)
# because esbuild's postinstall is unapproved, breaking the image build.
COPY video-renderer/package.json video-renderer/pnpm-lock.yaml video-renderer/pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
# Pre-warm Chrome Headless Shell at build time so the container's first
# real render isn't also the first time it downloads a browser.
COPY video-renderer/ensure-browser.mjs ./
RUN node ensure-browser.mjs
COPY video-renderer/server.js video-renderer/render.js ./
EXPOSE 3001
ENV PORT=3001
CMD ["node", "server.js"]