Deploy SkiaSharp on a container running .NET 6 Alpine Linux
Asked Answered
A

2

5

SkiaSharp fails at runtime when deployed to an alpine linux container, using .NET 6.0 with the following error:

System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibSkiaSharp: cannot open shared object file: No such file or directory at SkiaSharp.SkiaApi.sk_colortype_get_default_8888() at SkiaSharp.SKImageInfo..cctor() --- End of inner exception stack trace --- at ZXing.SkiaSharp.Rendering.SKBitmapRenderer.Render(BitMatrix matrix, BarcodeFormat format, String content, EncodingOptions options) at ZXing.BarcodeWriter`1.Write(String contents)

I have tried (with no effect)

  • Adding a reference to SkiaSharp.NativeAssets.Linux
  • Swapping with a reference to SkiaSharp.NativeAssets.Linux.NoDepedencies
  • Swapping with a reference to StoneCold.SkiaSharp.NativeAssets.AlpineLinux
  • Rolling back version from 2.88.3 to 2.80.3
  • Copying libSkiaSharp.so /usr/lib/
  • Adding my publish directory to LD_LIBRARY_PATH

Project file

  <ItemGroup>
    <PackageReference Include="SkiaSharp" Version="2.80.3" />
    <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.3" />
    ...
  </ItemGroup>

My current Dockerfile (simplified)

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
WORKDIR /src
COPY . .
WORKDIR "/src/Web"
RUN dotnet build "Web.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Web.csproj" -c Release -o /app/publish -r alpine-x64 --no-self-contained

FROM base AS final
RUN apt-get update \
    && apt-get install -y libfontconfig1 fontconfig \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/publish/
WORKDIR /app
COPY --from=publish /app/publish .
COPY --from=publish /app/publish/libSkiaSharp.so /usr/lib/
ENV ASPNETCORE_URLS=http://*:5000 
ENTRYPOINT ["dotnet", "Web.dll"]

Any help would be appreciated.

Update: Working Solution Thanks @omajid

FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
WORKDIR /src
COPY . .
WORKDIR "/src/Web"
RUN dotnet build "Web.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Web.csproj" -c Release -o /app/publish -r linux-musl-x64 --no-self-contained

FROM base AS final
RUN apk update \
    && apk --no-cache add icu-libs fontconfig ttf-dejavu
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS=http://*:5000 
ENV DOTNET_RUNNING_IN_CONTAINER=true
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
ENTRYPOINT ["dotnet", "Web.dll"]
Actinomycete answered 14/10, 2022 at 0:35 Comment(0)
S
5

You are targeting your application for alpine, but you are running it in the final container, which is based on base:

FROM base AS final

And base is just

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base

And that's a Debian 11 image:

$ podman run -it mcr.microsoft.com/dotnet/aspnet:6.0 /bin/bash
root@61566364141c:/# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

So, you probably want to switch the base container to alpine before running it? Alternatively, target linux-x64 instead of alpine-x64?

Also, Microsoft's recommendation is to use generic RIDs (eg, linux-musl-x64, or linux-arm64) instead of specific ones (eg alpine-x64 or rhel.8-arm64).

Servomechanism answered 14/10, 2022 at 13:35 Comment(1)
Great pick-up thank you! I'm suprised i have not encountered any issues with this set-up previously.Actinomycete
W
2

For .net 8.0, I figured out my issue from this question itself and https://github.com/wkhtmltopdf/wkhtmltopdf/issues/4775 . Here is my solution

  1. Need to update Dockerfile
  2. Need to install SkiaSharp.NativeAssets.Linux OR SkiaSharp.NativeAssets.Linux.NoDependencies into your project. Either one works. Without this you will have exception (in Linux)

My simplified Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src


...
...
...


FROM base AS final
RUN apt-get update \
    && apt-get install -y libfontconfig
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]

Notice RUN apt-get update && apt-get install -y libfontconfig is the fix

Whereinto answered 21/2 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.