使用 Azure DevOps 管道部署 Azure 函数应用

发布时间:2021-02-25 07:20

我有一个函数应用程序负责接收一个配置对象,渲染一个 highcharts 图并返回一个结果的 png。如果我的函数应用在应用服务计划上运行,这可以正常工作,但在消费计划上运行时则不然。在消费计划中,我收到以下错误:

<块引用>

错误:browserType.launch:无法启动浏览器:错误:spawn /home/site/wwwroot/browsers/chromium-844399/chrome-linux/chrome EACCES

这是我的函数应用:

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import path from "path";
import { mergeDeepLeft } from "ramda";
import { chromium, ChromiumBrowser, Page } from "playwright-chromium";
import { i18n } from "./highChartsLang";

// To avoid errors in page.evaluate when referring to function only existing in template
var window: any;

const httpTrigger: AzureFunction = async function (
  context: Context,
  req: HttpRequest
): Promise<void> {
  const res = await generateChart(req.body);
  context.res = res;
};

async function generateChart(body: any) {
  try {
    // Check config
    const { config, width, height, lang = "EN" } = body;
    if (!(!!width && !!height)) {
      return { status: 400, body: "Both width and height need to be set." };
    }

    // Setup browser - THIS IS WHERE THE ERROR HAPPENS
    const browser: ChromiumBrowser = await chromium.launch({
      headless: true,
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-dev-shm-usage",
      ],
    });

    // Render chart
    const page: Page = await browser.newPage({ viewport: { width, height } });
    const pagePath = path.resolve(process.cwd(), "templating", "template.html");
    await page.goto(`file://${pagePath}`);
    await page.evaluate(
      ([chartConfig, language]) => window.renderChart(chartConfig, language),
      [
        mergeDeepLeft(config, {
          chart: { animation: false },
          credits: false,
          plotOptions: { series: { animation: false } },
        }),
        typeof lang === "string" ? i18n[lang.toUpperCase()] : lang,
      ]
    );

    // Take screenshot and return png image
    const file = await page.screenshot();

    // Clean up
    await page.close();
    await browser.close();
    return { "Content-Type": "image/png", body: file };
  } catch (err) {
    return { status: 500, body: err.toString() };
  }
}

export default httpTrigger;

这就是我构建函数应用的方式:

trigger:
  branches:
    include:
      - 'master'

# Using latest ubuntu image
pool:
  vmImage: 'ubuntu-latest'

steps:
  - task: NodeTool@0
    displayName: 'Use Node version 12.x'
    inputs:
      versionSpec: '12.x'
      checkLatest: true

  # Install and build
  - script: |
      set -e

      # Set the install directory of chromium browser
      PLAYWRIGHT_BROWSERS_PATH=$(Build.SourcesDirectory)/browsers

      # Install and build
      npm ci
      npm run build

      # In case the agent does not respect the env var above, 
      # copy the browser from the npm-cache and into the local directory
      cp -R ~/.cache/ms-playwright $(Build.SourcesDirectory)/browsers

      # Trying desperately to avoid EACCESS error
      sudo chmod -R 755 $(Build.SourcesDirectory)/browsers
    displayName: 'Install dependencies and build'

  # Archive result
  - task: ArchiveFiles@2
    displayName: 'Archive files'
    inputs:
      rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
      includeRootFolder: false

  # Publish result
  - task: PublishBuildArtifacts@1
    displayName: 'Publish Artifact: drop'

此管道将应用安装、构建和归档到 zip 文件中。然后我们有一个发布管道,它在存档上执行部署:

steps:
- task: AzureFunctionApp@1
  displayName: 'Deploy Azure Function App'
  inputs:
    azureSubscription: '$(Parameters.AzureSubscription)'
    appType: '$(Parameters.AppType)'
    appName: '$(Parameters.AppName)'
    runtimeStack: 'NODE|12'
    appSettings: '-PLAYWRIGHT_BROWSERS_PATH /home/site/wwwroot/browsers'
    configurationStrings: '-PLAYWRIGHT_BROWSERS_PATH /home/site/wwwroot/browsers'

更新

我设法使用 vsCode 在工作状态下部署它。这意味着问题正在酝酿之中。所以在这一点上,我会稍微改写这个问题并提出问题;如何使用 Azure Devops Pipeline 部署此 FA?

回答1