Search code examples
docker.net-core-3.1playwright-sharp

Playwright-sharp in .NET Core 3.1 app hosted in docker container


I have created a .NET Core 3.1 nuget library that wraps functionality around Playwright-sharp v0.192.0. I'm using this library in a REST API (also .NET Core 3.1), and locally everything is working fine. The only requirement is that the host application also needs to reference Playwright-sharp in order to download the drivers correctly. This I can live with.

The problem arises when I try to run my REST API in Docker (linux). After installing the dependencies (libc6, libgdi etc) I get this exception:

PlaywrightSharp.PlaywrightSharpException: Driver not found in any of the locations.
   at PlaywrightSharp.Transport.Connection.GetExecutablePath() in /home/runner/work/playwright-sharp/playwright-sharp/src/PlaywrightSharp/Transport/Connection.cs:line 274
   at PlaywrightSharp.Transport.Connection.GetProcess(String driverExecutablePath) in /home/runner/work/playwright-sharp/playwright-sharp/src/PlaywrightSharp/Transport/Connection.cs:line 233
   at PlaywrightSharp.Transport.Connection.InstallAsync(String driverPath, String browsersPath) in /home/runner/work/playwright-sharp/playwright-sharp/src/PlaywrightSharp/Transport/Connection.cs:line 105

One suggestion is to start with the Playwright-sharp image instead of the .NET 3.1 but it seems to me it should be a way to include the required files and place them in the correct location for this to work. My current dockerfile looks like this:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src

COPY ./PlaywrightWrapper/nuget.config .

COPY ["PlaywrightWrapper/PlaywrightWrapper.csproj", "PlaywrightWrapper/"]
RUN dotnet restore "PlaywrightWrapper/PlaywrightWrapper.csproj" --configfile nuget.config
COPY . .
WORKDIR "/src/PlaywrightWrapper"
RUN dotnet build "PlaywrightWrapper.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "PlaywrightWrapper.csproj" -c Release -r linux-x64 -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

# install depdendencies
RUN apt-get update \
&& apt-get install -y --allow-unauthenticated \
    libc6-dev \
    libgdiplus \
    libx11-dev \
 && rm -rf /var/lib/apt/lists/*

# copy the Playwright browsers from .NET build step
WORKDIR /root/.cache/ms-playwright
COPY --from=build /root/.cache/ms-playwright ./


WORKDIR /app
ENTRYPOINT ["dotnet", "PlaywrightWrapper.dll"]

This step:

WORKDIR /root/.cache/ms-playwright
COPY --from=build /root/.cache/ms-playwright ./

copies the files to the same folder as I've seen in the official Playwright-sharp docker image.

Does anyone have a working Dockerfile that installs the required Playwright drivers for headless PDF generation inside a Docker container?


Solution

  • Finally had time to look into this again, and came up with a solution.

    A couple of promising approaches using the playwrightsharp docker image (suggested here) just didn't work in my case. Still not sure exactly why, but I had to manually add all dependencies instead. Just make sure to match the playwright browser versions (npm i ..) to the Playwright Sharp NuGet package you're using (in my case 0.192.0):

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    
    RUN apt-get update && apt-get install -y --no-install-recommends \
        xvfb
    
    RUN apt-get update && apt-get install -y --no-install-recommends \
        fonts-liberation\
        libasound2\
        libatk-bridge2.0-0\
        libatk1.0-0\
        libatspi2.0-0\
        libcairo2\
        libcups2\
        libdbus-1-3\
        libdrm2\
        libgbm1\
        libglib2.0-0\
        libgtk-3-0\
        libnspr4\
        libnss3\
        libpango-1.0-0\
        libx11-6\
        libxcb1\
        libxcomposite1\
        libxdamage1\
        libxext6\
        libxfixes3\
        libxrandr2
    
     RUN apt-get update && apt-get install -y npm && \
         npm i [email protected] && \
         npm i [email protected] && \
         npm i [email protected]
     RUN apt-get remove nodejs -y
    
    ... the rest of your docker file here