EvoPdf Next for .NET is a library that can be integrated into Azure Functions for Linux to create and process PDF documents.
You can create PDF documents, convert HTML, Word, Excel, RTF and Markdown documents to PDF, extract text and images from existing PDF documents, perform text search operations on PDF documents and convert PDF pages to images.
EvoPdf Next for .NET is compatible with 64-bit applications hosted on Azure Functions for Linux. Before running your application, additional system packages must be installed in the Azure environment. The next sections provide detailed setup instructions.
The library targets .NET Standard 2.0, allowing it to be used in any .NET Core application that supports this standard.
Create a new .NET project in Visual Studio and use the NuGet Package Manager to add a reference to the EvoPdf.Next.Linux NuGet metapackage which will install all the library components.
To install only specific components of the EvoPdf Next library you can add references to the corresponding NuGet packages. You can find more details about the available packages in the Getting Started on Linux documentation section.
After installing the package, add the using EvoPdf.Next; directive at the top of your source files to access the EvoPdf Next API.
Code examples and usage details can be found in the Getting Started on Linux documentation section.
Deploying to Azure Functions on Linux is more challenging than to Azure App Service. A function app created and published from Visual Studio runs from its deployment package: the WEBSITE_RUN_FROM_PACKAGE application setting is 1, the application folder is read-only, only folders such as /tmp can be written and the runtime files have no execute permission. The next sections describe the configuration for this case.
The HTML to PDF Converter component requires several native Linux libraries. These must be installed in the Azure Functions environment before running your application.
The PDF Processor component has no additional dependencies but it still requires copying the runtime to a writable location where you can grant execute permission. The other components don't require any additional setup.
The EvoPdf Next library provides an API to install the required dependencies and perform the necessary configuration steps.
A function app deployed as a zip archive extracted in the application folder runs the runtime in place, as described in Deploy a Zip Archive Extracted in the Application Folder. A function app deployed as a container image needs no configuration at all, as described in Deploy the Function App as a Container Image, the option we recommend for production.
The easiest approach is to call the InstallationConfigureRuntime(Boolean, String, String, Boolean) method in your .NET application to configure the runtime for the HTML to PDF Converter component running in Azure Functions on Linux.
This method allows you to specify a Bash script that will be executed before the first HTML to PDF or image conversion. It tracks whether the script has already run and ensures that it runs again only after the application restarts.
To use the PDF Processor component, you can call the PdfProcessorInstallationConfigureRuntime(Boolean, String) method in your .NET application to configure the runtime for the PDF Processor component running in Azure Functions on Linux.
To install only the required dependency packages, add the following line of code before the first call to the HTML to PDF or HTML to Image converter. You can call the method multiple times, but only the first call sets up the configuration. Subsequent calls will be ignored.
Installation.ConfigureRuntime(true, null, "apt update && apt install -y libnss3 libatk-bridge2.0-0 libcairo2 libpango-1.0-0");Additionally, to use the PDF Processor component, add the following line of code before the first call to a PDF Processor component. You can call the method multiple times, but only the first call sets up the configuration. Subsequent calls will be ignored.
PdfProcessorInstallation.ConfigureRuntime(true, null);HTML to PDF conversion can be resource-intensive depending on the complexity of the content, so proper sizing of the hosting plan is important.
When publishing, select the App Service plan or Premium as the Plan Type in the Visual Studio publish profile wizard. The Consumption and Flex Consumption plans are not suitable for running the converter.
The minimum supported hosting plan is B2 (2 cores, 3.5 GB RAM). The Free plan is also not suitable for Azure Functions running the converter.
For production scenarios or heavy workloads, a Premium plan such as P1v3 (2 vCPUs, 8 GB RAM) or higher is strongly recommended.
When configuring the publish profile, select Portable as the target runtime.
Finally, publish the application to Azure Functions on Linux.
Although configuring the environment through .NET code is the preferred method for maintaining consistency across restarts, you can alternatively install the required dependencies manually using the SSH console. Follow the steps below to configure the Linux environment for Azure Functions.
Before publishing your application, set the full path to the evopdf_loadhtml executable in your .NET code. This path should point to a writable location such as /tmp where the runtime files will be copied later.
converter.HtmlLoaderFilePath = "/tmp/evopdf_runtimes/linux-x64/native/evopdf_loadhtml";If you are also using the PDF Processor, set the full path to the evopdf_pdfprocessor executable in your .NET code. This path should point to a writable location such as /tmp where the runtime files will be copied later.
pdfProcessorComponent.PdfLoaderFilePath = "/tmp/evopdf_runtimes/linux-x64/native/evopdf_pdfprocessor";Publish your Azure Function using the same deployment options previously described for the .NET code-based configuration method.
After the application is published, continue with the environment setup to install the required packages as described in the steps below.
Open the Azure Portal, navigate to your Azure Function, then go to Development Tools → SSH and click the Go button to open the SSH console.
Run the following command to install the required Linux packages:
apt update && apt install -y libnss3 libatk-bridge2.0-0 libcairo2 libpango-1.0-0Copy the runtime files to the /tmp directory:
cp -r /home/site/wwwroot/evopdf_runtimes /tmp/evopdf_runtimesThen grant execution permission to the loader binary:
chmod +x /tmp/evopdf_runtimes/linux-x64/native/evopdf_loadhtmlIf you are also using the PDF Processor component grant execution permission to its binary as well:
chmod +x /tmp/evopdf_runtimes/linux-x64/native/evopdf_pdfprocessorA function app created with the Azure CLI and deployed with the az functionapp deployment source config-zip command does not run from its deployment package. The zip archive is extracted in the /home/site/wwwroot application folder, where the runtime files can be executed, so the runtime does not have to be copied. A function app created this way keeps running the runtime in place when it is later published from Visual Studio, which sets the WEBSITE_RUN_FROM_PACKAGE application setting only on the function apps it creates.
In the Azure portal open Cloud Shell in Bash mode and create the function app on a Linux App Service plan. The storage account name must be unique in Azure; replace mystorage with your own name and set --runtime-version to the .NET version of your project.
az group create --name pdf-app-rg --location eastus
az appservice plan create --name pdf-plan --resource-group pdf-app-rg --is-linux --sku B2
az storage account create --name mystorage --resource-group pdf-app-rg --sku Standard_LRS
az functionapp create --name pdf-func --resource-group pdf-app-rg --plan pdf-plan \
--storage-account mystorage --functions-version 4 \
--runtime dotnet-isolated --runtime-version 10 --os-type LinuxIn your code, configure the runtime without copying it, as in Azure App Service on Linux. The PDF Processor component needs no configuration in this case.
Installation.ConfigureRuntime(false, null, "apt update && apt install -y libnss3 libatk-bridge2.0-0 libcairo2 libpango-1.0-0");Publish the application to a folder and create a zip archive with the content of the publish folder at its root. In File Explorer, open the publish folder, select all its content and choose Send to > Compressed (zipped) folder. Then deploy the archive with the Azure CLI:
dotnet publish -c Release -o publish
az functionapp deployment source config-zip --name pdf-func --resource-group pdf-app-rg --src publish.zipThe archive contains the HTML to PDF Converter runtime and is larger than the files Cloud Shell accepts for upload, so run the deployment command on a computer with the Azure CLI installed. The first conversion after the application starts installs the packages and takes longer than the next ones.
A function app can run from a Linux container image built on the Azure Functions base image for the .NET isolated worker, with the packages required by the HTML to PDF Converter installed in the image. The application starts without installing anything and needs no runtime configuration in code. Container images run on App Service plans and Premium plans.
Publish the application for Linux and create the Dockerfile below next to the publish folder:
dotnet publish -c Release -r linux-x64 --self-contained false -o publishFROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated10.0
# Install the packages required by the HTML to PDF Converter
RUN apt-get update && \
apt-get install -y \
libnss3 \
libatk-bridge2.0-0 \
libcairo2 \
libpango-1.0-0 && \
rm -rf /var/lib/apt/lists/*
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
# Copy the published function app
COPY publish/ /home/site/wwwroot
# Ensure execute permissions for the HTML to PDF Converter and PDF Processor runtimes
RUN chmod +x /home/site/wwwroot/evopdf_runtimes/linux-x64/native/evopdf_loadhtml \
/home/site/wwwroot/evopdf_runtimes/linux-x64/native/evopdf_pdfprocessorFor a function app that targets .NET 8, start from the mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0 image. Build the image, push it to an Azure Container Registry as described in Publish to Azure Container Apps and create the function app from the image in Cloud Shell:
docker build --platform linux/amd64 -t pdf-func .
az functionapp create --name pdf-func --resource-group pdf-app-rg --plan pdf-plan \
--storage-account mystorage --functions-version 4 \
--image myregistry.azurecr.io/pdf-func:1 --registry-server myregistry.azurecr.io \
--registry-username myregistry \
--registry-password "$(az acr credential show --name myregistry --query 'passwords[0].value' -o tsv)"The function app pulls the image when it starts, which takes a few minutes the first time.
With all dependencies installed and configurations completed, your application is ready to run.