Run Playwright on Lambda. Since only /tmp is writable, launch Chromium with –disable-dev-shm-usage.
import { chromium, Browser, Page } from "playwright-chromium";
browser = await chromium.launch({
headless: true,
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage",
"--single-process",
],
});
const page = await browser.newPage();
await page.goto("https://example.com", {
waitUntil: "networkidle",
});
Build the application and the binaries that aws-lambda-ric depends on, then copy them into the official Playwright image. aws-lambda-ric is a package for running Lambda functions on a custom base image, connecting the application to the Lambda Runtime API.
Chromium is already installed, so there is no need to run npx playwright install --with-deps chromium. The image version is matched with the playwright library version.
FROM node:24-slim AS builder
# builder image doesn't need chromium so prevent from being installed by postinstall
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# for building curl/aws-lambda-cpp on aws-lambda-ric preinstall
RUN apt-get update && \
apt-get install -y --no-install-recommends \
cmake make g++ python3 xz-utils ca-certificates && \
rm -rf /var/lib/apt/lists/*
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /repo
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
COPY test-app/package.json ./test-app/
RUN pnpm install --frozen-lockfile --filter test-app...
COPY test-app/tsconfig.json ./test-app/
COPY test-app/src ./test-app/src
RUN pnpm --filter test-app run build
RUN pnpm deploy --filter test-app --prod /out
FROM mcr.microsoft.com/playwright:v1.59.1-noble
WORKDIR /var/task
COPY --from=builder /out/node_modules ./node_modules
COPY --from=builder /out/package.json ./package.json
COPY --from=builder /repo/test-app/dist/ ./
ENTRYPOINT ["/var/task/node_modules/.bin/aws-lambda-ric"]
CMD ["handler.handler"]
If invoking after deployment results in an Unhandled error, check that files are placed at the right paths.
new lambda.DockerImageFunction(this, "TestAppFunction", {
functionName: "test-app",
code: lambda.DockerImageCode.fromImageAsset(path.join(__dirname, "../.."), {
file: "test-app/Dockerfile",
}),
memorySize: 2048,
timeout: cdk.Duration.seconds(180),
architecture: lambda.Architecture.X86_64,
});