Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.
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.
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.
The image includes Chrome for Testing, the matching puppeteer version, and runs as
pptruser. Pin the tag to the Puppeteer version in package.json. See the
Puppeteer Docker guide.If you build on a plain Node image instead, note that npm 11, pnpm, Yarn, and Bun block
dependency install scripts by default, so Puppeteer’s browser download does not run on
npm ci. Run npx puppeteer browsers install chrome as an explicit build step, and install
the system libraries Chrome needs.
Use Debian’s chromium package with puppeteer-core (or puppeteer with the download
skipped) when you need an arm64 image or a smaller one. The package pulls in every library
Chromium needs, and there is no second browser download during the build. You get Debian’s
Chromium release cadence rather than the version Puppeteer was tested against.
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).
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.
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.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Ravion Docs","description":"Fast, powerful building blocks for CI/CD pipelines, deploys, and Terraform automation. An open module system and one canvas connect them for your team and agents, in your own cloud.","colors":{"primary":"#FE6104","light":"#FE6104","dark":"#F6DDCE"},"logo":{"light":"https://mintcdn.com/ravion-b90c0359/flJhuOPF2oqAa_dG/logo/light.svg?fit=max\u0026auto=format\u0026n=flJhuOPF2oqAa_dG\u0026q=85\u0026s=1f2e6cab050d18d564cdeb5f723e684d","dark":"https://mintcdn.com/ravion-b90c0359/flJhuOPF2oqAa_dG/logo/dark.svg?fit=max\u0026auto=format\u0026n=flJhuOPF2oqAa_dG\u0026q=85\u0026s=c9ebae6d3a290cf6ee644bb63dcf4b3e","href":"https://www.ravion.com"},"favicon":"https://mintcdn.com/ravion-b90c0359/zFu0q6w3B8mEcsTw/favicon.png?fit=max\u0026auto=format\u0026n=zFu0q6w3B8mEcsTw\u0026q=85\u0026s=b7e9559b318054140788c5c4f83a5739","background":{"color":{"dark":"#0F0004"}},"navbar":{"links":[{"href":"https://app.ravion.com/signup","label":"Start free trial"},{"href":"https://cal.com/team/ravion/demo","label":"Book a demo"},{"href":"https://discord.gg/hJyRfg4nNa","label":"Discord","type":"discord"}]},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/ravionhq","x":"https://x.com/ravion"}},"fonts":{"heading":{"family":"PP Fragment","weight":400,"source":"docs/fonts/PPFragment-GlareRegular.woff2","format":"woff2"},"body":{"family":"PP Neue Montreal","weight":450,"source":"docs/fonts/PPNeueMontreal-Variable.woff2","format":"woff2"}},"integrations":{"fathom":{"siteId":"GMFTPQUB"},"ga4":{"measurementId":"G-9F3ZH30W5Y"},"posthog":{"apiKey":"phc_knvqBBWDUykLHBQFmz9spqtcuvWnkupHeVcxqFF2K977","apiHost":"https://api.ravion.com/i"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"ravion-b90c0359","hasAudioNarration":false,"actualSubdomain":"ravion-b90c0359","customDomains":["www.ravion.com"],"gitSource":{"type":"github","owner":"ravionhq","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"feedback":{"edits":true,"issues":true,"thumbs":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"}},"buildId":"6af11428c675d3fb0a41f0e6","clientVersion":"0.0.4088","searchFilterCounts":[{"language":"default","tag":"API reference","count":547},{"language":"default","tag":"Documentation","count":117},{"language":"default","tag":"Modules","count":48},{"language":"default","tag":"CLI","count":42},{"language":"default","tag":"Standard library","count":40},{"language":"default","tag":"Command reference","count":38},{"language":"default","tag":"Deploy to AWS","count":27},{"language":"default","tag":"Frameworks","count":27},{"language":"default","tag":"Pipelines","count":23},{"language":"default","tag":"ExecutionEnvironments","count":19}],"searchSettings":{"maxResults":15}},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true,"deflection":{"enabled":true,"email":"support@ravion.com"}},"basePath":"/docs","hasChatPermissions":true,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"custom.css","content":"/* latin-ext */\n@font-face {\n font-family: 'DM Mono';\n font-style: italic;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/dmmono/v16/aFTW7PB1QTsUX8KYth-gCKSIUKw.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'DM Mono';\n font-style: italic;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/dmmono/v16/aFTW7PB1QTsUX8KYth-gBqSI.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n/* latin-ext */\n@font-face {\n font-family: 'DM Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/dmmono/v16/aFTU7PB1QTsUX8KYthSQBLyM.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'DM Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/dmmono/v16/aFTU7PB1QTsUX8KYthqQBA.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n@font-face{font-family:\"PP Neue Montreal\";src:url(\"/docs/fonts/PPNeueMontreal-Variable.woff2\") format(\"woff2\");font-weight:100 900;font-style:normal;font-display:swap}:root{--font-mono:\n \"DM Mono\", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace;--radius-interactive-element: 0.125rem;--radius-sm: 0.125rem;--radius-text-highlight: 0.125rem;--radius-md: 0.125rem;--radius-menus: 0.125rem;--radius-lg: 0.125rem;--radius-xl: 0.125rem;--radius-full: 9999px;--rounded-sm: 0.125rem;--rounded: 0.125rem;--rounded-md: 0.125rem;--rounded-lg: 0.125rem;--rounded-xl: 0.125rem;--rounded-2xl: 0.125rem;--rounded-3xl: 0.125rem;--border-radius: 0.125rem;font-size:17px}:where([class*=\"rounded\"]:not(.rounded-none):not(.rounded-full):not([class*=\"rounded-full\"])){border-radius:0.125rem!important}.rounded-full,[class*=\"rounded-full\"]{border-radius:var(--radius-full)!important}[data-radix-menu-content],[data-radix-dropdown-menu-content],[role=\"menu\"][data-side],[data-component-part=\"search-modal\"],[data-component-part=\"search-header\"],[data-component-part=\"search-list\"]{border-radius:0.125rem!important}:is(.dark,[data-theme=\"dark\"]) [data-component-part=\"search-modal\"]{box-shadow:0 0 0 100vmax rgb(0 0 0 / 60%),\n 0 25px 50px -12px rgb(0 0 0 / 70%)!important}@media (prefers-color-scheme: dark){[data-component-part=\"search-modal\"]{box-shadow:0 0 0 100vmax rgb(0 0 0 / 60%),\n 0 25px 50px -12px rgb(0 0 0 / 70%)!important}}code,pre,kbd,samp,[class*=\"language-\"],[data-component-part=\"code-block\"],[data-component-part=\"code-block\"] *{font-family:var(--font-mono)!important;font-weight:400!important}html{letter-spacing:0.02em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body,p,li{letter-spacing:0.02em}strong,b,.font-semibold{font-weight:600!important}a{font-weight:inherit!important}h1,h2,h3,h4,h5,h6{letter-spacing:0!important;font-weight:400!important}h1,h4,h5,h6{line-height:1.2!important}h2,h3{line-height:1.5!important}h3+h4{margin-top:1.25rem!important}h1.font-semibold,h2.font-semibold,h3.font-semibold,h4.font-semibold,h5.font-semibold,h6.font-semibold{font-weight:400!important}html[data-current-path=\"/changelog\"] #page-title{font-size:0!important}html[data-current-path=\"/changelog\"] #page-title::before{content:\"Product updates\";font-size:1.875rem}html[data-current-path=\"/changelog\"] #content-area>*{max-width:41.4rem}@media (min-width: 640px){html[data-current-path=\"/changelog\"] #page-title::before{font-size:2.25rem}}@media (min-width: 1536px){html[data-current-path=\"/changelog\"] #content-area>*{max-width:48.3rem}}.sidebar-group-header h3,h3.sidebar-title{font-weight:600!important}#navigation-items{line-height:1.25rem}#navigation-items .sidebar-group>*+*{margin-top:0!important}[data-component-part=\"card-title\"]{font-size:1.2rem!important}[data-component-part=\"card-content\"]{margin-top:0.5rem!important}code,pre,kbd,samp,[class*=\"language-\"],[data-component-part=\"code-block\"],[data-component-part=\"code-block\"] *{letter-spacing:normal}.max-w-8xl,[class*=\"max-w-8xl\"]{max-width:100%!important}#content-area>*{width:100%;max-width:36rem;margin-left:auto;margin-right:auto}@media (min-width: 1536px){#content-area>*{max-width:42rem}}[data-component-part=\"code-block-root\"],.code-block{--primary-light: 139 92 246}:is(.dark,[data-theme=\"dark\"]) [data-component-part=\"code-block-root\"],:is(.dark,[data-theme=\"dark\"]) .code-block{--primary-light: 167 139 250}a[href=\"https://www.mintlify.com/?utm_campaign=poweredBy\u0026utm_medium=referral\u0026utm_source=ravion-b90c0359\"],a[href*=\"mintlify.com\"][href*=\"poweredBy\"],a[href*=\"mintlify.com\"][href*=\"powered-by\"],a[aria-label*=\"Mintlify\"],a[title*=\"Mintlify\"]{display:none!important}html:not([data-ravion-auth-state]) :is(.navbar-link,navbar-link):has(a[href=\"https://app.ravion.com/signup\"],a[href=\"https://cal.com/team/ravion/demo\"]){visibility:hidden}:root{--rvn-base: #0f0004;--rvn-anchor-neutral: #fdddc9;--rvn-anchor-orange: #fe6104;--rvn-anchor-purple: #b287ff;--rvn-anchor-green: #88d18a;--rvn-anchor-red: #ff4d61}html.dark{--gray-50: 253 221 201;--gray-100: 253 221 201;--gray-200: 253 221 201;--gray-300: 224 194 177;--gray-400: 196 168 154;--gray-500: 136 113 104;--gray-600: 113 91 85;--gray-700: 86 66 63;--gray-800: 51 33 34;--gray-900: 39 22 24;--gray-950: 27 11 14;--color-white: var(--rvn-anchor-neutral)}html.dark [data-component-part=\"code-block-root\"],html.dark .dark\\:bg-codeblock{background-color:color-mix(in srgb, var(--rvn-anchor-neutral) 5%, var(--rvn-base))!important}html.dark [data-callout-type]{--rvn-callout: var(--rvn-anchor-purple);background-color:color-mix(in srgb, var(--rvn-callout) 5%, var(--rvn-base))!important;border-color:color-mix(in srgb, var(--rvn-callout) 30%, var(--rvn-base))!important}html.dark [data-callout-type=\"warning\"]{--rvn-callout: var(--rvn-anchor-orange)}html.dark :is([data-callout-type=\"tip\"],[data-callout-type=\"check\"]){--rvn-callout: var(--rvn-anchor-green)}html.dark :is([data-callout-type=\"danger\"],[data-callout-type=\"error\"]){--rvn-callout: var(--rvn-anchor-red)}html.dark [data-callout-type]>*,html.dark [data-callout-type] svg{color:var(--rvn-callout)!important}html.dark svg[id^=\"mermaid\"] :is(.node rect,.node polygon,.node circle,.node path){fill:color-mix(in srgb, var(--rvn-anchor-neutral) 10%, var(--rvn-base))!important;stroke:color-mix(in srgb, var(--rvn-anchor-neutral) 30%, var(--rvn-base))!important}html.dark svg[id^=\"mermaid\"] .cluster rect{fill:color-mix(in srgb, var(--rvn-anchor-neutral) 5%, var(--rvn-base))!important;stroke:color-mix(in srgb, var(--rvn-anchor-neutral) 15%, var(--rvn-base))!important}html.dark svg[id^=\"mermaid\"] :is(.cluster text,.cluster-label,.cluster-label *){fill:var(--rvn-anchor-neutral)!important;color:var(--rvn-anchor-neutral)!important}html.dark svg[id^=\"mermaid\"] :is(.flowchart-link,.edgePath path,.transition):not([style*=\"stroke\"]){stroke:color-mix(in srgb, var(--rvn-anchor-neutral) 51%, var(--rvn-base))!important}html.dark svg[id^=\"mermaid\"] :is(.flowchart-link,.edgePath path)[style*=\"CBD5E1\"i]{stroke:color-mix(in srgb, var(--rvn-anchor-neutral) 20%, var(--rvn-base))!important}html.dark svg[id^=\"mermaid\"] :is(.arrowMarkerPath,marker path){fill:color-mix(in srgb, var(--rvn-anchor-neutral) 51%, var(--rvn-base))!important;stroke:color-mix(in srgb, var(--rvn-anchor-neutral) 51%, var(--rvn-base))!important}html.dark svg[id^=\"mermaid\"] :is(.edgeLabel,.edgeLabel p,.edgeLabel span,.labelBkg){background-color:var(--rvn-base)!important;color:color-mix(in srgb, var(--rvn-anchor-neutral) 76%, var(--rvn-base))!important}html.dark svg[id^=\"mermaid\"] .edgeLabel rect{fill:var(--rvn-base)!important;opacity:1!important}"}],"page":{"pagePath":"guides/puppeteer-on-ecs","slug":"/guides/puppeteer-on-ecs","pageMetadata":{"title":"Run Puppeteer or Playwright on ECS","description":"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.","og:image":"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png","twitter:image":"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png","href":"/guides/puppeteer-on-ecs"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tab,Tabs,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`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.`}),`\n`,_jsx(Heading,{level:`2`,id:`install-chromium-in-the-image`,children:`Install Chromium in the image`}),`\n`,_jsxs(_components.p,{children:[`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 (`,_jsx(_components.code,{children:`noble`}),`).`]}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Playwright`,id:`playwright`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`docker`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`docker`,children:_jsxs(_components.code,{language:`docker`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` mcr.microsoft.com/playwright:v1.63.0-noble`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WORKDIR`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /app`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` package*.json ./`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` npm ci`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` . .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`USER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` pwuser`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CMD`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"node\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"server.js\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`The image contains the browsers but not the `,_jsx(_components.code,{children:`playwright`}),` npm package — `,_jsx(_components.code,{children:`npm ci`}),` installs it.\nPin the image tag to the exact Playwright version in `,_jsx(_components.code,{children:`package.json`}),`; a mismatch fails at\nlaunch because the package looks for a browser build the image does not have. See the\n`,_jsx(_components.a,{href:`https://playwright.dev/docs/docker`,children:`Playwright Docker guide`}),`.`]})]}),_jsxs(Tab,{title:`Puppeteer`,id:`puppeteer`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`docker`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`docker`,children:_jsxs(_components.code,{language:`docker`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ghcr.io/puppeteer/puppeteer:25.10.0`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WORKDIR`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /home/pptruser/app`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` --chown=pptruser:pptruser package*.json ./`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` npm ci`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` --chown=pptruser:pptruser . .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CMD`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"node\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"server.js\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`The image includes Chrome for Testing, the matching `,_jsx(_components.code,{children:`puppeteer`}),` version, and runs as\n`,_jsx(_components.code,{children:`pptruser`}),`. Pin the tag to the Puppeteer version in `,_jsx(_components.code,{children:`package.json`}),`. See the\n`,_jsx(_components.a,{href:`https://pptr.dev/guides/docker`,children:`Puppeteer Docker guide`}),`.`]}),_jsxs(_components.p,{children:[`If you build on a plain Node image instead, note that npm 11, pnpm, Yarn, and Bun block\ndependency install scripts by default, so Puppeteer’s browser download does not run on\n`,_jsx(_components.code,{children:`npm ci`}),`. Run `,_jsx(_components.code,{children:`npx puppeteer browsers install chrome`}),` as an explicit build step, and install\nthe `,_jsx(_components.a,{href:`https://pptr.dev/troubleshooting#chrome-doesnt-launch-on-linux`,children:`system libraries Chrome needs`}),`.`]})]}),_jsxs(Tab,{title:`Distro Chromium`,id:`distro-chromium`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`docker`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`docker`,children:_jsxs(_components.code,{language:`docker`,numberOfLines:`12`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` public.ecr.aws/docker/library/node:24-slim`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` apt-get update \u0026\u0026 apt-get install -y --no-install-recommends \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` chromium fonts-liberation \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026 rm -rf /var/lib/apt/lists/*`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`ENV`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` PUPPETEER_SKIP_DOWNLOAD=true \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WORKDIR`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /app`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` package*.json ./`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` npm ci`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` . .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`USER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` node`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CMD`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"node\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"server.js\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`Use Debian’s `,_jsx(_components.code,{children:`chromium`}),` package with `,_jsx(_components.code,{children:`puppeteer-core`}),` (or `,_jsx(_components.code,{children:`puppeteer`}),` with the download\nskipped) when you need an `,_jsx(_components.code,{children:`arm64`}),` image or a smaller one. The package pulls in every library\nChromium needs, and there is no second browser download during the build. You get Debian’s\nChromium release cadence rather than the version Puppeteer was tested against.`]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`launch-options`,children:`Launch options`}),`\n`,_jsxs(_components.p,{children:[`Chromium’s sandbox relies on user namespaces that containers usually do not grant, and `,_jsx(_components.code,{children:`/dev/shm`}),` inside a Fargate task is 64 MB — too small for a real page. Disable both:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` browser`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` puppeteer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`launch`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` args:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"--no-sandbox\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"--disable-setuid-sandbox\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"--disable-dev-shm-usage\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`})`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Headless is the default in current Puppeteer and Playwright, so there is nothing to set for it. Playwright takes the same flags via `,_jsx(_components.code,{children:`chromium.launch({ args: [...] })`}),`; on ECS you cannot use the `,_jsx(_components.code,{children:`--ipc=host`}),` alternative the Playwright docs suggest for `,_jsx(_components.code,{children:`/dev/shm`}),`, because Fargate does not support host IPC mode.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Only render content you trust with the sandbox disabled. A page that exploits Chromium gains the\npermissions of the task role. If you render untrusted pages, keep the sandbox on: run as the\nnon-root user the official images provide (`,_jsx(_components.code,{children:`pwuser`}),`, `,_jsx(_components.code,{children:`pptruser`}),`) and give Chromium the\n`,_jsx(_components.code,{children:`SYS_ADMIN`}),` capability or a seccomp profile that allows user namespaces. Fargate permits\nneither, so put those tasks on EC2 capacity (`,_jsx(_components.code,{children:`capacity_provider: ec2`}),`).`]})}),`\n`,_jsx(Heading,{level:`2`,id:`task-sizing`,children:`Task sizing`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Memory.`}),` Budget at least 1 GB per concurrent browser page plus your app. The default `,_jsx(_components.code,{children:`fargate_size`}),` of 2 vCPU / 4 GB handles a couple of pages; raise it before scaling out.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Ephemeral storage.`}),` Chromium writes profiles and caches to disk. If you screenshot or download at volume, increase `,_jsx(_components.code,{children:`task_ephemeral_storage_size_gib`}),` above the 20 GiB Fargate default.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Architecture.`}),` Chrome for Testing, the build Puppeteer downloads, has no Linux `,_jsx(_components.code,{children:`arm64`}),` binaries, so a Puppeteer image built on it runs on `,_jsx(_components.code,{children:`X86_64`}),` only. For `,_jsx(_components.code,{children:`cpu_architecture: ARM64`}),` (Graviton) use the Playwright image, which is published for both architectures, or Debian’s `,_jsx(_components.code,{children:`chromium`}),` package.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`isolate-browser-work-in-a-worker`,children:`Isolate browser work in a worker`}),`\n`,_jsxs(_components.p,{children:[`Run the browser in a separate `,_jsx(_components.a,{href:`/module-definitions/catalog/rvn-ecs-worker`,children:_jsx(_components.code,{children:`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 `,_jsx(_components.code,{children:`--no-sandbox`}),` at all.`]}),`\n`,_jsx(Heading,{level:`2`,id:`related-pages`,children:`Related pages`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/module-definitions/catalog/rvn-ecs-web`,children:_jsx(_components.code,{children:`rvn-ecs-web`})})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/module-definitions/catalog/rvn-ecs-worker`,children:_jsx(_components.code,{children:`rvn-ecs-worker`})})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Run Puppeteer or Playwright on ECS","description":"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.","og:image":"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png","twitter:image":"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png","href":"/guides/puppeteer-on-ecs"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Install Chromium in the image","slug":"install-chromium-in-the-image","depth":2,"children":[]},{"title":"Launch options","slug":"launch-options","depth":2,"children":[]},{"title":"Task sizing","slug":"task-sizing","depth":2,"children":[]},{"title":"Isolate browser work in a worker","slug":"isolate-browser-work-in-a-worker","depth":2,"children":[]},{"title":"Related pages","slug":"related-pages","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/ravion-b90c0359/c514f1aea613ba76/navbar-auth-link.js","/docs/_mintlify/custom/ravion-b90c0359/073d951ef5e29315/schema-anchor-redirects.js","/docs/_mintlify/custom/ravion-b90c0359/a38f18e58e04c0a7/catalog-anchor-redirects.js"],"subdomain":"ravion-b90c0359","siteName":"Ravion Docs","title":"Run Puppeteer or Playwright on ECS - Ravion Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-24T19:30:32.420Z","originalFileLocation":"guides/puppeteer-on-ecs.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Ravion Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Run Puppeteer or Playwright on ECS - Ravion Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Ravion Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://www.ravion.com/docs/guides/puppeteer-on-ecs\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Run Puppeteer or Playwright on ECS - Ravion Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/ravion-b90c0359/PBg3PC_UrJuB5_rW/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Ravion Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#FE6104\">\u003clink data-mint-head rel=\"canonical\" href=\"https://www.ravion.com/docs/guides/puppeteer-on-ecs\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/guides/puppeteer-on-ecs.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://www.ravion.com/#organization\",\"name\":\"Ravion Docs\",\"url\":\"https://www.ravion.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/ravion-b90c0359/flJhuOPF2oqAa_dG/logo/light.svg?fit=max\u0026auto=format\u0026n=flJhuOPF2oqAa_dG\u0026q=85\u0026s=1f2e6cab050d18d564cdeb5f723e684d\"}},{\"@type\":\"WebSite\",\"@id\":\"https://www.ravion.com/docs#website\",\"name\":\"Ravion Docs\",\"url\":\"https://www.ravion.com/docs\",\"publisher\":{\"@id\":\"https://www.ravion.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs#webpage\",\"url\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs\",\"name\":\"Run Puppeteer or Playwright on ECS\",\"description\":\"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.\",\"dateModified\":\"2026-09-24T19:30:32.420Z\",\"isPartOf\":{\"@id\":\"https://www.ravion.com/docs#website\"},\"breadcrumb\":{\"@id\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Guides\",\"item\":\"https://www.ravion.com/docs/guides/custom-domains\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Run Puppeteer or Playwright on ECS\",\"item\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs#article\",\"headline\":\"Run Puppeteer or Playwright on ECS\",\"name\":\"Run Puppeteer or Playwright on ECS\",\"description\":\"Configure headless Chromium for AWS Fargate or EC2 tasks: install the browser in the image, disable the sandbox, size the task, and isolate browser work in a worker service.\",\"url\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs\",\"mainEntityOfPage\":{\"@id\":\"https://www.ravion.com/docs/guides/puppeteer-on-ecs#webpage\"},\"image\":\"https://www.ravion.com/og/docs/guides/puppeteer-on-ecs.png\",\"dateModified\":\"2026-09-24T19:30:32.420Z\",\"publisher\":{\"@id\":\"https://www.ravion.com/#organization\"},\"isPartOf\":{\"@id\":\"https://www.ravion.com/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Ravion Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Ravion Docs","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Introduction","pages":[{"title":"Build a faster, safer software factory","sidebarTitle":"Overview","href":""},{"title":"Start here","sidebarTitle":"Start here","href":"/start-here"},{"title":"How Ravion works","href":"/how-ravion-works"},{"title":"Product philosophy","href":"/philosophy"},{"title":"Report bugs and feedback","href":"/report-bugs-and-feedback"},{"title":"Contact Ravion support for product help","sidebarTitle":"Contact support","href":"/contact-support"}]},{"group":"Concepts","pages":[{"title":"Ravion concepts: projects, modules, pipelines","sidebarTitle":"Core concepts","href":"/concepts/core-concepts"},{"title":"Projects and environments","href":"/concepts/projects-and-environments"},{"title":"Ravion modules: infrastructure building blocks","sidebarTitle":"Modules","href":"/concepts/modules"},{"title":"CI/CD pipelines","sidebarTitle":"CI/CD pipelines","href":"/concepts/pipelines"},{"title":"Sandboxes","sidebarTitle":"Sandboxes","href":"/concepts/sandboxes"},{"title":"Infrastructure as code","href":"/concepts/infrastructure-as-code"}]},{"group":"Config as code","pages":[{"title":"Project config file","href":"/config-as-code/project-config-file"},{"title":"Pipeline config file","href":"/config-as-code/pipeline-config-file"},{"title":"GitHub integration","href":"/config-as-code/github-integration"}]},{"group":"Access control","pages":[{"title":"Role-based access control","href":"/access-control/rbac"},{"title":"Custom roles","href":"/access-control/custom-roles"}]},{"group":"Migrate","pages":[{"title":"Migrate from Flightcontrol","sidebarTitle":"From Flightcontrol","href":"/migrate/from-flightcontrol"},{"title":"Migrate from Heroku to AWS","sidebarTitle":"From Heroku","href":"/migrate/from-heroku"},{"title":"Migrate Heroku Postgres to AWS RDS","sidebarTitle":"Heroku Postgres to RDS","href":"/migrate/heroku-postgres-to-rds"},{"title":"Run your existing Terraform with Ravion","sidebarTitle":"Run existing Terraform","href":"/migrate/existing-terraform-stack"},{"title":"Import resources into a Ravion standard module","sidebarTitle":"Import into a standard module","href":"/migrate/import-into-standard-module"},{"title":"Import into Terraform/OpenTofu stacks","sidebarTitle":"Import into a Terraform Stack","href":"/migrate/import-into-terraform-stack"}]},{"group":"GitHub Actions","pages":[{"title":"GitHub Actions runners","sidebarTitle":"Runners","href":"/github-actions/runners"},{"title":"Caching for GitHub Actions","sidebarTitle":"Caching","href":"/github-actions/caching"}]},{"group":"Modules","pages":[{"title":"Ravion modules: infrastructure building blocks","sidebarTitle":"Modules","href":"/concepts/modules"},{"title":"Manage Terraform state for modules","sidebarTitle":"Stack","href":"/modules/stack"},{"title":"Reference outputs from other modules","sidebarTitle":"Output references","href":"/modules/output-references"},{"title":"Build application artifacts with modules","sidebarTitle":"Build","href":"/modules/build"},{"title":"Deploy application releases to modules","sidebarTitle":"Deploy","href":"/modules/deploy"},{"title":"Monitor module health with CloudWatch metrics","sidebarTitle":"Metrics","href":"/modules/metrics"},{"title":"View and query module logs","sidebarTitle":"Logs","href":"/modules/logs"},{"title":"Link modules to external systems","sidebarTitle":"Links","href":"/modules/links"},{"group":"Standard library","root":{"title":"Standard library","href":"/module-definitions/standard-library"},"pages":[{"title":"ACM Certificate","sidebarTitle":"rvn-acm-certificate","href":"/module-definitions/catalog/rvn-acm-certificate"},{"group":"rvn-aurora","root":{"title":"Aurora Database","sidebarTitle":"rvn-aurora","href":"/module-definitions/catalog/rvn-aurora"},"pages":[{"title":"Aurora Database inputs: Inputs to global database","sidebarTitle":"Inputs: Inputs to global database","href":"/module-definitions/catalog/rvn-aurora/inputs-inputs"},{"title":"Aurora Database inputs: Misc to terraform settings","sidebarTitle":"Inputs: Misc to terraform settings","href":"/module-definitions/catalog/rvn-aurora/inputs-misc"}]},{"title":"AWS Application Load Balancer","sidebarTitle":"rvn-aws-alb","href":"/module-definitions/catalog/rvn-aws-alb"},{"title":"alterNAT","sidebarTitle":"rvn-aws-alternat","href":"/module-definitions/catalog/rvn-aws-alternat"},{"title":"AMI","sidebarTitle":"rvn-aws-ami","href":"/module-definitions/catalog/rvn-aws-ami"},{"title":"AWS Compliance","sidebarTitle":"rvn-aws-compliance","href":"/module-definitions/catalog/rvn-aws-compliance"},{"title":"AWS ECR Repository","sidebarTitle":"rvn-aws-ecr","href":"/module-definitions/catalog/rvn-aws-ecr"},{"title":"AWS IAM Policy","sidebarTitle":"rvn-aws-iam-policy","href":"/module-definitions/catalog/rvn-aws-iam-policy"},{"title":"AWS IAM Role","sidebarTitle":"rvn-aws-iam-role","href":"/module-definitions/catalog/rvn-aws-iam-role"},{"title":"AWS KMS Key","sidebarTitle":"rvn-aws-kms","href":"/module-definitions/catalog/rvn-aws-kms"},{"title":"VPC Network","sidebarTitle":"rvn-aws-network","href":"/module-definitions/catalog/rvn-aws-network"},{"title":"AWS Secret","sidebarTitle":"rvn-aws-secret","href":"/module-definitions/catalog/rvn-aws-secret"},{"title":"Static Hosting","sidebarTitle":"rvn-aws-static","href":"/module-definitions/catalog/rvn-aws-static"},{"title":"CloudFront CDN","sidebarTitle":"rvn-cloudfront","href":"/module-definitions/catalog/rvn-cloudfront"},{"group":"rvn-ec2-service","root":{"title":"EC2 Service","sidebarTitle":"rvn-ec2-service","href":"/module-definitions/catalog/rvn-ec2-service"},"pages":[{"title":"EC2 Service inputs: Inputs to logging","sidebarTitle":"Inputs: Inputs to logging","href":"/module-definitions/catalog/rvn-ec2-service/inputs-inputs"},{"title":"EC2 Service inputs: Terraform settings to terraform settings","sidebarTitle":"Inputs: Terraform settings to terraform settings","href":"/module-definitions/catalog/rvn-ec2-service/inputs-terraform-settings"}]},{"group":"rvn-ecs-cluster","root":{"title":"ECS Cluster","sidebarTitle":"rvn-ecs-cluster","href":"/module-definitions/catalog/rvn-ecs-cluster"},"pages":[{"title":"ECS Cluster inputs","sidebarTitle":"Inputs","href":"/module-definitions/catalog/rvn-ecs-cluster/inputs"}]},{"group":"rvn-ecs-nlb","root":{"title":"ECS Network Service","sidebarTitle":"rvn-ecs-nlb","href":"/module-definitions/catalog/rvn-ecs-nlb"},"pages":[{"title":"ECS Network Service inputs: ECS cluster to logging","sidebarTitle":"Inputs: ECS cluster to logging","href":"/module-definitions/catalog/rvn-ecs-nlb/inputs-ecs-cluster"},{"title":"ECS Network Service inputs: IAM roles and policies to terraform settings","sidebarTitle":"Inputs: IAM roles and policies to terraform settings","href":"/module-definitions/catalog/rvn-ecs-nlb/inputs-iam-roles-and-policies"}]},{"group":"rvn-ecs-web","root":{"title":"ECS Web Service","sidebarTitle":"rvn-ecs-web","href":"/module-definitions/catalog/rvn-ecs-web"},"pages":[{"title":"ECS Web Service inputs: ECS cluster to environment variables","sidebarTitle":"Inputs: ECS cluster to environment variables","href":"/module-definitions/catalog/rvn-ecs-web/inputs-ecs-cluster"},{"title":"ECS Web Service inputs: Pre and post deploy to terraform settings","sidebarTitle":"Inputs: Pre and post deploy to terraform settings","href":"/module-definitions/catalog/rvn-ecs-web/inputs-pre-and-post-deploy"}]},{"group":"rvn-ecs-worker","root":{"title":"ECS Worker","sidebarTitle":"rvn-ecs-worker","href":"/module-definitions/catalog/rvn-ecs-worker"},"pages":[{"title":"ECS Worker inputs: ECS cluster to iAM roles and policies","sidebarTitle":"Inputs: ECS cluster to iAM roles and policies","href":"/module-definitions/catalog/rvn-ecs-worker/inputs-ecs-cluster"},{"title":"ECS Worker inputs: Networking and deployment to terraform settings","sidebarTitle":"Inputs: Networking and deployment to terraform settings","href":"/module-definitions/catalog/rvn-ecs-worker/inputs-networking-and-deployment"}]},{"title":"EFS File System","sidebarTitle":"rvn-efs","href":"/module-definitions/catalog/rvn-efs"},{"group":"rvn-eks-addons","root":{"title":"EKS Add-ons","sidebarTitle":"rvn-eks-addons","href":"/module-definitions/catalog/rvn-eks-addons"},"pages":[{"title":"EKS Add-ons inputs: Inputs to logs","sidebarTitle":"Inputs: Inputs to logs","href":"/module-definitions/catalog/rvn-eks-addons/inputs-inputs"},{"title":"EKS Add-ons inputs: Metrics to terraform settings","sidebarTitle":"Inputs: Metrics to terraform settings","href":"/module-definitions/catalog/rvn-eks-addons/inputs-metrics"}]},{"title":"EKS Helm Chart","sidebarTitle":"rvn-eks-chart","href":"/module-definitions/catalog/rvn-eks-chart"},{"title":"EKS Cluster","sidebarTitle":"rvn-eks-cluster","href":"/module-definitions/catalog/rvn-eks-cluster"},{"group":"rvn-eks-web","root":{"title":"EKS Web Service","sidebarTitle":"rvn-eks-web","href":"/module-definitions/catalog/rvn-eks-web"},"pages":[{"title":"EKS Web Service inputs: EKS cluster to networking and deployment","sidebarTitle":"Inputs: EKS cluster to networking and deployment","href":"/module-definitions/catalog/rvn-eks-web/inputs-eks-cluster"},{"title":"EKS Web Service inputs: Builder config to terraform settings","sidebarTitle":"Inputs: Builder config to terraform settings","href":"/module-definitions/catalog/rvn-eks-web/inputs-builder-config"}]},{"group":"rvn-eks-worker","root":{"title":"EKS Worker","sidebarTitle":"rvn-eks-worker","href":"/module-definitions/catalog/rvn-eks-worker"},"pages":[{"title":"EKS Worker inputs","sidebarTitle":"Inputs","href":"/module-definitions/catalog/rvn-eks-worker/inputs"}]},{"title":"ElastiCache","sidebarTitle":"rvn-elasticache","href":"/module-definitions/catalog/rvn-elasticache"},{"group":"rvn-lambda","root":{"title":"Lambda Function","sidebarTitle":"rvn-lambda","href":"/module-definitions/catalog/rvn-lambda"},"pages":[{"title":"Lambda Function inputs: AWS account \u0026 region to advanced Lambda settings","sidebarTitle":"Inputs: AWS account \u0026 region to advanced Lambda settings","href":"/module-definitions/catalog/rvn-lambda/inputs-aws-account-region"},{"title":"Lambda Function inputs: Builder config to terraform settings","sidebarTitle":"Inputs: Builder config to terraform settings","href":"/module-definitions/catalog/rvn-lambda/inputs-builder-config"}]},{"group":"rvn-rds","root":{"title":"RDS Database","sidebarTitle":"rvn-rds","href":"/module-definitions/catalog/rvn-rds"},"pages":[{"title":"RDS Database inputs","sidebarTitle":"Inputs","href":"/module-definitions/catalog/rvn-rds/inputs"}]},{"title":"RDS Proxy","sidebarTitle":"rvn-rds-proxy","href":"/module-definitions/catalog/rvn-rds-proxy"},{"title":"Route 53 DNS","sidebarTitle":"rvn-route53","href":"/module-definitions/catalog/rvn-route53"},{"title":"S3 Bucket","sidebarTitle":"rvn-s3","href":"/module-definitions/catalog/rvn-s3"},{"title":"Terraform Stack","sidebarTitle":"rvn-stack","href":"/module-definitions/catalog/rvn-stack"}]}]},{"group":"Pipelines","pages":[{"title":"CI/CD pipelines","sidebarTitle":"CI/CD pipelines","href":"/concepts/pipelines"},{"title":"Sandboxes","sidebarTitle":"Sandboxes","href":"/concepts/sandboxes"},{"title":"Pipeline examples","sidebarTitle":"Examples","href":"/pipelines/examples"},{"group":"Configuration","root":{"title":"Pipeline configuration","sidebarTitle":"Configuration","href":"/pipelines/config-reference"},"pages":[{"title":"Pipeline configuration: Top-level fields","sidebarTitle":"Pipeline config","href":"/pipelines/config-reference/pipelineconfig"},{"title":"Pipeline configuration: Triggers","sidebarTitle":"Triggers","href":"/pipelines/config-reference/triggers"},{"title":"Pipeline configuration: Inputs","sidebarTitle":"Inputs","href":"/pipelines/config-reference/inputs"},{"title":"Pipeline configuration: Variants","sidebarTitle":"Variants","href":"/pipelines/config-reference/variants"},{"title":"Pipeline configuration: Steps","sidebarTitle":"Steps","href":"/pipelines/config-reference/steps"},{"title":"Pipeline configuration: CI steps","sidebarTitle":"CI steps","href":"/pipelines/config-reference/ci-steps"},{"title":"Pipeline configuration: Build configs","sidebarTitle":"Build configs","href":"/pipelines/config-reference/build-configs"},{"title":"Pipeline configuration: Step infrastructure","sidebarTitle":"Step infrastructure","href":"/pipelines/config-reference/step-infrastructure"},{"title":"Pipeline configuration: Other types","sidebarTitle":"Other types","href":"/pipelines/config-reference/other-types"},{"title":"Pipeline configuration: Template expressions","sidebarTitle":"Template expressions","href":"/pipelines/config-reference/template-expressions"}]},{"title":"Ravion pipeline step types and actions","sidebarTitle":"Step types","href":"/pipelines/step-types"},{"title":"Ravion pipeline concurrency","sidebarTitle":"Concurrency","href":"/pipelines/concurrency"},{"title":"Pipeline variants","sidebarTitle":"Variants","href":"/pipelines/variants"},{"title":"Pipeline templating","sidebarTitle":"Templating","href":"/pipelines/templating"}]},{"group":"Guides","pages":[{"title":"Configure custom domains for Ravion services","sidebarTitle":"Custom domains","href":"/guides/custom-domains"},{"title":"Deploy a service to multiple AWS regions","sidebarTitle":"Multi-region","href":"/guides/aws/multi-region"},{"title":"Managing secrets","href":"/guides/managing-secrets"},{"title":"Running database migrations","description":"Run schema migrations once per deploy — at the end of the build, in an ECS pre-deploy hook, or as a pipeline step — and understand the trade-offs of each.","href":"/guides/database-migrations"},{"title":"Run Puppeteer or Playwright on ECS","href":"/guides/puppeteer-on-ecs"}]},{"group":"Troubleshooting","pages":[{"title":"Stuck Terraform state lock","description":"Confirm an abandoned Terraform state lock is no longer active, then release it safely from the dashboard, CLI, or API so the stack can run again.","href":"/troubleshooting/stuck-terraform-state-lock"},{"title":"PostgreSQL SSL connection error: no pg_hba.conf entry","sidebarTitle":"Postgres SSL connection error","href":"/troubleshooting/postgres-ssl-connection"},{"title":"Random 502 errors behind a load balancer","href":"/troubleshooting/load-balancer-502-keepalive-timeout"},{"title":"Docker Hub rate limits","href":"/troubleshooting/docker-hub-rate-limits"},{"title":"JavaScript heap out of memory","href":"/troubleshooting/node-heap-out-of-memory"},{"title":"Too many VPCs: VpcLimitExceeded","sidebarTitle":"Too many VPCs","href":"/troubleshooting/too-many-vpcs"},{"title":"Unable to place a task: Fargate vCPU quota","sidebarTitle":"Fargate vCPU quota","href":"/troubleshooting/fargate-vcpu-quota"}]},{"group":"Agent setup","pages":[{"title":"Ravion agent skill","sidebarTitle":"Agent skill","href":"/agent-skill"}]},{"group":"Module definitions","pages":[{"title":"Ravion standard module catalog","sidebarTitle":"Module catalog","href":"/module-definitions/catalog"},{"group":"Definition schema","root":{"title":"Module definition schema","sidebarTitle":"Definition schema","href":"/module-definitions/definition-schema"},"pages":[{"title":"Module definition schema: Module","sidebarTitle":"Module","href":"/module-definitions/definition-schema/module"},{"title":"Module definition schema: Inputs","sidebarTitle":"Inputs","href":"/module-definitions/definition-schema/inputs"},{"title":"Module definition schema: Input types","sidebarTitle":"Input types","href":"/module-definitions/definition-schema/input-types"},{"title":"Module definition schema: Object input types","sidebarTitle":"Object input types","href":"/module-definitions/definition-schema/object-input-types"},{"title":"Module definition schema: Stack","sidebarTitle":"Stack","href":"/module-definitions/definition-schema/stack"},{"title":"Module definition schema: Build","sidebarTitle":"Build","href":"/module-definitions/definition-schema/build"},{"title":"Module schema: Build configs","sidebarTitle":"Build configs","href":"/module-definitions/definition-schema/build-configs"},{"title":"Module definition schema: Deploy","sidebarTitle":"Deploy","href":"/module-definitions/definition-schema/deploy"},{"title":"Module schema: ECS deployment strategies","sidebarTitle":"ECS deployments","href":"/module-definitions/definition-schema/ecs-deployments"},{"title":"Module schema: ECS container definitions","sidebarTitle":"ECS container definitions","href":"/module-definitions/definition-schema/ecs-container-definitions"},{"title":"Module schema: ECS task definitions","sidebarTitle":"ECS task definitions","href":"/module-definitions/definition-schema/ecs-task-definitions"},{"title":"Module schema: EKS deployments","sidebarTitle":"EKS deployments","href":"/module-definitions/definition-schema/eks-deployments"},{"title":"Module schema: Lambda deployments","sidebarTitle":"Lambda deployments","href":"/module-definitions/definition-schema/lambda-deployments"},{"title":"Module definition schema: UI and readme","sidebarTitle":"UI","href":"/module-definitions/definition-schema/ui"},{"title":"Other types","sidebarTitle":"Other types","href":"/module-definitions/definition-schema/other-types"},{"title":"Module schema: Template expressions","sidebarTitle":"Template expressions","href":"/module-definitions/definition-schema/template-expressions"}]}]}]},{"tab":"Deploy to AWS","pages":[{"title":"Deploy to AWS","href":"/deploy/aws"}]},{"tab":"CLI","pages":[{"title":"CLI","href":"/cli/overview"}]},{"tab":"MCP","pages":[{"title":"MCP","href":"/mcp/overview"}]},{"tab":"API reference","pages":[{"title":"API reference","href":"/api-reference/overview"}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog"}]}]},"basePath":"","title":"Run Puppeteer or Playwright on ECS - Ravion Docs","buildId":"dpl_6dVqRXFR2Go5vF5RLvAdHuv189oT","deploymentId":"dpl_6dVqRXFR2Go5vF5RLvAdHuv189oT","dynamics":[],"chunks":[]}