DigitalOcean App Platform中Puppeteer无法找到指定路径的Chromium
在DigitalOcean App Platform上运行Puppeteer生成PDF时的浏览器启动问题
环境信息
- 平台:DigitalOcean App Platform
- Node.js版本:20.x
- Puppeteer版本:最新版
- 部署方式:通过
.aptfile安装依赖
问题描述
运行Node.js/Express应用生成PDF时,已通过.aptfile安装Chromium,但启动浏览器时提示找不到指定路径的可执行文件。
错误信息
Error generating invoice: Error: Browser was not found at the configured executablePath (/layers/digitalocean_apt/apt/usr/bin/chromium-bsu)
at ChromeLauncher.launch (/workspace/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserLauncher.js:76:19)
相关代码片段
import type { Request, Response } from "express"; import type { InvoiceRequest } from "./types/invoiceRequest"; import * as pug from "pug"; import puppeteer from "puppeteer"; import express from "express"; import fs from "fs"; const app = express(); const port = 3000; // Precompile the Pug template once at startup const compiledFunction = pug.compileFile("./templates/invoice.pug"); // Optional timeout middleware app.use((req, res, next) => { res.setTimeout(60000, () => { res.status(504).json({ error: "Request timed out." }); }); next(); }); // Middleware to parse JSON bodies app.use(express.json()); app.get("/", (req: Request, res: Response) => { res.send("Hello World!"); }); app.post( "/invoice/generate-invoice", async (req: Request<{}, {}, InvoiceRequest>, res: Response) => { console.log("Received request:", req.body); try { const invoiceData = req.body; // Calculate totals const subtotal = invoiceData.products.reduce( (sum, product) => sum + product.price, 0 ); const vat = subtotal * 0.25; // 25% VAT const total = subtotal + vat; // Format dates const invoiceDate = new Date().toISOString().split("T")[0]; const dueDate = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000) .toISOString() .split("T")[0]; // Generate HTML using Pug template const html = compiledFunction({}); // Use Puppeteer to generate the PDF from HTML const browser = await puppeteer.launch({ args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--single-process", "--no-zygote", ], executablePath: "/layers/digitalocean_apt/apt/usr/bin/chromium-bsu", }); const page = await browser.newPage(); await page.setContent(html, { waitUntil: "networkidle0" }); const pdfBuffer = await page.pdf({ format: "A4" }); await browser.close(); res.setHeader("Content-Type", "application/pdf"); res.setHeader("Content-Disposition", "attachment; filename=invoice.pdf"); res.send(pdfBuffer); // store the pdf localy fs.writeFile("invoice.pdf", pdfBuffer, (err) => { if (err) { console.error("Error saving invoice:", err); } else { console.log("Invoice saved successfully"); } }); } catch (error) { console.error("Error generating invoice:", error); res.status(500).json({ error: "Failed to generate invoice" }); } } ); app.listen(process.env.PORT || port, () => { console.log(`Example app listening at http://localhost:${port}`); });
.aptfile内容
chromium chromium-common chromium-sandbox ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 # ... [other dependencies] ...
解决方案
1. 修正Chromium可执行文件路径
chromium-bsu是一款太空射击游戏,并非浏览器可执行文件。将executablePath改为正确的Chromium路径,DigitalOcean App Platform的APT层中默认路径为:
executablePath: "/usr/bin/chromium-browser"
2. 优化Puppeteer启动参数
保留现有参数的基础上,添加适配服务器环境的参数:
args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--single-process", "--no-zygote", "--disable-gpu", // 服务器无GPU,禁用避免警告 "--font-render-hinting=none" // 优化字体渲染 ]
3. 补充.aptfile依赖
确保依赖包完整,避免运行时缺失库的错误:
chromium chromium-common chromium-sandbox ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libnss3 libx11-xcb1 libxcb-dri3-0 libxss1 libxtst6
4. 可选:使用Puppeteer自带浏览器
移除executablePath配置,Puppeteer会自动下载兼容的浏览器版本,无需手动管理Chromium安装,但会增加部署包体积。
内容的提问来源于stack exchange,提问作者Azzpr
相关产品推荐
相关产品推荐

