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 node:20-bookwormRUN apt-get updateRUN apt-get install -y chromium# Copy everything from your project to the Docker image. Adjust if needed.COPY package.json package*.json yarn.lock* pnpm-lock.yaml* bun.lockb* tsconfig.json* remotion.config.* ./COPY src ./src# If you have a public folder:COPY public ./public# 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 node:20-bookwormRUN apt-get updateRUN apt-get install -y chromium# Copy everything from your project to the Docker image. Adjust if needed.COPY package.json package*.json yarn.lock* pnpm-lock.yaml* bun.lockb* tsconfig.json* remotion.config.* ./COPY src ./src# If you have a public folder:COPY public ./public# 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
dockerFROM debian:bookworm
dockerRUN apt-get update
dockerRUN apt-get update
dockerRUN apt-get install -y nodejs npm chromium
dockerRUN apt-get install -y nodejs npm chromium
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* bun.lockb* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public
dockerCOPY package.json package*.json yarn.lock* pnpm-lock.yaml* bun.lockb* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public
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
Assuming you want to render the composition MyComp:
render.mjstsximport {bundle } from "@remotion/bundler";import {renderMedia ,selectComposition } from "@remotion/renderer";import {createRequire } from "node:module";constrequire =createRequire (import.meta .url );constbundled = awaitbundle ({entryPoint :require .resolve ("./src/index.ts"),// If you have a Webpack override, make sure to import it herewebpackOverride : (config ) =>config ,});constcomposition = awaitselectComposition ({serveUrl :bundled ,id : "MyComp",});console .log ("Starting to render composition");awaitrenderMedia ({codec : "h264",composition ,serveUrl :bundled ,outputLocation : `out/${composition .id }.mp4`,chromiumOptions : {enableMultiProcessOnLinux : true,},});console .log (`Rendered composition ${composition .id }.`);
render.mjstsximport {bundle } from "@remotion/bundler";import {renderMedia ,selectComposition } from "@remotion/renderer";import {createRequire } from "node:module";constrequire =createRequire (import.meta .url );constbundled = awaitbundle ({entryPoint :require .resolve ("./src/index.ts"),// If you have a Webpack override, make sure to import it herewebpackOverride : (config ) =>config ,});constcomposition = awaitselectComposition ({serveUrl :bundled ,id : "MyComp",});console .log ("Starting to render composition");awaitrenderMedia ({codec : "h264",composition ,serveUrl :bundled ,outputLocation : `out/${composition .id }.mp4`,chromiumOptions : {enableMultiProcessOnLinux : true,},});console .log (`Rendered composition ${composition .id }.`);
We recommend setting the enableMultiProcessOnLinux option for this Docker image, available from v4.0.42. Read more
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
Emojis
No emojis are installed by default. If you want to use emojis, install an emoji font:
dockerRUN apt-get install fonts-noto-color-emoji
dockerRUN apt-get install fonts-noto-color-emoji
Japanese, Chinese, Korean, etc.
Those fonts may have limited Character support enabled by default. If you need full support, install the following fonts:
dockerRUN apt-get install fonts-noto-cjk
dockerRUN apt-get install fonts-noto-cjk
Why are the packages not pinned?
In Debian (and also Alpine), old packages are removed from the repositories once new versions are released. This means that pinning the versions will actually cause the Dockerfiles to break in the future. We choose Debian as the distribution because the packages get well tested before they get released into the repository.
Notes for older versions
If you are on a lower version than
v4.0.0, addffmpegto the list of packages to install:dockerRUN apt-get install -y nodejs ffmpeg npm chromiumdockerRUN apt-get install -y nodejs ffmpeg npm chromiumIf you are on Remotion
v3.3.80or lower, tell Remotion where Chrome is installed:dockerENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromiumdockerENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
Recommendation: Don't use Alpine Linux
Alpine Linux is a lightweight distribution often used in Docker. There are two known issues with it when used in conjunction with Remotion:
- The launch of the Rust parts of Remotion may be very slow (>10sec slowdown per render)
- If a new version of Chrome gets released in the registry, you might be unable to downgrade because old versions are not kept and breaking changes can not be ruled out.
Changelog
October 11th, 2023: Used the node:20-bookworm, which is faster to deploy and also Debian.
September 25th, 2023: Recommend setting enableMultiProcessOnLinux.
May 30th, 2023: Update document for Remotion 4.0.
April 15th, 2023: Unpinning the versions in Debian since it would cause breakage.
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.