EvoPdf Next for .NET is a library that can be integrated into applications running in Amazon Elastic Container Service (ECS) on AWS Fargate 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 runs in Amazon ECS tasks on AWS Fargate created from a Linux container image built on the ASP.NET Core runtime images. The image contains the application, the library runtime and the system packages required by the HTML to PDF Converter, so a new task converts from its first request. The other components don't require any additional packages.
The library targets .NET Standard 2.0, making it usable in any .NET Core application that supports this standard.
Create a new ASP.NET Core 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.
Publish the application for Linux:
dotnet publish -c Release -r linux-x64 --self-contained false -o publishCreate the Dockerfile below next to the publish folder and replace MyApp.dll with the name of your application. It starts from the ASP.NET Core runtime image, installs the system packages required by the HTML to PDF Converter, copies the publish folder and gives execute permission to the runtime files, which a publish folder created on Windows does not keep. The application listens on port 8080.
FROM mcr.microsoft.com/dotnet/aspnet:10.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/*
# Set the working directory
WORKDIR /app
# Copy the published application
COPY publish/ .
# Ensure execute permissions for the HTML to PDF Converter runtime
RUN chmod +x /app/evopdf_runtimes/linux-x64/native/evopdf_loadhtml
# Ensure execute permissions for the PDF Processor runtime
RUN chmod +x /app/evopdf_runtimes/linux-x64/native/evopdf_pdfprocessor
# Listen on port 8080
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
# Start the application
ENTRYPOINT ["dotnet", "MyApp.dll"]For an application that targets .NET 8, start from the mcr.microsoft.com/dotnet/aspnet:8.0 image; the packages are the same. Build the image for the x86_64 architecture:
docker build --platform linux/amd64 -t pdf-app .ECS loads the image from Amazon Elastic Container Registry (ECR). With the AWS CLI configured for your account, create the repository, sign in to the registry and push the image; replace the account number and the region with your own:
aws ecr create-repository --repository-name pdf-app --region eu-central-1
aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.eu-central-1.amazonaws.com
docker tag pdf-app 123456789012.dkr.ecr.eu-central-1.amazonaws.com/pdf-app:1
docker push 123456789012.dkr.ecr.eu-central-1.amazonaws.com/pdf-app:1Run the next commands in AWS CloudShell, which is already signed in to your account and region. Create the task execution role, which allows ECS to pull the image and to write the logs, the cluster and the log group. If the role already exists in your account, skip the first two commands.
aws iam create-role --role-name ecsTaskExecutionRole --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
aws ecs create-cluster --cluster-name pdf-cluster
aws logs create-log-group --log-group-name /ecs/pdf-appCreate the task.json task definition below, with your account number and region, and register it:
{
"family": "pdf-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "2048",
"memory": "4096",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" },
"containerDefinitions": [{
"name": "pdf-app",
"image": "123456789012.dkr.ecr.eu-central-1.amazonaws.com/pdf-app:1",
"essential": true,
"portMappings": [{ "containerPort": 8080 }],
"logConfiguration": { "logDriver": "awslogs", "options": {
"awslogs-group": "/ecs/pdf-app", "awslogs-region": "eu-central-1", "awslogs-stream-prefix": "pdf" } }
}]
}aws ecs register-task-definition --cli-input-json file://task.jsonHTML to PDF conversion can be resource-intensive, depending on the complexity of the content. 2 vCPUs ("cpu": "2048") and 4 GB of memory ("memory": "4096") per task are the minimum we recommend.
The commands below run a task in a public subnet of the default VPC with a security group that opens port 8080, then show its public address:
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query "Vpcs[0].VpcId" --output text)
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC Name=default-for-az,Values=true --query "Subnets[0].SubnetId" --output text)
SG=$(aws ec2 create-security-group --group-name pdf-app-sg --description "pdf-app" --vpc-id $VPC --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id $SG --protocol tcp --port 8080 --cidr 0.0.0.0/0
TASK=$(aws ecs run-task --cluster pdf-cluster --launch-type FARGATE --task-definition pdf-app \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SG],assignPublicIp=ENABLED}" \
--query "tasks[0].taskArn" --output text)
aws ecs wait tasks-running --cluster pdf-cluster --tasks $TASK
ENI=$(aws ecs describe-tasks --cluster pdf-cluster --tasks $TASK --query "tasks[0].attachments[0].details[?name=='networkInterfaceId'].value" --output text)
aws ec2 describe-network-interfaces --network-interface-ids $ENI --query "NetworkInterfaces[0].Association.PublicIp" --output textOpen the address with http:// and port 8080. For production, create an ECS service from the same task definition, with an Application Load Balancer in front of the tasks and the number of tasks that matches your load.
As a reference, in the Europe (Frankfurt) region a task with 2 vCPUs and 4 GB of memory converted a simple HTML page in about 170 ms and about 4 times per second with four parallel conversions.
You can follow the same steps to publish the EvoPdf Next ASP.NET demo application, from the EvoPdf_Next_AspNetDemo_Linux_net10.0.csproj project, with EvoPdf_Next_AspNetDemo_Linux_net10.0.dll in the Dockerfile.
The output and the exceptions of the application are written to the /ecs/pdf-app log group in CloudWatch Logs. If a task stops right after it starts, the stoppedReason of the task explains why:
aws ecs describe-tasks --cluster pdf-cluster --tasks $TASK --query "tasks[0].stoppedReason"