How to Run Aspose.Words in Docker

Microservices, in conjunction with containerization make it possible to easily combine technologies. Docker allows you to easily integrate Aspose.Words functionality into your application, regardless of what technology is in your development stack.

In case you are targeting microservices, or if the main technology in your stack is not .NET, C++ or Java, but you need Aspose.Words functionality, or if you already use Docker in your stack, then you may be interested in utilizing Aspose.Words in a Docker container.

Prerequisites

  • Docker must be installed on your system. For information on how to install Docker on Windows or Mac, refer to the links in the “See Also” section.

  • Also, note that Visual Studio 2017, .NET Core 2.2 SDK is used in the example, provided below.

Hello World Application

In this example, you create a simple Hello World console application that makes a “Hello World!” document and saves it in all supported save formats. The application can then be built and run in Docker.

Creating the Console Application

To create the Hello World program, follow the steps below:

  1. Once Docker is installed, make sure that it uses Linux Containers (default). If necessary, select the Switch to Linux containers option from the Docker Desktops menu.
  2. In Visual Studio, create a .NET Core console application.
    todo:image_alt_text
  3. Install the latest Aspose.Words version from NuGet. SkiaSharp will be installed as a dependency of Aspose.Words.
    todo:image_alt_text
  4. Since the application will be run on Linux, the appropriate native Linux assets must be installed. Start with the Debian base image and install SkiaSharp.NativeAssets.Linux.
  5. When all required dependencies are added, write a simple program that creates a “Hello World!” document and saves it in all supported save formats:
    .NET
    using Aspose.Words;
    using System;
    namespace Aspose.Words.Docker.Sample
    {
    	class Program
    	{
        	static void Main(string[] args)
        	{
            	// Create document and save it in all available formats.
            	Document doc = new Document();
            	DocumentBuilder builder = new DocumentBuilder(doc);
            	builder.Writeln("Hello from Aspose.Words!!!");
            	foreach (SaveFormat sf in Enum.GetValues(typeof(SaveFormat)))
            	{
                	if (sf != SaveFormat.Unknown)
                	{
                    	try
                    	{
                        	// The folder specified will be mounted as a volume when run the application in Docker image.
                        	doc.Save(string.Format("/TestOut/out{0}", FileFormatUtil.SaveFormatToExtension(sf)), sf);
                        	Console.WriteLine("Saving {0}\t\t[OK]", sf);
                    	}
                    	catch
                    	{
                        	Console.WriteLine("Saving {0}\t\t[FAILED]", sf);
                    	}
                	}
            	}
        	}
    	}
    }
    

Note that the “TestOut” folder is specified as an output folder for saving output documents. When running the application in Docker, a folder on the host machine will be mounted to this folder in the container. This will enable you to easily view the output generated by Aspose.Words in the Docker container.

Configuring a Dockerfile

The next step is to create and configure the Dockerfile.

  1. Create the Dockerfile and place it next to the solution file of your application. Keep this file name without extension (the default).
  2. In the Dockerfile, specify:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2
WORKDIR /app
RUN apt-get update && apt-get install -y libfontconfig1
COPY . ./
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "Aspse.Words.Docker.Sample/out/Aspse.Words.Docker.Sample.dll"]

The above is a simple Dockerfile, which contains the following instructions:

  • The SDK image to be used. Here it is the .Net Core SDK 2.2 image. Docker will download it when the build is run. The version of SDK is specified as a tag.
  • The working directory, which is specified in the next line.
  • The command to install libfontconfig1 is run in the container. This is required by SkiaSharp.
  • The command to copy everything to container, publish the application, and specify the entry point.

Building and Running the Application in Docker

Now the application can be built and run in Docker. Open your favorite command prompt, change directory to the folder with the application (folder where the solution file and the Dockerfile are placed) and run the following command:

docker build -t awtest .

The first time this command is executed it may take longer, since Docker needs to download the required images. Once the previous command is completed, run the following command:

docker run --mount type=bind,source=C:\Temp,target=/TestOut --rm awtest from Docker

Images Supporting Aspose.Words

Aspose.Words is available for both .NET Framework and .NET Core. The .NET Core images are much smaller in size than .NET Framework images, which makes the .NET Core the better choice for creating microservices and for use in containers. It is possible to deploy apps to Linux Docker containers (for cross-platform deployment), which are lighter than Windows containers.

Official images for the .NET Core SDK are provided for:

  • Debian 9 and 10
  • Ubuntu 18.04 and 19.04
  • Alpine 3.7 and 3.9
  • Windows Nano Server

To work with graphics, Aspose.Words for .NET Standard depends on SkiaSharp. This limits the images Aspose.Words can be run on to the following:

  • Debian 9 and 10
  • Ubuntu 18.04 and 19.04
  • Alpine 3.9

