c# - 无法启动 Base!/app/.local-chromium/Linux-706915/chrome-linux/chrome : . .. libX11.so.6

标签 c# docker asp.net-core-3.1 puppeteer-sharp

我有一个在 ASP.NET Core 3.1 上运行的 puppeteer-sharp 实例,它在本地运行良好。对于部署,它构建在 docker 容器中并部署到 K8 开发集群。 docker 容器构建良好,但应用程序在运行时失败并显示错误 Failed to launch Base! /app/.local-chromium/Linux-706915/chrome-linux/chrome: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory尝试使用 puppeteer-sharp 时。
从以下资源中,我拼凑了以下 dockerfile。我对 docker 仍然相当缺乏经验,所以想象一下配置有问题,但我愿意接受建议!
使用的资源:

  • http://www.hardkoded.com/blog/puppeteer-sharp-docker
  • https://techoverflow.net/2018/06/05/how-to-fix-puppetteer-error-while-loading-shared-libraries-libx11-xcb-so-1-cannot-open-shared-object-file-no-such-file-or-directory/
  • Docker NodeJS Puppeteer@2.0.0 - How do fix Failed to launch chrome! issue (headless = false 没有效果)

  • Dockerfile:
    #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
    EXPOSE 443
    
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /src
    
    #####################
    #PUPPETEER RECIPE
    #####################
    # Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)
    # Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
    # installs, work.
    ARG CHROME_VERSION="81.0.4044.138-1"
    RUN apt-get update && apt-get -f install && apt-get -y install apt-utils wget gnupg2 
    RUN apt-get -f install && apt-get -y install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils
    RUN wget --no-verbose -O /tmp/chrome.deb http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb \
    && apt-get update \
    && apt-get install -y /tmp/chrome.deb --no-install-recommends --allow-downgrades \
    && rm /tmp/chrome.deb
    
    # NOTE: REMOVED THIS WHILST DEBUGGING - D
    # Add user, so we don't need --no-sandbox.
    # same layer as npm install to keep re-chowned files from using up several hundred MBs more space    
    #RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
        #&& mkdir -p /home/pptruser/Downloads \
        #&& chown -R pptruser:pptruser /home/pptruser
    #
    ## Run everything after as non-privileged user.
    #
    #USER pptruser
    
    ENV PUPPETEER_EXECUTABLE_PATH "/usr/bin/google-chrome-unstable"
    
    #####################
    #END PUPPETEER RECIPE
    #####################
    
    
    COPY ["ProjectName.Core/ProjectName.Core.csproj", "ProjectName.Core/"]
    RUN dotnet restore "ProjectName.Core/ProjectName.Core.csproj"
    COPY . .
    WORKDIR "/src/ProjectName.Core"
    RUN dotnet build "ProjectName.Core.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "ProjectName.Core.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "ProjectName.Core.dll"]
    
    代码实现:
            public static async Task<Stream> GeneratePdfFromHtml(string html, List<string> styleUrls = null)
            {
                await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
    
                var browser = await Puppeteer.LaunchAsync(new LaunchOptions
                {
                    Headless = true                
                });
    
                using (var page = await browser.NewPageAsync())
                {
                    await page.SetContentAsync(html);
    
                    if(styleUrls != null)
                        foreach (var url in styleUrls)
                        {
                            await page.AddStyleTagAsync(url);
                        }
    
                    return await page.PdfStreamAsync();                
                }
            }
    
    使用 Docker 的资源都针对 .NET Core 2.0,所以我不知道这是否与它有关。它在 Docker 环境之外运行良好的事实表明 .NET Core 版本不是问题,更有可能是 dockerfile 本身的一个步骤。

    最佳答案

    好吧,事实证明这是一个混合的东西。 dockerfile 需要重新排列,并且在没有沙箱的情况下效果最佳。正如您将看到的,原始代码是在中间镜像而不是最终/基础上安装依赖项。
    出于某种原因,我无法让它在沙盒用户下正常工作,所以它被删除了。因此,实现需要更新以启用 --no-sandbox 参数。
    这是其他任何人都在努力使 puppeteer-sharp 与 .NET Core 3.1 一起工作的更新代码。
    dockerfile

    #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
    #####################
    #PUPPETEER RECIPE
    #####################
    # Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)
    # Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
    # installs, work.
    ARG CHROME_VERSION="81.0.4044.138-1"
    RUN apt-get update && apt-get -f install && apt-get -y install wget gnupg2 apt-utils
    RUN wget --no-verbose -O /tmp/chrome.deb http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb \
    && apt-get update \
    && apt-get install -y /tmp/chrome.deb --no-install-recommends --allow-downgrades fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf \
    && rm /tmp/chrome.deb
    
    ENV PUPPETEER_EXECUTABLE_PATH "/usr/bin/google-chrome"
    #####################
    #END PUPPETEER RECIPE
    #####################
    
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /src
    
    
    COPY ["ProjectName.Core/ProjectName.Core.csproj", "ProjectName.Core/"]
    RUN dotnet restore "ProjectName.Core/ProjectName.Core.csproj"
    
    
    COPY . .
    WORKDIR "/src/ProjectName.Core"
    RUN dotnet build "ProjectName.Core.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "ProjectName.Core.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "ProjectName.Core.dll"]
    
    实现
    public static async Task<Stream> GeneratePdfFromHtml(string html, List<string> styleUrls = null)
    {
        await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
    
        var browser = await Puppeteer.LaunchAsync(new LaunchOptions
        {
            Args = new[] { "--no-sandbox" },
            Headless = true                
        });
    
        using (var page = await browser.NewPageAsync())
        {
            await page.SetContentAsync(html);
    
            if(styleUrls != null)
                foreach (var url in styleUrls)
                {
                    await page.AddStyleTagAsync(new AddTagOptions { Path = url });
                }
    
            return await page.PdfStreamAsync();                
        }
    }
    
    可能值得注意的是,puppeteer-sharp 的 docker 实现在使用本地 url(例如 localhost:1234/lib/bootsrap/bootsrap.min.css)查找样式表时似乎也存在问题。它只是永远挂着和旋转,因此改变了 AddStyleTagAsync()改为使用文件路径。不要忘记,这是在 IHostingEnvironment.WebRootPath 下找到的,可以为您节省谷歌搜索。
    希望这可以帮助其他人。毫无疑问,在不久的将来,它也会再次出现在我的面前!

    关于c# - 无法启动 Base!/app/.local-chromium/Linux-706915/chrome-linux/chrome : . .. libX11.so.6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64292937/

    相关文章:

    c# - Protobuf-Net 序列化无法访问原型(prototype)类型的对象

    c# - 在 WebApi Controller 中使用导航属性而不是 LINQ Join

    docker - 在 Kubernetes 中使用 dind 运行私有(private)仓库

    Wcf 服务在 .NET Core 3.1 控制台应用程序中工作,但在 ASP.NET Core 3.1 Web API 中无法工作

    c# - 检测 TextBlock 在 StackPanel 中是否可见

    ubuntu - 当我在 docker 容器中启动 X 服务器时主机屏幕关闭

    linux - 如何使用 Docker 远程 API?

    asp.net-core - 使用 ASP.NET Core 启用远程错误

    asp.net-core - ASP.NET Core v3.1 应用程序真的可以独立吗?

    c# - 使用 itextsharp 将转发器控件转换为 pdf 每个重复的内容都应该出现在新页面中