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"]
Advertisement
Answer
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
).