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

在Elastic Beanstalk(Amazon Linux 2023)上使用Puppeteer生成PDF时遭遇‘Could not find Chrome’错误的可靠解决方法求助

在Elastic Beanstalk(Amazon Linux 2023)上使用Puppeteer生成PDF时遭遇‘Could not find Chrome’错误的可靠解决方法

我最近在Node.js应用里用Puppeteer生成PDF发票,本地测试完全正常,但部署到基于Amazon Linux 2023的Elastic Beanstalk(EB)时,一直碰到Chrome找不到的错误。之前用第三方脚本安装Chrome经常导致EB部署卡住超时,折腾了好几天终于找到稳定的解决方案,分享给同样踩坑的朋友:

我的问题背景

本地运行时,Puppeteer能自动找到Chrome,生成PDF毫无问题。但部署到EB后,要么部署过程卡在安装Chrome的步骤,要么部署成功后调用PDF生成接口时,Puppeteer报错“Could not find Chrome”。

我之前的Puppeteer代码

const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');

function fillTemplate(html, data) {
  return html.replace(/{{(.*?)}}/g, (_, key) => data[key.trim()] ?? '');
}

async function generateInvoicePDF(filledHtml, outputFileName) {
  const browser = await puppeteer.launch({
    headless: true,
    executablePath: '/usr/bin/google-chrome',
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage'
    ]
  });
  const page = await browser.newPage();
  await page.setContent(filledHtml, { waitUntil: 'networkidle0' });

  const logoBase64 = fs.readFileSync('./public/icon.png', { encoding: 'base64' });
  
  await page.pdf({
    path: outputFileName,
    format: 'A4',
    printBackground: true,
    displayHeaderFooter: true,
    margin: {
      top: '60px',
      bottom: '60px',
      left: '15mm',
      right: '15mm'
    }
  });

  await browser.close();
  return outputFileName;
}

我之前踩坑的EB配置

# .ebextensions/01_install_chrome.config
commands:
  01_install_chrome:
    command: "curl https://intoli.com/install-google-chrome.sh | bash"

这个脚本经常因为网络波动或者执行步骤过多,导致EB部署超时卡住,即使偶尔成功,Puppeteer还是会莫名找不到Chrome。


可靠的解决步骤

1. 改用Amazon Linux 2023官方RPM安装Chrome

放弃第三方脚本,直接用Google官方的RPM包安装,EB的packages.rpm机制会自动处理依赖和安装逻辑,更稳定。

修改.ebextensions/01_install_chrome.config为:

packages:
  rpm:
    google-chrome-stable: https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm

commands:
  # 创建软链接,确保和代码里的executablePath一致
  01_create_chrome_symlink:
    command: ln -sf /usr/bin/google-chrome-stable /usr/bin/google-chrome
    test: '[ ! -f /usr/bin/google-chrome ]'

  # 安装Chrome无头运行必需的系统依赖
  02_install_system_deps:
    command: dnf install -y atk cups-libs gtk3 libXcomposite alsa-lib libXcursor libXdamage libXext libXi libXrandr libXScrnSaver libXtst pango at-spi2-atk libXt xorg-x11-server-Xvfb xorg-x11-xauth dbus-glib dbus

为什么这样做?

  • 官方RPM包的安装过程更可控,不会像第三方脚本那样有多余的步骤导致超时
  • 补充的系统依赖是Chrome无头模式运行的必要条件,缺失的话即使Chrome安装了也无法启动
  • 软链接保证代码里的/usr/bin/google-chrome路径有效

2. 优化Puppeteer启动参数

针对EB的资源限制和环境,调整Puppeteer的启动选项,尤其是无头模式和资源相关的参数:

const browser = await puppeteer.launch({
  headless: 'new', // Puppeteer v19+推荐使用新版无头模式,兼容性更好
  executablePath: '/usr/bin/google-chrome',
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage', // 解决EB实例/dev/shm空间不足的问题
    '--disable-gpu', // 无头模式不需要GPU
    '--no-zygote', // 减少进程数,降低资源占用
    '--single-process',
    '--disable-features=VizDisplayCompositor' // 避免部分环境下的渲染问题
  ]
});

关键说明:

  • headless: 'new'是Puppeteer的新版无头模式,比旧的headless: true更接近真实Chrome的行为,减少兼容性问题
  • --disable-dev-shm-usage会让Chrome用临时文件代替/dev/shm,EB实例的/dev/shm默认很小,容易导致Chrome崩溃

3. 修正静态文件路径

EB部署后,应用的根目录可能和本地不同,用相对路径读取文件容易出错,建议用path.resolve获取绝对路径:

// 替换原来的fs.readFileSync路径
const logoPath = path.resolve(__dirname, './public/icon.png');
const logoBase64 = fs.readFileSync(logoPath, { encoding: 'base64' });

这一步虽然不是Chrome找不到的直接原因,但能避免PDF生成时的资源加载错误,保证最终PDF的完整性。


验证方案有效性

  1. 重新部署EB应用:这次部署不会再超时卡住,因为RPM安装比脚本快且稳定
  2. 登录EB实例,执行google-chrome --version,确认Chrome已成功安装
  3. 调用PDF生成接口,应该能正常生成PDF,不会再报“Could not find Chrome”的错误

额外注意事项

  • 如果你使用的是puppeteer-core,请确保版本和安装的Chrome版本兼容(Puppeteer官方有版本对应表,尽量使用最新版的puppeteer-core)
  • 建议使用至少t2.small以上的EB实例,t2.micro的资源可能不足以支撑Chrome无头模式运行
  • 如果还是遇到权限问题,可以检查EB应用的运行用户(默认是webapp)是否有执行Chrome的权限,官方RPM安装的Chrome默认是全局可执行的,一般没问题

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:50:29