Dockerizing a Remotion app
We recommend the following structure for your Dockerfile. Read below about the individual steps and whether you need to adjust them.
DockerfiledockerFROM debian:bookwormRUN apt-get updateRUN apt-get install -y nodejs="18.13.0+dfsg1-1" npm="9.2.0~ds1-1" ffmpeg="7:5.1.2-3" chromium="111.0.5563.110-1"# Copy everything from your project to the Docker image. Adjust if needed.COPY package.json package*.json yarn.lock* pnpm-lock.yaml* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public# Specify the location of the Chromium browserENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium# Install the right package manager and dependencies - see below for Yarn/PNPMRUN npm i# Run your applicationCOPY render.mjs render.mjsCMD ["node", "render.mjs"]
DockerfiledockerFROM debian:bookwormRUN apt-get updateRUN apt-get install -y nodejs="18.13.0+dfsg1-1" npm="9.2.0~ds1-1" ffmpeg="7:5.1.2-3" chromium="111.0.5563.110-1"# Copy everything from your project to the Docker image. Adjust if needed.COPY package.json package*.json yarn.lock* pnpm-lock.yaml* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public# Specify the location of the Chromium browserENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium# Install the right package manager and dependencies - see below for Yarn/PNPMRUN npm i# Run your applicationCOPY render.mjs render.mjsCMD ["node", "render.mjs"]
Click here to see an example for a render.mjs script you can use.
This Dockerfile is unable to render WebGL content. Suggestions on how to improve the Dockerfile to support it are welcomed.
Line-by-line
dockerFROM debian:bookworm-20230320-slim
dockerFROM debian:bookworm-20230320-slim
dockerRUN apt-get update
dockerRUN apt-get update
dockerRUN apt-get install -y nodejs="18.13.0+dfsg1-1" npm="9.2.0~ds1-1" ffmpeg="7:5.1.2-3" chromium="111.0.5563.110-1"
dockerRUN apt-get install -y nodejs="18.13.0+dfsg1-1" npm="9.2.0~ds1-1" ffmpeg="7:5.1.2-3" chromium="111.0.5563.110-1"
COPY syntax allows multiple files, but at least one file must exist. It is assumed package.json, src and public exist in your project, but you can adjust this to your needs.
dockerCOPY package.json package*.json yarn.lock* pnpm-lock.yaml* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public
dockerCOPY package.json package*.json yarn.lock* pnpm-lock.yaml* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public
dockerENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
dockerENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
If you are on Remotion v3.3.81 or higher, you don't need this line.
If you use NPM, put the following in your Dockerfile:
dockerRUN npm idockerRUN npm iIf you use Yarn or PNPM, add the
packageManagerfield to yourpackage.json(example:"packageManager": "pnpm@7.7.1") and remove thenpmline from step 3. Then put following in your Dockerfile:If you use PNPMdockerRUN corepack enableRUN pnpm iIf you use PNPMdockerRUN corepack enableRUN pnpm iIf you use YarndockerRUN corepack enableRUN yarnIf you use YarndockerRUN corepack enableRUN yarn
dockerCOPY render.mjs render.mjsCMD ["node", "render.mjs"]
dockerCOPY render.mjs render.mjsCMD ["node", "render.mjs"]
Example render script
render.mjsjsimport { bundle } from "@remotion/bundler";import { getCompositions, renderMedia } from "@remotion/renderer";import { createRequire } from "node:module";const require = createRequire(import.meta.url);const bundled = await bundle({entryPoint: require.resolve("./src/index.ts"),// If you have a Webpack override, make sure to import it herewebpackOverride: (config) => config,});const compositions = await getCompositions(bundled);const composition = compositions[0];console.log("Starting to render composition", composition.id);await renderMedia({codec: "h264",composition,serveUrl: bundled,outputLocation: `out/${composition.id}.mp4`,});console.log(`Rendered composition ${composition.id}.`);
render.mjsjsimport { bundle } from "@remotion/bundler";import { getCompositions, renderMedia } from "@remotion/renderer";import { createRequire } from "node:module";const require = createRequire(import.meta.url);const bundled = await bundle({entryPoint: require.resolve("./src/index.ts"),// If you have a Webpack override, make sure to import it herewebpackOverride: (config) => config,});const compositions = await getCompositions(bundled);const composition = compositions[0];console.log("Starting to render composition", composition.id);await renderMedia({codec: "h264",composition,serveUrl: bundled,outputLocation: `out/${composition.id}.mp4`,});console.log(`Rendered composition ${composition.id}.`);
Building the Docker image
Run
shdocker build -t remotion-app .
shdocker build -t remotion-app .
to build a Docker image called remotion-app.
Use the following command to run the image:
shdocker run remotion-app
shdocker run remotion-app
Changelog
April 3rd, 2023: Changed the Alpine Docker image to a Debian one, since the versions of Alpine packages cannot be pinned. This makes the Debian one less likely to break.