在 Linux 上的 azure 函数节点上部署时,Puppeteer 抛出启动异常
Puppeteer throws launch exception when deployed on azure functions node on Linux
问题:使用 puppeteer 获取网站的屏幕截图。在开发机器上工作正常,但在部署到云上的 Azure Functions 时抛出以下异常。
环境:在 Azure 上(节点 12,Linux,消费计划),函数使用服务总线主题触发。
错误:
Result: Failure Exception: Error: Failed to launch the browser process! spawn
/home/site/wwwroot/node_modules/puppeteer/.local-chromium/linux-818858/chrome-linux/chrome
EACCES TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
Stack: Error: Failed to launch the browser process!
spawn /home/site/wwwroot/node_modules/puppeteer/.local-chromium/linux-818858/chrome-linux/chrome
EACCES TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
at onClose (/home/site/wwwroot/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:193:20)
at ChildProcess.<anonymous> (/home/site/wwwroot/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:185:85)
at ChildProcess.emit (events.js:314:20) at Process.ChildProcess._handle.onexit (internal/child_process.js:274:12)
at onErrorNT (internal/child_process.js:470:16) at processTicksAndRejections (internal/process/task_queues.js:84:21)
我遵循了 puppeteer 故障排除文档中的建议,但仍然遇到同样的问题。
我尝试过的午餐设置
let browser = await puppeteer.launch({ ignoreDefaultArgs: ['--disable-extensions'] });
let browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
let browser = await puppeteer.launch({ headless: true });
let browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
以上的 None 有效。他们都抛出相同的错误。
我在函数中检查了 FTPing,chrome 文件 puppeteer 正在寻找,存在。
提前致谢。
Azure 在 Linux 消费计划中具有 运行 headless Chromium 的必要依赖项。所以我们可以使用Azure函数中的包puppeteer
。但是我们需要使用远程构建来部署应用程序。详情请参考Azure feedback and the blog.
例如
创建 Azure 函数应用
创建 Azure 函数项目
一个。安装包
npm install puppeteer
b。 function.json
{
"bindings": [
{
"name": "mySbMsg",
"type": "serviceBusTrigger",
"direction": "in",
"topicName": "bowman1012",
"subscriptionName": "test",
"connection": "bowman1012_SERVICEBUS"
},
{
"type": "blob",
"direction": "out",
"name": "outputBlob",
"path": "outcontainer/{rand-guid}.png",
"connection": "AzureWebJobsStorage"
}
]
}
c。代码
const puppeteer = require("puppeteer");
module.exports = async function (context, mySbMsg) {
context.log(
"JavaScript ServiceBus topic trigger function processed message",
mySbMsg
);
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto("https://google.com/");
const screenshotBuffer = await page.screenshot({ fullPage: true });
await browser.close();
context.bindings.outputBlob = screenshotBuffer;
};
- 在根项目文件夹中添加
.funcignore
文件
*.js.map
*.ts
.git*
.vscode
local.settings.json
test
tsconfig.json
node_modules
- 部署到 Azure
func azure functionapp publish $appName --build remote
- 测试
更新
由于您使用 typescript 创建 Azure 函数,我们需要更新 .funcignore
如下
*.js.map
.git*
.vscode
local.settings.json
test
node_modules
例如
我的函数代码index.ts
import { AzureFunction, Context } from "@azure/functions";
import { ServiceBusMessage } from "@azure/service-bus";
import puppeteer from "puppeteer";
import { BlobServiceClient } from "@azure/storage-blob";
const serviceBusTopicTrigger: AzureFunction = async function (
context: Context,
mySbMsg: ServiceBusMessage
): Promise<void> {
try {
const promotionId = context.bindingData.userProperties.promotionId;
context.log(
"Player Screen Grabber ServiceBus topic trigger function processing message started",
promotionId
);
const playerURL = "https://www.google.com/";
let browser = await puppeteer.launch({ headless: true });
let page = await browser.newPage();
await page.goto(playerURL, { waitUntil: "networkidle2" });
await page.setViewport({ width: 1920, height: 1080 });
const screenshotBuffer = await page.screenshot({
encoding: "binary",
});
await page.close();
await browser.close();
// the storage account connection string
const constr = process.env["AzureWebJobsStorage"] + "";
const blobserviceClient = BlobServiceClient.fromConnectionString(constr);
const containerClient = blobserviceClient.getContainerClient(
"outcontainer"
);
const blob = containerClient.getBlockBlobClient(`${promotionId}.png`);
await blob.uploadData(screenshotBuffer);
context.log(
"Player Screen Grabber ServiceBus topic trigger function processing message ended",
promotionId
);
} catch (error) {
throw error;
}
};
export default serviceBusTopicTrigger;
部署到 Azure
func azure functionapp publish $appName --build remote
测试
我的服务总线消息
结果
问题:使用 puppeteer 获取网站的屏幕截图。在开发机器上工作正常,但在部署到云上的 Azure Functions 时抛出以下异常。
环境:在 Azure 上(节点 12,Linux,消费计划),函数使用服务总线主题触发。
错误:
Result: Failure Exception: Error: Failed to launch the browser process! spawn
/home/site/wwwroot/node_modules/puppeteer/.local-chromium/linux-818858/chrome-linux/chrome
EACCES TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
Stack: Error: Failed to launch the browser process!
spawn /home/site/wwwroot/node_modules/puppeteer/.local-chromium/linux-818858/chrome-linux/chrome
EACCES TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
at onClose (/home/site/wwwroot/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:193:20)
at ChildProcess.<anonymous> (/home/site/wwwroot/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:185:85)
at ChildProcess.emit (events.js:314:20) at Process.ChildProcess._handle.onexit (internal/child_process.js:274:12)
at onErrorNT (internal/child_process.js:470:16) at processTicksAndRejections (internal/process/task_queues.js:84:21)
我遵循了 puppeteer 故障排除文档中的建议,但仍然遇到同样的问题。
我尝试过的午餐设置
let browser = await puppeteer.launch({ ignoreDefaultArgs: ['--disable-extensions'] });
let browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
let browser = await puppeteer.launch({ headless: true });
let browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
以上的 None 有效。他们都抛出相同的错误。
我在函数中检查了 FTPing,chrome 文件 puppeteer 正在寻找,存在。
提前致谢。
Azure 在 Linux 消费计划中具有 运行 headless Chromium 的必要依赖项。所以我们可以使用Azure函数中的包puppeteer
。但是我们需要使用远程构建来部署应用程序。详情请参考Azure feedback and the blog.
例如
创建 Azure 函数应用
创建 Azure 函数项目
一个。安装包
npm install puppeteer
b。 function.json
{
"bindings": [
{
"name": "mySbMsg",
"type": "serviceBusTrigger",
"direction": "in",
"topicName": "bowman1012",
"subscriptionName": "test",
"connection": "bowman1012_SERVICEBUS"
},
{
"type": "blob",
"direction": "out",
"name": "outputBlob",
"path": "outcontainer/{rand-guid}.png",
"connection": "AzureWebJobsStorage"
}
]
}
c。代码
const puppeteer = require("puppeteer");
module.exports = async function (context, mySbMsg) {
context.log(
"JavaScript ServiceBus topic trigger function processed message",
mySbMsg
);
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto("https://google.com/");
const screenshotBuffer = await page.screenshot({ fullPage: true });
await browser.close();
context.bindings.outputBlob = screenshotBuffer;
};
- 在根项目文件夹中添加
.funcignore
文件
*.js.map
*.ts
.git*
.vscode
local.settings.json
test
tsconfig.json
node_modules
- 部署到 Azure
func azure functionapp publish $appName --build remote
- 测试
更新
由于您使用 typescript 创建 Azure 函数,我们需要更新 .funcignore
如下
*.js.map
.git*
.vscode
local.settings.json
test
node_modules
例如
我的函数代码index.ts
import { AzureFunction, Context } from "@azure/functions";
import { ServiceBusMessage } from "@azure/service-bus";
import puppeteer from "puppeteer";
import { BlobServiceClient } from "@azure/storage-blob";
const serviceBusTopicTrigger: AzureFunction = async function (
context: Context,
mySbMsg: ServiceBusMessage
): Promise<void> {
try {
const promotionId = context.bindingData.userProperties.promotionId;
context.log(
"Player Screen Grabber ServiceBus topic trigger function processing message started",
promotionId
);
const playerURL = "https://www.google.com/";
let browser = await puppeteer.launch({ headless: true });
let page = await browser.newPage();
await page.goto(playerURL, { waitUntil: "networkidle2" });
await page.setViewport({ width: 1920, height: 1080 });
const screenshotBuffer = await page.screenshot({
encoding: "binary",
});
await page.close();
await browser.close();
// the storage account connection string
const constr = process.env["AzureWebJobsStorage"] + "";
const blobserviceClient = BlobServiceClient.fromConnectionString(constr);
const containerClient = blobserviceClient.getContainerClient(
"outcontainer"
);
const blob = containerClient.getBlockBlobClient(`${promotionId}.png`);
await blob.uploadData(screenshotBuffer);
context.log(
"Player Screen Grabber ServiceBus topic trigger function processing message ended",
promotionId
);
} catch (error) {
throw error;
}
};
export default serviceBusTopicTrigger;
部署到 Azure
func azure functionapp publish $appName --build remote
测试
我的服务总线消息
结果