Skip to main content
Headless browsers work well on ECS, but three things differ from a laptop: there is no display, the container runs as a process that Chromium’s sandbox does not trust, and Chromium needs memory and shared-memory space that the defaults do not provide.

Install Chromium in the image

Puppeteer and Playwright download a browser at install time, but that browser needs system libraries a plain Node image lacks. The simplest route is the image each project publishes, which ships the browser and its dependencies pre-installed. Both are based on Ubuntu 24.04 (noble).
The image contains the browsers but not the playwright npm package — npm ci installs it. Pin the image tag to the exact Playwright version in package.json; a mismatch fails at launch because the package looks for a browser build the image does not have. See the Playwright Docker guide.

Launch options

Chromium’s sandbox relies on user namespaces that containers usually do not grant, and /dev/shm inside a Fargate task is 64 MB — too small for a real page. Disable both:
Headless is the default in current Puppeteer and Playwright, so there is nothing to set for it. Playwright takes the same flags via chromium.launch({ args: [...] }); on ECS you cannot use the --ipc=host alternative the Playwright docs suggest for /dev/shm, because Fargate does not support host IPC mode.
Only render content you trust with the sandbox disabled. A page that exploits Chromium gains the permissions of the task role. If you render untrusted pages, keep the sandbox on: run as the non-root user the official images provide (pwuser, pptruser) and give Chromium the SYS_ADMIN capability or a seccomp profile that allows user namespaces. Fargate permits neither, so put those tasks on EC2 capacity (capacity_provider: ec2).

Task sizing

  • Memory. Budget at least 1 GB per concurrent browser page plus your app. The default fargate_size of 2 vCPU / 4 GB handles a couple of pages; raise it before scaling out.
  • Ephemeral storage. Chromium writes profiles and caches to disk. If you screenshot or download at volume, increase task_ephemeral_storage_size_gib above the 20 GiB Fargate default.
  • Architecture. Chrome for Testing, the build Puppeteer downloads, has no Linux arm64 binaries, so a Puppeteer image built on it runs on X86_64 only. For cpu_architecture: ARM64 (Graviton) use the Playwright image, which is published for both architectures, or Debian’s chromium package.

Isolate browser work in a worker

Run the browser in a separate rvn-ecs-worker that pulls jobs from a queue, rather than in the web service. That keeps a crashed or leaked Chromium from taking down request handling, lets you scale renderers independently, and means the web service does not need the larger image or --no-sandbox at all.