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

Express+Puppeteer生成PDF邮件附件Linux服务器报错求助

Puppeteer在Linux服务器启动失败的解决方案

问题背景

在Express.js项目中,通过Puppeteer实时生成PDF并作为邮件附件发送,该功能在Windows本地环境正常运行,但部署到Linux服务器时出现「启动浏览器进程失败」的错误,且需求为不在服务器存储PDF文件。

用户代码

async function generatePDF(templatePath, params) {
  try {
      const htmlTemplate = await ejs.renderFile(templatePath, params);
     const browser = await puppeteer.launch({
      headless: true,
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-gpu',
        '--disable-software-rasterizer'
      ],
      dumpio: true,
    });
      const page = await browser.newPage();
      await page.setContent(htmlTemplate, { waitUntil: 'domcontentloaded' });
      const pdfBuffer = await page.pdf({
          format: 'A4',
          printBackground: true,
      });
      await browser.close();
      return pdfBuffer; 
  } catch (error) {
      throw new Error(`PDF generation failed: ${error.message}`);
  }
}

exports.process = async (email, name) => {
  try {
    const emailBodyParams = { };
    const invitationParams = {  };
    // Generate PDF buffers
    const emailBody = await ejs.renderFile(path.join(__dirname, 'templates', 'invitation.html'), emailBodyParams);
    const invitationBuffer = await generatePDF(path.join(__dirname, 'templates', 'card.html'), invitationParams);
    const mailOptions = {
      from: '"No Reply" <no-reply@test.org>',
      to: email,
      subject: 'Your invitation',
      html: emailBody,
      attachments: [
          {
              filename: 'invitation_card.pdf',
              content: invitationBuffer,
          }
      ],
    };
    // Send the email
    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            throw new Error(error);
        }
      console.log(info);
        return true;
    });
    } catch (err) {
    throw new Error(err);
    }
}

报错信息

You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:
 Error: Error: PDF generation failed: Failed to launch the browser process!
 TROUBLESHOOTING: https://pptr.dev/troubleshooting
 at exports.processEmail (................emailProcessService.js:69:9)
 at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

解决方案

1. 安装Chrome依赖库

Linux服务器默认缺少Chrome/Chromium运行所需的系统依赖,根据发行版执行对应命令:

  • Debian/Ubuntu:
sudo apt-get update
sudo apt-get install -y libnss3 libatk-bridge2.0-0 libdrm-dev libxkbcommon-dev libgbm-dev libasound-dev libatspi2.0-0 libxshmfence-dev
  • CentOS/RHEL:
sudo yum install -y pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64

2. 手动指定Chrome可执行路径

Puppeteer可能无法自动定位到浏览器可执行文件,在launch配置中添加executablePath:

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
    '--disable-gpu',
    '--disable-software-rasterizer'
  ],
  dumpio: true,
  executablePath: '/usr/bin/google-chrome' // 用`which google-chromium`或`which chrome`查找实际路径
});

3. 缓解内存与进程限制

Linux服务器的/dev/shm临时空间有限,可通过以下参数优化:

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
    '--disable-gpu',
    '--disable-software-rasterizer',
    '--disable-features=VizDisplayCompositor',
    '--single-process' // 单进程模式减少内存占用
  ],
  dumpio: true,
});

4. 修复邮件发送的Promise捕获问题

原代码中transporter.sendMail使用回调形式,在async函数中会导致未捕获的Promise拒绝,改为Promise封装:

// 替换原邮件发送代码
await new Promise((resolve, reject) => {
  transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      reject(error);
    } else {
      console.log(info);
      resolve(true);
    }
  });
});

5. 升级Puppeteer版本

旧版Puppeteer可能与服务器上的浏览器版本不兼容,执行升级命令:

npm update puppeteer

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:54:58