部署到Azure后Node.js项目中的Puppeteer无法运行(本地环境正常)
部署到Azure后Node.js项目中的Puppeteer无法运行(本地环境正常)
我帮你梳理下这个问题,Azure的Linux Web App环境和本地差异挺大的,核心问题是你在GitHub Runner上安装的Chrome路径到了Azure就失效了,加上环境依赖和权限的问题,导致Puppeteer找不到浏览器。咱们一步步来调整:
1. 修正GitHub Actions部署流程
你当前在构建阶段安装Chrome并写入PUPPETEER_EXECUTABLE_PATH到.env的操作是无效的——这个路径是GitHub Runner机器上的,打包到Azure后完全不存在。直接修改你的.yml文件里的Prepare for Puppeteer步骤:
- name: Prepare for Puppeteer run: | npm uninstall puppeteer-core npm install puppeteer # 移除在Runner上安装Chrome的操作,留到Azure环境中处理
同时,删掉生成.env的那行命令,避免错误的路径被带到Azure。
2. 优化Azure启动脚本(startup.sh)
Azure的Ubuntu环境缺少Chrome运行所需的系统依赖,而且默认的/root/.cache目录你可能没有写入权限,所以调整启动脚本,补充依赖安装和Puppeteer浏览器安装步骤:
#!/bin/bash echo "Listing directory contents to debug:" ls -la /home/site/wwwroot echo "" echo "Installing Chrome dependencies..." apt-get update && apt-get install -y \ libx11-xcb1 \ libxcomposite1 \ libxcursor1 \ libxdamage1 \ libxi6 \ libxtst6 \ libnss3 \ libcups2 \ libxss1 \ libxrandr2 \ libasound2 \ libatk1.0-0 \ libatk-bridge2.0-0 \ libpangocairo-1.0-0 \ libgtk-3-0 \ libgbm1 echo "Setting up Puppeteer cache directory..." # 设置缓存到Azure有权限的目录 export PUPPETEER_CACHE_DIR="/home/site/.cache/puppeteer" mkdir -p $PUPPETEER_CACHE_DIR echo "Installing Chrome via Puppeteer..." npx puppeteer browsers install chrome echo "Starting Node.js application..." # Try server.js first, fall back to index.js, then try app.js if [ -f "/home/site/wwwroot/server.js" ]; then node server.js elif [ -f "/home/site/wwwroot/index.js" ]; then node index.js elif [ -f "/home/site/wwwroot/app.js" ]; then node app.js else echo "No main entry file found. Looking for JavaScript files:" find /home/site/wwwroot -name "*.js" -type f | head -10 exit 1 fi
3. 调整Puppeteer启动代码
去掉硬编码的executablePath配置,让Puppeteer自动寻找Azure环境中刚安装的Chrome,同时优化启动参数:
app.get("/_api/screenshot", async (req, res) => { try { const targetUrl = req.query.url || "https://example.com"; console.log("Starting browser launch..."); const browser = await puppeteer.launch({ headless: "new", // 使用新版无头模式,兼容性更好 args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--single-process", "--no-zygote", "--disable-gpu", // Azure环境不需要GPU渲染 ], // 移除executablePath配置,让Puppeteer自动查找 }); console.log("Browser launched successfully"); const page = await browser.newPage(); console.log("Navigating to:", targetUrl); await page.goto(targetUrl, { waitUntil: "networkidle0" }); console.log("Page loaded, taking screenshot"); const screenshotBuffer = await page.screenshot({ encoding: "base64" }); console.log("Screenshot taken, closing browser"); await browser.close(); res.send(`<img src="data:image/png;base64,${screenshotBuffer}" />`); } catch (error) { console.error("Error in /api/screenshot:", error); res.status(500).json({ error: "Failed to take screenshot", message: error.message, stack: error.stack, puppeteerCacheDir: process.env.PUPPETEER_CACHE_DIR || "No cache dir set", }); } });
4. 额外配置:Azure环境变量
在Azure Portal的Web App配置中,添加环境变量:
PUPPETEER_CACHE_DIR=/home/site/.cache/puppeteer
这一步是确保Puppeteer始终使用有权限的缓存目录,避免后续出现写入错误。
这么调整后,每次启动Azure Web App时,都会自动安装Chrome所需的系统依赖和Chrome浏览器本身,同时让Puppeteer能正确找到浏览器路径,应该就能解决你遇到的问题了。
备注:内容来源于stack exchange,提问作者Akshay Pagare
相关产品推荐
相关产品推荐

