I implemented a functionality to capture a webpage screenshot and convert it into an image. Initially, I tried using Puppeteer, but it didn't work on Azure. Then, I attempted to use Playwright to achieve the same functionality, but I am encountering issues when running it from an Azure Function.
Microsoft.Playwright.PlaywrightException: Driver not found: /home/.playwright/node/linux-x64/node
at Microsoft.Playwright.Helpers.Driver.GetExecutablePath() in /_/src/Playwright/Helpers/Driver.cs:line 96
at Microsoft.Playwright.Transport.StdIOTransport.GetProcess(String driverArgs) in /_/src/Playwright/Transport/StdIOTransport.cs:line 116
at Microsoft.Playwright.Transport.StdIOTransport..ctor() in /_/src/Playwright/Transport/StdIOTransport.cs:line 46
at Microsoft.Playwright.Playwright.CreateAsync() in /_/src/Playwright/Playwright.cs:line 43
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = true,
Args =
[
"--no-sandbox", "--disable-gpu", "--disable-setuid-sandbox", "--disable-dev-shm-usage"
]
});
I am using Azure Flex consumption plan to deploy azure function. I am tried creating startup.sh script and run in Program.cs to install necessary packages. Function is deployed using Azure DevOps Pipeline.
Microsoft.Playwright.PlaywrightException: Driver not found: /home/.playwright/node/linux-x64/node
The error occurred because the Flex Consumption environment doesn't support Playwright's required browser drivers and binaries. It has limitations on file system access, installing runtime dependencies and running startup scripts, which makes it incompatible with Playwright.
So, I used an App Service Plan instead. I successfully deployed the Function project using the Azure DevOps Pipeline to the Azure Function App and got the output.
Azure DevOps Pipeline YAML File :
trigger:
- main
variables:
azureSubscription: '<subscription>'
functionAppName: 'kamnetap2'
vmImageName: 'windows-latest'
workingDirectory: '$(System.DefaultWorkingDirectory)/'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: DotNetCoreCLI@2
displayName: Build
inputs:
command: 'build'
projects: |
$(workingDirectory)/*.csproj
arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: 'development'
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- task: AzureFunctionApp@2
displayName: 'Azure functions app deploy'
inputs:
connectedServiceNameARM: '$(azureSubscription)'
appType: functionApp
appName: $(functionAppName)
package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
Azure Function App Output :