重建Docker镜像后AWS Lambda中puppeteer-core 9.0.0报错求助
我基于nodejs:14-x86_64的AWS Lambda Docker镜像运行puppeteer-core 9.0.0,服务正常跑了一年多,近期没改代码重建镜像后突然报这个错:
Error: Protocol error (Page.navigate): Target closed.
at /var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:208:63
at new Promise ()
at CDPSession.send (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:207:16)
at navigate (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/FrameManager.js:108:47)
at FrameManager.navigateFrame (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/FrameManager.js:91:13)
at Frame.goto (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/FrameManager.js:416:41)
at Page.goto (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Page.js:819:53)
at pdfBuffer (file:///var/task/app.js:111:16)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Runtime.handler (file:///var/task/app.js:310:18)
查了下是nodejs:14_x86_64基础镜像标签更新导致新旧镜像有差异,但npm依赖完全一致。已经锁定原镜像的具体标签(public.ecr.aws/lambda/nodejs:14.2023.08.22.07-x86_64),问题还是没解决,分享几个排查方向:
核对Chrome/Chromium版本兼容性
Puppeteer-core 9.0.0绑定的Chromium版本是88,哪怕锁定了Lambda基础镜像,yum update可能偷偷升级了系统里的Chromium包。分别在新旧镜像里跑这个命令看版本:chromium-browser --version如果版本不对,要么在Dockerfile里指定安装Chromium 88,要么回退到兼容的包版本。
检查系统依赖库变化
Lambda基础镜像的系统依赖(比如libnss、libatk这些)可能在yum update后更新了,导致Puppeteer启动Chromium时兼容出问题。可以试试:- 把Dockerfile里的
yum update -y删掉,别升级系统包,只装需要的依赖 - 对比新旧镜像里关键依赖的版本,比如:
要是有差异,手动指定装旧版本的依赖包。rpm -qa | grep libnss rpm -qa | grep libatk
- 把Dockerfile里的
确认Puppeteer启动参数
看看启动Chromium的参数是不是适配当前环境,Lambda环境一般要禁用沙箱,加上无头模式的必要参数,比如:const browser = await puppeteer.launch({ headless: true, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu', '--single-process' ] });同时检查有没有内存限制之类的参数冲突。
查看Lambda完整执行日志
去AWS Lambda控制台看全量日志,除了这个报错,有没有Chromium启动失败的前置错误(比如缺依赖、权限问题)。也可以在代码里加日志,捕获Chromium启动阶段的异常:try { const browser = await puppeteer.launch(...); console.log('Chromium启动成功'); } catch (launchError) { console.error('Chromium启动失败:', launchError); throw launchError; }验证字体安装是否正常
Dockerfile里装了一堆字体,可能存在安装失败或者文件损坏的情况。在镜像里跑这些命令检查字体:fc-list | grep "Arial" fc-list | grep "Liberation"要是字体缺了,重新装对应的包,或者换个靠谱的源加速安装。
检查Lambda资源配置
哪怕镜像没改,Lambda的内存、CPU配置是不是被调过?Puppeteer吃内存,至少给1024MB以上,同时看看超时时间够不够。
附锁定基础镜像后的Dockerfile:
FROM public.ecr.aws/lambda/nodejs:14.2023.08.22.07-x86_64 as base RUN yum update -y RUN yum -y install amazon-linux-extras RUN amazon-linux-extras install epel -y RUN yum -y install cabextract RUN yum -y install ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc RUN yum -y install liberation-mono-fonts liberation-narrow-fonts liberation-sans-fonts liberation-serif-fonts urw-base35* RUN rpm -i https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm WORKDIR ${LAMBDA_TASK_ROOT} ARG LAMBDA_NAME COPY lambdas/source/${LAMBDA_NAME} . RUN npm ci CMD [ "app.handler" ]
内容的提问来源于stack exchange,提问作者scastria

