DinkToPdf in Docker container - dotnet core 2.2

I was busy with a project and I was required to create a pdf “report” in the project and then serve it to a user through the Angular app. So as with all things I created a POC.

Once I got the POC working then I decided to get ready to deploy so naturally I put it into a container. Thats when things got interesting, after googling around, I found a solution and here is what I came up with:


  1. Create the development space.
mkdir PdfDemoSpace
cd PdfDemoSpace 


  1. Create the dotnet webapi project

dotnet new webapi --name PdfDemo

Dependencies Management

  1. Add Dependencies for production

Copy the lib folder found the git repository: DinkToPdf-DotnetCore-Docker

  1. Add Dependencies for development
cd PdfDemo

dotnet add package DinkToPdf 

dotnet restore


  1. Startup.cs
public void ConfigureServices(IServiceCollection services)
    services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
  1. Adding the dll’s required by the package into the output folder:
<ItemGroup Condition=" '$(CONFIGURATION)' == 'Debug' ">
    <ContentWithTargetPath Include="..\lib\64bit\libwkhtmltox.dll">
<ItemGroup Condition=" '$(CONFIGURATION)' == 'Release' ">
    <ContentWithTargetPath Include="..\lib\64bit\libwkhtmltox.dll">
  1. Inject the IConverter into the controller
private IConverter _converter;
public ValuesController(IConverter converter)
    _converter = converter;
  1. Update the get action method to work with the directory and do some demo work:
        public async Task<IActionResult> Get()
            if (!Directory.Exists(Path.Combine(Directory.GetCurrentDirectory(), "reports")))
                Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "reports"));

            if(!Directory.Exists(Path.Combine(Directory.GetCurrentDirectory(), "reports", "instanceId")))
                Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "reports", "instanceId"));
            var globalSettings = new GlobalSettings
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings { Top = 10 },
                DocumentTitle = "PDF Report",
                Out = $@"{Path.Combine(Directory.GetCurrentDirectory(), "reports","instanceId")}/Employee_Report.{Guid.NewGuid()}.pdf"
            var objectSettings = new ObjectSettings
                PagesCount = true,
                HtmlContent = TemplateGenerator.GetHTMLString(),
                WebSettings = { DefaultEncoding = "utf-8", UserStyleSheet =  Path.Combine(Directory.GetCurrentDirectory(), "assets", "styles.css") },
                HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true },
                FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer" }
            var pdf = new HtmlToPdfDocument()
                GlobalSettings = globalSettings,
                Objects = { objectSettings }
            var memory = new MemoryStream();  
            using (var stream = new FileStream(globalSettings.Out, FileMode.Open))  
                 await stream.CopyToAsync(memory);  
            memory.Position = 0; 
            return File(memory, GetContentType(globalSettings.Out), Path.GetFileName(globalSettings.Out)); 
        private string GetContentType(string path)  
            var types = GetMimeTypes();  
            var ext = Path.GetExtension(path).ToLowerInvariant();  
            return types[ext];  

        private Dictionary<string, string> GetMimeTypes()
            return new Dictionary<string, string>
                {".txt", "text/plain"},
                {".pdf", "application/pdf"},
                {".doc", "application/vnd.ms-word"},
                {".docx", "application/vnd.ms-word"},
                {".xls", "application/vnd.ms-excel"},
                {".xlsx", "application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet"},  
                {".png", "image/png"},
                {".jpg", "image/jpeg"},
                {".jpeg", "image/jpeg"},
                {".gif", "image/gif"},
                {".csv", "text/csv"}

Some Demo data:

    public class DataStorage
        public List<Employee> GetAllEmployess()
            return new List<Employee>
                new Employee { Name="Mike", LastName="Turner", Age=35, Gender="Male"},
                new Employee { Name="Sonja", LastName="Markus", Age=22, Gender="Female"},
                new Employee { Name="Luck", LastName="Martins", Age=40, Gender="Male"},
                new Employee { Name="Sofia", LastName="Packner", Age=30, Gender="Female"},
                new Employee { Name="John", LastName="Doe", Age=45, Gender="Male"}

A Demo object to work with:

    public class Employee
        public string Name { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string Gender { get; set; } 

Create a template generator class

    public class TemplateGenerator
        public static string GetHTMLString()
            var employees = new DataStorage().GetAllEmployess();
            var sb = new StringBuilder();
                                <div class='header'><h1>This is the generated PDF report!!!</h1></div>
                                <table align='center'>
            foreach (var emp in employees)
                                  </tr>", emp.Name, emp.LastName, emp.Age, emp.Gender);
            return sb.ToString();


  1. The Dockerfile
FROM microsoft/dotnet:2.2-sdk AS build-env
COPY . ./
RUN dotnet publish PdfDemo.sln -c Release -o out

FROM microsoft/dotnet:2.2-aspnetcore-runtime

RUN apt update
RUN apt install -y libgdiplus
RUN ln -s /usr/lib/libgdiplus.so /lib/x86_64-linux-gnu/libgdiplus.so
RUN apt-get install -y --no-install-recommends zlib1g fontconfig libfreetype6 libx11-6 libxext6 libxrender1 wget gdebi
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN gdebi --n wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN apt install libssl1.0-dev
RUN ln -s /usr/local/lib/libwkhtmltox.so /usr/lib/libwkhtmltox.so

COPY --from=build-env /app/PdfDemo/out .
COPY lib/64bit .
ENTRYPOINT ["dotnet", "PdfDemo.dll"]


This is not a optimised solution but highlights the dependencies required and a basic workflow in getting the items working together.