c# IronPdf 在 Linux Docker 下关闭.NET 6 Web API

G.D*_*mov 8 c# asp.net-web-api docker ironpdf .net-6.0

版本

  • 用于 PDF 导出的单独 .NET 6.0 Web API
  • IronPdf.Linux - 2022.5.5629
  • IronPdf.Native.Chrome.Linux - 2022.5.5618

截至编写最新 IronPdf Linux NuGet 包之日
在此输入图像描述

问题

当我在 Docker Linux Container 下运行 .NET 6 Web API 时,当我点击 IronPdf 中的第一个方法时,应用程序会自行关闭this.pdfRenderer.RenderHtmlAsPdfAsync。没有错误或进入catch块,只是应用程序停止,我必须再次运行它。

我尝试了什么?代码

我正在关注 IronPdf 提供的官方文档:https ://ironpdf.com/docs/questions/docker-linux/

这是我的用例以及我如何使用 IronPdf 库:

[HttpGet]
[Route("Reporting/PDF/{reportItemId:int}"]
public async Task<IActionResult> GenerateReport(int reportItemId)
{
    try
    {
        IronPdf.Logging.Logger.EnableDebugging = true;
        IronPdf.Logging.Logger.LogFilePath = "Default.log"; //May be set to a directory name or full file
        IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;

        IronPdf.Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled;
        Installation.LinuxAndDockerDependenciesAutoConfig = false;
        IronPdf.Installation.Initialize();

        ReportItemViewModel reportItemViewModel = this.reportingManager.GetReportItemById(reportItemId); // Internal Logic
        List<PdfDocument> pdfDocs = new List<PdfDocument>();

        foreach (int itemsectionId in reportItemViewModel.ReportItemSectionIds)
        {
            PdfDocument pdfDocument = await CreatePDFDocument(itemsectionId);
            
            pdfDocs.Add(pdfDocument);
        }

        PdfDocument mergedPdfs = IronPdf.PdfDocument.Merge(pdfDocs);

        await AddFooterToPdfDocument(mergedPdfs);
        
        // ... getting mergedPdfs.Stream and uploading it

        return Ok();
    }
    catch (Exception ex)
    {
        this.diagnosticService.AddErrorLog(ex: ex, accountId: accountId, employeeId: employeeId);
        return BadRequest(ex.Message);
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码片段中,我包含了建议的自动依赖项安装、禁用 GPU 加速和“提前”初始化,如 IronPdf 库中所述。

从 IronPdf 库调用的第一个方法位于方法内部CreatePDFDocument- await this.pdfRenderer.RenderHtmlAsPdfAsync

private async Task<PdfDocument> CreatePDFDocument(int itemsectionId)
{
    try
    {
        this.pdfRenderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
        this.pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = true;
        this.pdfRenderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;

        this.pdfRenderer.RenderingOptions.MarginLeft = 6.35;
        this.pdfRenderer.RenderingOptions.MarginRight = 6.35;
        this.pdfRenderer.RenderingOptions.MarginBottom = 12;

        this.pdfRenderer.RenderingOptions.Timeout = 120;
        this.pdfRenderer.RenderingOptions.HtmlHeader = new IronPdf.HtmlHeaderFooter
        {
            HtmlFragment = await this.viewRenderer.ConvertToStringAsync("Reports/_Header", itemsectionId)
        };

        string viewAsString =
           await this.viewRenderer.ConvertToStringAsync("Reports/ReportContainer", itemsectionId);

        PdfDocument pdfDocument = await this.pdfRenderer.RenderHtmlAsPdfAsync(
              viewAsString,
              new Uri(this.BaseUrl));

        return pdfDocument;
    }
    catch (Exception ex)
    {
        this.diagnosticService.AddErrorLog(ex: ex, accountId: account.Id, employeeId: employeeId);
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我们点击该await this.pdfRenderer.RenderHtmlAsPdfAsync方法时,应用程序就会关闭。我们不会进入catch阻塞状态或在某个地方抛出错误。我尝试传递非常简单的 HTML 代码<div><h1>Hello World, from IronPdf under Docker Linux</h1></div>,然后应用程序再次关闭。

注意:通过上面给出的代码流程,我已经成功提取了数百个 PDF。仅当尝试使用 Linux Docker 映像构建和运行项目时才会出现此问题。

Docker配置

右键单击该项目并选择Add-> Docker support...-> Target OS->Linux创建所需的Dockerfile.
在此输入图像描述

我正在修改Dockerfile以匹配上面链接中提供的 IronPdf 支持。Debian Linux DockerFiles我正在尝试->部分下提供的一个Debian 11 with .NET 6

# base runtime image (Debian 11 w/ .NET6 runtime)
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 1433
EXPOSE 3306
# install necessary packages
RUN apt update \
    && apt install -y libgdiplus libxkbcommon-x11-0 libc6 libc6-dev libgtk2.0-0 libnss3 libatk-bridge2.0-0 libx11-xcb1 libxcb-dri3-0 libdrm-common libgbm1 libasound2 libxrender1 libfontconfig1 libxshmfence1
# update write permissions
RUN chmod 777 .
# base development image (Debian 11 w/ .NET6 SDK)
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# restore NuGet packages
COPY ["Example.Export/Example.Export.csproj", "Example.Export/"]
RUN dotnet restore "Example.Export/Example.Export.csproj"
# build project
COPY . .
WORKDIR "/src/Example.Export"
RUN dotnet build "Example.Export.csproj" -c Release -o /app/build
# publish project
FROM build AS publish
RUN dotnet publish "Example.Export.csproj" -c Release -o /app/publish
# run app
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Example.Export.dll"]
Run Code Online (Sandbox Code Playgroud)

我正在启动该项目,一切正常:
在此输入图像描述
在此输入图像描述

await this.pdfRenderer.RenderHtmlAsPdfAsync编辑 1:我在调用该方法(项目停止后)后立即提供 Docker 日志。(注意:我包括了最后 X 行,因为整个日志非常大并且没有错误)

13:47:16 (139776153876224): Found job 2 in group 1 (of 1 groups)
13:47:16 (139776153876224): Found job 2 in group 1 (of 1 groups)
13:47:16 (139776153876224): Printing from browser to '/tmp/pdfzwqWbJ'
13:47:16 (139776153876224): Printing from browser to '/tmp/pdfzwqWbJ'
13:47:16 (139776153876224): Received browser print callback for path '/tmp/pdfzwqWbJ' (1)
13:47:16 (139776153876224): Received browser print callback for path '/tmp/pdfzwqWbJ' (1)
13:47:16 (139776153876224): Print finished for browser 2(success: 1)
13:47:16 (139776153876224): Print finished for browser 2(success: 1)
13:47:16 (139776153876224): Resolving job for browser 2 with 80743 bytes
13:47:16 (139776153876224): Resolving job for browser 2 with 80743 bytes
13:47:16 (139776153876224): PdfDocumentFactory created document 0x7f201403a860 from 80743 bytes
13:47:16 (139776153876224): PdfDocumentFactory created document 0x7f201403a860 from 80743 bytes
13:47:16 (139776153876224): Resolving job for browser 2 with 1 page document
13:47:16 (139776153876224): Resolving job for browser 2 with 1 page document
13:47:16 (139776153876224): Generating bytes for document 0x7f201403a860
13:47:16 (139776153876224): Generating bytes for document 0x7f201403a860
13:47:16 (139776153876224): Successfully generated 80751 bytes for document 0x7f201403a860
13:47:16 (139776153876224): Successfully generated 80751 bytes for document 0x7f201403a860
13:47:16 (139776153876224): PdfDocumentFactory closed document 0x7f201403a860
13:47:16 (139776153876224): PdfDocumentFactory closed document 0x7f201403a860
13:47:16 (139776153876224): Closing browser 2
13:47:16 (139776153876224): Closing browser 2
13:47:16 (139776153876224): Destroying browser (id:2)
13:47:16 (139776153876224): Destroying browser (id:2)
13:47:16 (139776153876224): Finished job 2
13:47:16 (139776153876224): Finished job 2
13:47:16 (139776153876224): Found job 2 in group 1 (of 1 groups)
13:47:16 (139776153876224): Found job 2 in group 1 (of 1 groups)
13:47:16 (139776153876224): Job group 1 finished
13:47:16 (139776153876224): Job group 1 finished
13:47:16 (139776153876224): Job group 1 has overlays
13:47:16 (139776153876224): Job group 1 has overlays
13:47:16 (139776153876224): Retrieved 80751 bytes for job group 1 page 0 overlay 2
13:47:16 (139776153876224): Retrieved 80751 bytes for job group 1 page 0 overlay 2
13:47:16 (139776153876224): PdfDocumentFactory created document 0x7f201403a860 from 7745 bytes
13:47:16 (139776153876224): PdfDocumentFactory created document 0x7f201403a860 from 7745 bytes
13:47:16 (139776153876224): Applying overlay to page 0
13:47:16 (139776153876224): Applying overlay to page 0
13:47:16 (139776153876224): PdfDocumentFactory created document 0x7f202024d270 from 80751 bytes
13:47:16 (139776153876224): PdfDocumentFactory created document 0x7f202024d270 from 80751 bytes
13:47:16 (139776153876224): PdfDocumentFactory closed document 0x7f202024d270
13:47:16 (139776153876224): PdfDocumentFactory closed document 0x7f202024d270
13:47:16 (139776153876224): Generating bytes for document 0x7f201403a860
13:47:16 (139776153876224): Generating bytes for document 0x7f201403a860
13:47:16 (139776153876224): Successfully generated 88299 bytes for document 0x7f201403a860
13:47:16 (139776153876224): Successfully generated 88299 bytes for document 0x7f201403a860
13:47:16 (139776153876224): PdfDocumentFactory closed document 0x7f201403a860
13:47:16 (139776153876224): PdfDocumentFactory closed document 0x7f201403a860
13:47:16 (139776153876224): Successfully applied overlays
13:47:16 (139776153876224): Successfully applied overlays
13:47:16 (139776153876224): CefMessagePumpStd::Quit()
13:47:16 (139776892073728): PdfDocumentFactory closed document 0x7f2050020740
13:47:16 (139776153876224): CefMessagePumpStd::Quit()
13:47:16 (139776892073728): PdfDocumentFactory closed document 0x7f2050020740
13:47:16 (139776892073728): PdfDocumentFactory created document 0x7f2050020740 from 88299 bytes
13:47:16 (139776892073728): PdfDocumentFactory created document 0x7f2050020740 from 88299 bytes
13:47:16 (139776892073728): Storing updated document 0
13:47:16 (139776892073728): Storing updated document 0
Run Code Online (Sandbox Code Playgroud)

编辑 1 - 临时解决方案

我能够按照@ScottMildenberger 的评论中的建议临时解决该问题。更改了我部署到 Azure 的方式后,它现在正在生产中运行。

作为 Zip 部署部署到 Azure 应用服务。棘手的部分是,在Configuration“应用程序服务”部分中,我们必须更改一个应用程序设置。转到Application Settings并更改WEBSITE_RUN_FROM_PACKAGE为值为0。这将提供应用程序服务readwrite权限。我们这样做是因为IronPdf在幕后进行文件操作并且需要write访问权限。
WEBSITE_RUN_FROM_PACKAGE 或者如果您将 Azure 管道与 YML 一起使用:

# base runtime image (Debian 11 w/ .NET6 runtime)
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 1433
EXPOSE 3306
# install necessary packages
RUN apt update \
    && apt install -y libgdiplus libxkbcommon-x11-0 libc6 libc6-dev libgtk2.0-0 libnss3 libatk-bridge2.0-0 libx11-xcb1 libxcb-dri3-0 libdrm-common libgbm1 libasound2 libxrender1 libfontconfig1 libxshmfence1
# update write permissions
RUN chmod 777 .
# base development image (Debian 11 w/ .NET6 SDK)
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# restore NuGet packages
COPY ["Example.Export/Example.Export.csproj", "Example.Export/"]
RUN dotnet restore "Example.Export/Example.Export.csproj"
# build project
COPY . .
WORKDIR "/src/Example.Export"
RUN dotnet build "Example.Export.csproj" -c Release -o /app/build
# publish project
FROM build AS publish
RUN dotnet publish "Example.Export.csproj" -c Release -o /app/publish
# run app
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Example.Export.dll"]
Run Code Online (Sandbox Code Playgroud)

我仍然无法在 Docker Linux 容器下运行它。如果我修复它,我将使用解决方案再次编辑。

Gol*_*ave 3

解决方案似乎是从命令行使用 Docker。在 MacOS 内置调试​​器 docker-compose 启动设置上使用 Visual Studio (17.0.2) 时,我遇到了同样的问题。但是,当从命令行使用 Docker 时,它没有遇到问题,并且我能够一遍又一遍地重复调用“RenderHtmlAsPdfAsync”,而程序不会停止执行。所以,我认为这与与 docker 容器中附加的调试器的一些交互有关。

我已向 IronPdf 支持人员发送了一封电子邮件,他们回复了以下内容,希望对您有所帮助:

我们已意识到所描述的问题,以下几点可能有助于避免(尽管不能解决问题):

  • 删除所有调试断点
  • 在发布模式下运行
  • 在 Visual Studio 之外运行 Docker(通过 Docker 命令行)
  • 更新 Visual Studio

  • 2023年4月,我仍然遇到这个问题 (3认同)