HeadlessChromium.Puppeteer.Dotnet.OS.Fork
1.2.1.3
dotnet add package HeadlessChromium.Puppeteer.Dotnet.OS.Fork --version 1.2.1.3
NuGet\Install-Package HeadlessChromium.Puppeteer.Dotnet.OS.Fork -Version 1.2.1.3
<PackageReference Include="HeadlessChromium.Puppeteer.Dotnet.OS.Fork" Version="1.2.1.3" />
<PackageVersion Include="HeadlessChromium.Puppeteer.Dotnet.OS.Fork" Version="1.2.1.3" />
<PackageReference Include="HeadlessChromium.Puppeteer.Dotnet.OS.Fork" />
paket add HeadlessChromium.Puppeteer.Dotnet.OS.Fork --version 1.2.1.3
#r "nuget: HeadlessChromium.Puppeteer.Dotnet.OS.Fork, 1.2.1.3"
#:package HeadlessChromium.Puppeteer.Dotnet.OS.Fork@1.2.1.3
#addin nuget:?package=HeadlessChromium.Puppeteer.Dotnet.OS.Fork&version=1.2.1.3
#tool nuget:?package=HeadlessChromium.Puppeteer.Dotnet.OS.Fork&version=1.2.1.3
HeadlessChromium.Puppeteer.Lambda.Dotnet
Packages everything you need to run PuppeteerSharp in AWS Lambda or a Docker container on Chromium into a Nuget Package
Description
The chromium binary for this project has been extracted from the NPM project Sparticuz/chromium. It is automatically extracted to /tmp/chromium at runtime. For now, the chromium binary only supports x86_64
Supported platforms, auto-detected at runtime:
- AWS Lambda
dotnet8/dotnet10(Amazon Linux 2023 based). - Ubuntu 22.04 LTS Docker containers (e.g.
mcr.microsoft.com/dotnet/runtime:10.0-based images before they moved to 24.04, or anyubuntu:22.04-based image). Ubuntu 22.04 reuses the AL2023 dependency bundle - it was validated to run unmodified in a vanillaubuntu:22.04container, since AL2023's bundled shared libraries (NSS, NSPR, expat) satisfy what Ubuntu 22.04 needs and there is no separate Sparticuz-published Ubuntu build. - Chainguard / Wolfi containers (e.g.
cgr.dev/chainguard/aspnet-runtime, or any Wolfi-based image reportingID=wolfiorID=chainguard). Wolfi reuses the AL2023 dependency bundle and addswolfi.tar.bron top of it, which carrieslibsqlite3.so.0- see below. End-to-end renders of both a local document and a live HTTPS page on the real image confirm the combination. See the assumptions below.
Why Wolfi needs an extra archive
A dependency walk of the Sparticuz binary resolves every library it links against from either the image or al2023.tar.br, which is why Wolfi first looked like a pure reuse of the AL2023 bundle. It is not. The first time a page needs TLS, NSS loads its PKCS#11 module libsoftokn3.so with dlopen(), and that module needs libsqlite3.so.0 for the SQLite-backed certificate database. Amazon Linux and Ubuntu ship libsqlite3.so.0 in the base image; Chainguard's distroless images do not, and failing NSS initialisation is fatal:
ERROR:crypto/nss_util.cc:256 Error initializing NSS with a persistent database
(sql:/tmp/.local/share/pki/nssdb): libsqlite3.so.0: cannot open shared object file
FATAL:crypto/nss_util.cc:146 nss_error=-5925
Chromium aborts there, so the symptom reaching the caller is a TargetClosedException or NavigationException ("Target closed", "the remote party closed the WebSocket connection") in the middle of GoToAsync - and only for pages fetched over the network. Rendering a local document via SetContentAsync never touches NSS and keeps working, which is what makes this failure easy to miss.
payloads/wolfi.tar.br supplies the library, is extracted only on Wolfi, and is regenerated by tools/build-wolfi-payload.sh.
Chainguard / Wolfi assumptions
Chainguard support relies on three properties of the shipping images, all verified rather than assumed:
- Non-root, uid 65532. The images run as
nonrootwithAPP_UID=65532. Chromium and its libraries are extracted to/tmp, which is mode1777and therefore the one location this uid can write to. A read-only root filesystem is not supported -/tmpis hardcoded. - Distroless. There is no shell, so nothing can be diagnosed from inside a running container. Every failure path is therefore reported through log output and exception messages; enable
DEBUGlogging to see them. - x86_64 only. The Sparticuz Chromium payload is x86_64. Chainguard also publishes arm64 images, which this library cannot serve.
No change to your Dockerfile is required - no apk packages, no hand-installed Chromium. See sample/SampleAspNet-chainguard/ for a working ASP.NET example.
Platform detection
Platform detection runs automatically and needs no configuration in the common case:
- If the
CHROMIUM_PLATFORM_OVERRIDEenvironment variable is set to a supported value (al2023,ubuntu-22.04, orwolfi- withchainguardaccepted as an alias forwolfi), it's used immediately. - Otherwise,
/etc/system-release-cpeis checked for Amazon Linux 2023. - Otherwise,
/etc/os-releaseis checked. Matching is on theIDfield (falling back toNAMEwhenIDis absent), compared against known identifiers:ubuntuwithVERSION_ID="22.04", orwolfi/chainguard. Wolfi'sVERSION_IDis a rolling build date and is deliberately ignored.
If none of the above match - an invalid override value, or an unrecognized OS - ExtractChromium() throws a ChromiumExtractionException. The message names the OS that was detected, lists the supported platform identifiers, and points at CHROMIUM_PLATFORM_OVERRIDE. A caller that knows better can still set ChromiumExtractor.OperatingSystem before calling ExtractChromium(), which bypasses detection entirely.
Troubleshooting
Enable DEBUG-level logging on ChromiumExtractor to see which detection method was used and what platform was resolved. A ChromiumExtractionException mentioning the supported platform list means detection failed (invalid CHROMIUM_PLATFORM_OVERRIDE value, or no matching OS file) - set CHROMIUM_PLATFORM_OVERRIDE explicitly to unblock it, e.g.:
docker run -e CHROMIUM_PLATFORM_OVERRIDE=ubuntu-22.04 myimage
docker run -e CHROMIUM_PLATFORM_OVERRIDE=wolfi myimage
Upgrading
Unrecognized platforms now fail fast. Previously, when platform detection could not resolve a platform, a WARNING was logged and the OS-specific dependency archive was simply skipped. Chromium then failed later with a dynamic-linker error, which on a distroless image is close to undiagnosable. ExtractChromium() now throws a ChromiumExtractionException at that point instead.
- If you already set
ChromiumExtractor.OperatingSystembefore callingExtractChromium(), nothing changes - that still bypasses detection. - If you relied on warn-and-continue and set the platform afterwards, move the assignment before the call, or set
CHROMIUM_PLATFORM_OVERRIDE. - On a supported platform, nothing changes.
The unreleased chainguard-20230214 platform identifier has been removed in favour of wolfi. It never shipped in a release and its detection could never fire, so no consumer can depend on it; chainguard is accepted as an alias for wolfi.
Usage
Screenshot a URL as a byte[].
var browserLauncher = new HeadlessChromiumPuppeteerLauncher(logger);
using(var browser = await browserLauncher.LaunchAsync())
using(var page = await browser.NewPageAsync())
{
await page.GoToAsync(url);
return await page.ScreenshotDataAsync();
}
For more use cases see the PuppeteerSharp documentation
Projects using this library
These projects are using this library and are good examples of how you might consume this nuget package
Building
To build locally:
.\build.ps1 -Target Build
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.Extensions.Logging (>= 8.0.0)
- Mono.Posix.NETStandard (>= 1.0.0)
- PuppeteerSharp (>= 25.3.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.