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.
Dockerfiledocker
FROM 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"]
Dockerfiledocker
FROM 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
docker
FROM debian:bookworm-20230320-slim
docker
FROM debian:bookworm-20230320-slim
docker
RUN apt-get update
docker
RUN apt-get update
docker
RUN 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"
docker
RUN 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.
docker
COPY package.json package*.json yarn.lock* pnpm-lock.yaml* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public
docker
COPY package.json package*.json yarn.lock* pnpm-lock.yaml* tsconfig.json* remotion.config.* ./COPY src ./srcCOPY public ./public
docker
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
docker
ENV 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
packageManager
field to yourpackage.json
(example:"packageManager": "pnpm@7.7.1"
) and remove thenpm
line 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
docker
COPY render.mjs render.mjsCMD ["node", "render.mjs"]
docker
COPY render.mjs render.mjsCMD ["node", "render.mjs"]
Example render script
render.mjsjs
import { 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.mjsjs
import { 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
sh
docker build -t remotion-app .
sh
docker build -t remotion-app .
to build a Docker image called remotion-app
.
Use the following command to run the image:
sh
docker run remotion-app
sh
docker 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.