Versions
- Separate .NET 6.0 Web API for PDF export
- IronPdf.Linux - 2022.5.5629
- IronPdf.Native.Chrome.Linux - 2022.5.5618
As of the date of writing the latest IronPdf Linux NuGet packages
Problem
When I ran the .NET 6 Web API under Docker Linux Container the app shuts down itself when I hit the first method from IronPdf this.pdfRenderer.RenderHtmlAsPdfAsync
. There is no error or going into the catch
block, simply the app stops and I have to run it again.
What have I tried? Code
I am following the official documentation provided by IronPdf: https://ironpdf.com/docs/questions/docker-linux/
Here is my usecase and how I use IronPdf library:
[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);
}
}
In the code snippet above I've included the suggested Automatic Dependency Installation, Disable GPU Acceleration and "Ahead of Time" Initialization as stated in the IronPdf librabary.
The first method to be called from IronPdf librabry is inside the CreatePDFDocument
method - 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;
}
}
When we hit the await this.pdfRenderer.RenderHtmlAsPdfAsync
method the app simply shuts down. We don't go in the catch
block or throw error somewhere. I've tried to pass it very simple HTML like <div><h1>Hello World, from IronPdf under Docker Linux</h1></div>
and the app shuts down again.
Note: With the code flow given above, I've successfully extracted hundreds of PDFs. The problem only arises when trying to build and run the project with a Linux Docker image.
Docker configuration
Right-clicking on the project and selecting Add
-> Docker support...
-> Target OS
-> Linux
creates the needed Dockerfile
.
I am modifying the Dockerfile
to match what IronPdf support provided in the link above. I am trying the one provided under the section 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"]
I am starting the project and everything runs normally:
Edit 1: I am providing the Docker logs exactly after calling the await this.pdfRenderer.RenderHtmlAsPdfAsync
method after which the project stops. (Note: I am including the last X lines, as the whole log is really big and doesn't hold an error)
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
Edit 1 - Temporary Solution
I was able to make a temporary solution to the problem as suggested in the comments by @ScottMildenberger. After changing the way I deploy to Azure it's working on production now.
Deploy to Azure App Service as Zip Deploy. The tricky part is that in the Configuration
section in the App Service we have to change one application setting. Go to Application Settings
and change WEBSITE_RUN_FROM_PACKAGE
to have a value of 0
. This gives the App Service read
and write
permissions. We do that because IronPdf
is doing file operations behind the scenes and needs write
access.
or if you are using Azure pipelines with YML:
- task: AzureTask@4
inputs:
... inputs ...
appType: 'webApp'
packageForLinux: 'path.zip'
AppSettings: '-WEBSITE_RUN_FROM_PACKAGE 0'
enableCustomDeployment: true
DeploymentType: 'zipDeploy'
TakeAppOfflineFlag: false
I am still not able to run it under the Docker Linux container. In case I fix it, I will edit again with the solution.