SkiaSharp does not work on Windows Nano Server due to a lack of some native dependencies, which is a known issue in SkiaSharp. The issue will be resolved in 1.68.1.1 version of SkiaSharp. If you need to run Aspose.Words in a Windows container, use the .NET Framework base image with the .NET Framework version of Aspose.Words, which does not depend on SkiaSharp.

SkiaSharp is a wrapper around the native Skia library. The following runtimes are provided in the SkiaSharp NuGet package:

  • osx
  • tizen-armel
  • tizen-x86
  • win10-arm
  • win10-x64
  • win10-x86
  • win-x64
  • win-x86

To run it in Linux, you should use additional NuGet packages with the corresponding native assets, such as native builds of Skia library, listed below:

  • SkiaSharp.NativeAssets.Linux – provides a native Skia build for x64 Debian based Linux distributions.
  • SkiaSharp.NativeAssets.Linux.NoDependencies – the package is intended to be used in Linux distributions that do not have the libfontconfig dependency. Tested on RHEL 7 (x64).
  • Goelze.SkiaSharp.NativeAssets.AlpineLinux – provides a native Skia build for x64 Alpine Linux 3.9.
  • Jellyfin.SkiaSharp.NativeAssets.LinuxArm – provides a native Skia build for arm32 and arm64 Debian based Linux distributions.

More Examples

  1. In the above example, the application was run in an SDK image. SDK images are heavier than runtime images. The example below demonstrates how the Docker file should be modified in order to use the SDK image to build the application, and the runtime image to run it:
    FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
    WORKDIR /app
    \# copy csproj and restore as distinct layers
    COPY Aspose.Words.Docker.Sample/*.csproj ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet restore
    \# copy and publish app and libraries
    WORKDIR /app/
    COPY Aspose.Words.Docker.Sample/. ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet publish -c Release -o out
    \# copy to runtime environment
    FROM mcr.microsoft.com/dotnet/core/runtime:2.2 AS runtime
    WORKDIR /app
    \# libfontconfig1 is required to properly work with fonts in Linux.
    RUN apt-get update && apt-get install -y libfontconfig1
    COPY --from=build /app/Aspose.Words.Docker.Sample/out ./
    ENTRYPOINT ["dotnet", "Aspose.Words.Docker.Sample.dll"]
  2. To run the application in Ubuntu 18.04, the Dockerfile remains practically the same (only the tag is changed):
    FROM mcr.microsoft.com/dotnet/core/sdk:2.2-bionic AS build
    WORKDIR /app
    \# copy csproj and restore as distinct layers
    COPY Aspose.Words.Docker.Sample/*.csproj ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet restore
    \# copy and publish app and libraries
    WORKDIR /app/
    COPY Aspose.Words.Docker.Sample/. ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet publish -c Release -o out
    \# copy to runtime environment
    FROM mcr.microsoft.com/dotnet/core/runtime:2.2-bionic AS runtime
    WORKDIR /app
    \# libfontconfig1 is required to properly work with fonts in Linux.
    RUN apt-get update && apt-get install -y libfontconfig1
    COPY --from=build /app/Aspose.Words.Docker.Sample/out ./
    ENTRYPOINT ["dotnet", "Aspose.Words.Docker.Sample.dll"]
  3. To run the application in Alpine Linux, it is required to add the SkiaSharp native assets and use the following Dockerfile:
    FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine3.9 AS build
    WORKDIR /app
    \# copy csproj and restore as distinct layers
    COPY Aspose.Words.Docker.Sample/*.csproj ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet restore
    \# copy and publish app and libraries
    WORKDIR /app/
    COPY Aspose.Words.Docker.Sample/. ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet publish -c Release -o out
    \# copy to runtime environment
    FROM mcr.microsoft.com/dotnet/core/runtime:2.2-alpine3.9 AS runtime
    WORKDIR /app
    \# fontconfig is required to properly work with fonts in Linux.
    RUN apk update && apk upgrade && apk add fontconfig
    COPY --from=build /app/Aspose.Words.Docker.Sample/out ./
    ENTRYPOINT ["dotnet", "Aspose.Words.Docker.Sample.dll"]
  4. To run the application in RHEL 7, it is required to add the SkiaSharp native assets and use the following Dockerfile:
    FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build
    WORKDIR /app
    \# copy csproj and restore as distinct layers
    COPY Aspose.Words.Docker.Sample/*.csproj ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet restore
    \# copy and publish app and libraries
    WORKDIR /app/
    COPY Aspose.Words.Docker.Sample/. ./Aspose.Words.Docker.Sample/
    WORKDIR /app/Aspose.Words.Docker.Sample
    RUN dotnet publish -c Release -o out
    \# copy to runtime environment
    FROM kkamberta/dotnet-21-rhel7 AS runtime
    WORKDIR /app
    COPY --from=build /app/Aspose.Words.Docker.Sample/out ./
    ENTRYPOINT ["/opt/rh/rh-dotnet21/root/usr/bin/dotnet", "Aspose.Words.Docker.Sample.dll"]

See Also