You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Puppeteer运行数小时后启动浏览器失败问题求助

问题描述

使用Puppeteer进行网页数据爬取,初始运行数小时一切正常,但一段时间后会随机停止工作并报错。已查阅相关帖子及StackOverflow问题,但未解决,且报错情况与他人略有不同。

环境说明

通过GitHub workflow将代码部署至Ubuntu VPS,启动Docker容器,工作流使用专门创建的任务用户,怀疑存在权限缺失问题。

报错信息

Error: Failed to launch the browser process!
[119330:119330:0503/192600.082150:FATAL:spawn_subprocess.cc(237)] posix_spawn /root/.cache/puppeteer/chrome/linux-135.0.7049.114/chrome-linux64/chrome_crashpad_handler: Operation not permitted (1)


TROUBLESHOOTING: https://pptr.dev/troubleshooting

    at Interface.onClose (/my-app/node_modules/@puppeteer/browsers/lib/cjs/launch.js:325:24)
    at Interface.emit (node:events:531:35)
    at Interface.close (node:internal/readline/interface:528:10)
    at Socket.onend (node:internal/readline/interface:254:10)
    at Socket.emit (node:events:531:35)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

核心代码

同一VPS的Docker容器中,另一个仓库使用完全相同的Puppeteer代码却能正常运行无崩溃。

const browser = await puppeteer.launch({
  headless: true,
  args: ["--no-sandbox"],
});

try {
  const page = await browser.newPage();
  await page.goto(URL);
  await page.waitForSelector(".today");

  return await page.evaluate(() => {
    /* ... 数据处理逻辑 ... */
    return result;
  });
} catch (error: any) {
  logger.error("无法爬取数据:", error);
  return [];
} finally {
  await browser.close();
}

已尝试的解决方案

  • 将Puppeteer从v24.2.0升级至v24.7.2
  • 添加可执行路径配置/usr/bin/chromium
  • 尝试添加启动参数--disable-setuid-sandbox、--disable-dev-shm-usage、--disable-features=CrashpadHandler
  • 尝试添加--disable-crash-reporter参数

相关配置文件

Dockerfile

# 使用官方Node.js 20镜像
FROM node:20-buster

# 安装Puppeteer、Chromium和PostgreSQL客户端所需依赖
RUN apt-get update && apt-get install -y \
    fonts-liberation \
    libasound2 \
    libatk-bridge2.0-0 \
    libatk1.0-0 \
    libatspi2.0-0 \
    libcups2 \
    libdbus-1-3 \
    libdrm2 \
    libgbm1 \
    libgtk-3-0 \
    libnspr4 \
    libnss3 \
    libvulkan1 \
    libxcomposite1 \
    libxdamage1 \
    libxfixes3 \
    libxkbcommon0 \
    libxrandr2 \
    xdg-utils \
    wget \
    curl \
    chromium

# 启用corepack管理Yarn
RUN corepack enable

# 创建并设置工作目录
WORKDIR /bot-feed

# 先复制package文件(优化缓存)
COPY package.json yarn.lock ./

# 安装依赖
RUN yarn install

# 复制TS源码及其他文件
COPY . .

# 启动机器人
CMD ["yarn", "run", "start"]

docker-compose.yml

services:
  bot-feed:
    build: .
    image: twitter-bot:1.0.0
    container_name: twitter-bot
    env_file:
      - .env
    networks:
      - cr-station

networks:
  cr-station:
    driver: bridge

github-workflow.yml

name: Deployment Workflow

on:
  push:
    branches: ["main"]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 🛠️ 检出代码
        uses: actions/checkout@v3

      - name: 🚀 部署代码
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          source: "./"
          target: "~/bot-feed"

      - name: 🚀 在VPS上执行部署命令
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd ~/bot-feed
            yarn install
            yarn run docker

问题分析与解决方案

核心原因

报错指向chrome_crashpad_handler启动失败,提示"Operation not permitted",结合环境来看,主要有两个可能:

  1. 容器内用户权限问题:当前Docker容器以root用户运行,Puppeteer默认在/root/.cache下下载Chrome,后续运行时可能因权限变更或系统安全模块限制,导致无法启动crashpad进程。
  2. 缓存目录冲突:虽然安装了系统级Chromium,但Puppeteer仍优先使用自行下载的Chrome版本,多次运行后缓存目录权限可能出现异常。

针对性解决方案

1. 在Docker容器内创建非root用户运行

容器以root运行存在安全风险,也容易触发权限限制,修改Dockerfile添加非root用户:

# ... 原有内容 ...

# 创建非root用户并赋予工作目录权限
RUN useradd -m appuser && chown -R appuser:appuser /bot-feed
USER appuser

# 启动机器人
CMD ["yarn", "run", "start"]

2. 强制Puppeteer使用系统安装的Chromium

避免Puppeteer自行下载Chrome,指定系统Chromium路径并禁用crashpad相关功能:
修改Puppeteer启动配置:

const browser = await puppeteer.launch({
  headless: true,
  args: [
    "--no-sandbox",
    "--disable-setuid-sandbox",
    "--disable-dev-shm-usage",
    "--disable-features=CrashpadHandler",
    "--disable-crash-reporter"
  ],
  executablePath: "/usr/bin/chromium",
  defaultViewport: null,
});

同时在Dockerfile中添加环境变量,禁止Puppeteer下载浏览器:

# ... 原有内容 ...

# 添加环境变量,禁用Puppeteer自动下载浏览器
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium

# ... 原有内容 ...

3. 检查VPS的安全限制

确认VPS是否启用了SELinux或AppArmor,这些安全模块可能阻止容器内进程启动crashpad。可临时关闭测试:

# 临时关闭SELinux
sudo setenforce 0
# 临时关闭AppArmor
sudo systemctl stop apparmor

如果关闭后恢复正常,需配置相应规则允许容器内进程操作。

验证建议

修改配置后重新部署,观察是否仍出现随机崩溃。由于另一个仓库能正常运行,可对比两个仓库的Docker镜像构建日志,确认是否存在依赖或权限差异。


内容的提问来源于stack exchange,提问作者Neeko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:23:09