升级Puppeteer与Node版本后Docker环境浏览器启动失败求助
问题
我正在升级一个使用Puppeteer、通过Docker部署在Cloud Run上的Node仓库依赖项,版本跨度较大:从Puppeteer 12.0.0升级至21.0.3,同时Node从12升级至18。升级后Puppeteer浏览器无法正常工作,本地ARM64架构Mac和其他环境都出现相同问题。
启动浏览器的代码:
const browser = await launch({ args: ['--no-sandbox', '--disable-setuid-sandbox', '--font-render-hinting=none'], headless: 'new', });
执行时错误信息:
TargetCloseError: Protocol error (Target.setAutoAttach): Target closed at CallbackRegistry.clear (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:138:36) at #onClose (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:282:25) at WebSocket.<anonymous> (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/common/NodeWebSocketTransport.js:57:30) at callListener (/app/node_modules/ws/lib/event-target.js:290:14) at WebSocket.onClose (/app/node_modules/ws/lib/event-target.js:220:9) at WebSocket.emit (node:events:513:28) at WebSocket.emitClose (/app/node_modules/ws/lib/websocket.js:258:10) at Socket.socketOnClose (/app/node_modules/ws/lib/websocket.js:1264:15) at Socket.emit (node:events:513:28) at TCP.<anonymous> (node:net:313:12) performing snapshot function...
Dockerfile内容:
FROM ubuntu:20.04 ENV NODE_VERSION v18.12.0 ENV NVM_DIR /usr/src/.nvm ENV NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/bin ENV PATH $NODE_PATH:$PATH COPY ./build-config/fonts.conf /etc/fonts/local.conf RUN apt-get -qq update && apt-get -qq dist-upgrade RUN apt-get -y -qq install software-properties-common && \ apt-add-repository "deb http://archive.canonical.com/ubuntu $(lsb_release -sc) partner" RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections RUN apt-get -y -qq --no-install-recommends install \ build-essential \ ca-certificates \ curl \ dumb-init \ ffmpeg \ fontconfig \ fonts-freefont-ttf \ fonts-gfs-neohellenic \ fonts-indic \ fonts-ipafont-gothic \ fonts-kacst \ fonts-liberation \ fonts-noto-cjk \ fonts-noto-color-emoji \ fonts-roboto \ fonts-thai-tlwg \ fonts-ubuntu \ fonts-wqy-zenhei \ gconf-service \ git \ libappindicator1 \ libappindicator3-1 \ libasound2 \ libatk-bridge2.0-0 \ libatk1.0-0 \ libc6 \ libcairo2 \ libcups2 \ libdbus-1-3 \ libexpat1 \ libfontconfig1 \ libgbm-dev \ libgbm1 \ libgcc1 \ libgconf-2-4 \ libgdk-pixbuf2.0-0 \ libglib2.0-0 \ libgtk-3-0 \ libnspr4 \ libnss3 \ libpango-1.0-0 \ libpangocairo-1.0-0 \ libstdc++6 \ libu2f-udev \ libx11-6 \ libx11-xcb1 \ libxcb1 \ libxcomposite1 \ libxcursor1 \ libxdamage1 \ libxext6 \ libxfixes3 \ libxi6 \ libxrandr2 \ libxrender1 \ libxss1 \ libxtst6 \ locales \ lsb-release \ msttcorefonts \ pdftk \ unzip \ wget \ xdg-utils \ xvfb RUN mkdir -p $NVM_DIR &&\ curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash &&\ . $NVM_DIR/nvm.sh &&\ nvm install $NODE_VERSION ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init RUN chmod +x /usr/local/bin/dumb-init RUN fc-cache -f -v && \ apt-get -qq clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* COPY ./ /app WORKDIR /app RUN cp /app/fonts/*.otf /usr/share/fonts/opentype && mkfontscale && mkfontdir && fc-cache -f -v ARG NPM_TOKEN ENV NPM_TOKEN ${NPM_TOKEN} RUN npm i --omit=dev EXPOSE ${PORT} ENTRYPOINT ["dumb-init", "--"] CMD ["node", "/app/build/src/index.js"]
手动启动Chrome时的错误:
$ google-chrome-stable --headless --no-sandbox -disable-setuid-sandbox --font-render-hinting=none --dump-dom https://developer.chrome.com [0829/232805.405001:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory [0829/232805.482207:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory [0829/232805.482827:ERROR:bus.cc(399)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory [0829/232805.716354:WARNING:sandbox_linux.cc(393)] InitializeSandbox() called with multiple threads in process gpu-process. [0829/232805.721404:WARNING:bluez_dbus_manager.cc(247)] Floss manager not present, cannot set Floss enable/disable. Segmentation fault
添加dbus服务后,错误变为连接拒绝。
解决方案
1. 调整Puppeteer启动参数
针对新版本Puppeteer的new headless模式,补充必要参数避免Chrome崩溃:
const browser = await launch({ args: [ '--no-sandbox', '--disable-setuid-sandbox', '--font-render-hinting=none', '--disable-gpu', '--disable-dev-shm-usage', '--disable-software-rasterizer', '--single-process' // *关键:避免多进程导致的段错误* ], headless: 'new', executablePath: '/usr/bin/google-chrome-stable' // 指定手动安装的Chrome路径,规避权限问题 });
2. 修复Dockerfile配置
(1)安装匹配版本的Chrome
替换原有步骤,安装与Puppeteer 21.0.3兼容的Chrome 115.0.5790.170:
# 在安装系统依赖后添加 RUN wget -q https://dl.google.com/linux/direct/google-chrome-stable_115.0.5790.170-1_amd64.deb RUN apt-get install -y ./google-chrome-stable_115.0.5790.170-1_amd64.deb RUN rm google-chrome-stable_115.0.5790.170-1_amd64.deb
(2)创建非root用户运行
以root运行Chrome易触发权限和沙箱问题,添加专用用户:
# 在安装Chrome后、复制代码前添加 RUN useradd -m pptruser RUN chown -R pptruser:pptruser /app USER pptruser
(3)简化启动流程
无需手动启动dbus,新版本Chrome在headless模式下不依赖该服务;保持dumb-init作为入口即可。
3. 优化Cloud Run部署配置
- 分配至少1GB内存给服务,Chrome headless模式需要足够内存支撑
- 根据服务需求配置IAM权限或开启未认证调用
4. 验证Chrome启动
进入容器后,用非root用户执行以下命令验证Chrome是否正常:
su pptruser -c "google-chrome-stable --headless=new --no-sandbox --disable-setuid-sandbox --dump-dom https://developer.chrome.com"
若能正常输出网页DOM,说明Chrome启动正常,再测试Puppeteer连接。
内容的提问来源于stack exchange,提问作者pidgezero
相关产品推荐
相关产品推荐

