Native Deployment
Pragmatic.Imaging ships with a Rust-compiled native library (pragmatic_native.dll / .so / .dylib). This guide covers platform coverage, publish options, and Docker / container considerations.
Supported runtimes
Section titled “Supported runtimes”The NuGet package carries native binaries for the RIDs below:
| RID | File | Status |
|---|---|---|
win-x64 | pragmatic_native.dll | Shipped |
linux-x64 | libpragmatic_native.so | In progress — build locally from native/ until the CI artifact lands |
osx-arm64 | libpragmatic_native.dylib | In progress |
linux-arm64 | libpragmatic_native.so | Planned |
osx-x64 | libpragmatic_native.dylib | Planned |
linux-musl-x64 (Alpine) | — | Not planned (glibc required) |
If your target isn’t win-x64, build the native library yourself from the repo’s Pragmatic.Imaging/native/ Rust project and copy the output into runtimes/{rid}/native/ of your publish output.
Track the platform-coverage issue on GitHub for progress.
Framework-dependent deployment
Section titled “Framework-dependent deployment”For framework-dependent apps (the default dotnet publish), the native binary is picked up automatically from the NuGet’s runtimes/ folder. No extra configuration needed.
dotnet publish -c ReleaseThe native binary ends up alongside your .dlls in publish/runtimes/{rid}/native/.
Self-contained deployment
Section titled “Self-contained deployment”For self-contained apps (--self-contained true), MSBuild copies only the native binary for the target RID:
dotnet publish -c Release -r win-x64 --self-contained trueResult: the native binary is flattened into the publish output.
Native AOT
Section titled “Native AOT”The binding is AOT-compatible — no reflection or dynamic code generation.
dotnet publish -c Release -r win-x64 -p:PublishAot=trueThe native binary still lives alongside the AOT-compiled app. AOT affects the .NET code, not the Rust library.
Docker
Section titled “Docker”The native library needs glibc on Linux. Recommended base images:
mcr.microsoft.com/dotnet/runtime:10.0-bookworm-slim— Debian, worksmcr.microsoft.com/dotnet/runtime:10.0-jammy— Ubuntu, worksmcr.microsoft.com/dotnet/runtime:10.0-alpine— does NOT work (Alpine uses musl, not glibc)
For Alpine, either:
- Switch to a glibc-based image
- Build
libpragmatic_native.sotargeting musl yourself (non-trivial)
Minimal Dockerfile
Section titled “Minimal Dockerfile”FROM mcr.microsoft.com/dotnet/sdk:10.0 AS buildWORKDIR /srcCOPY . .RUN dotnet publish ./src/App -c Release -o /publish
FROM mcr.microsoft.com/dotnet/runtime:10.0-bookworm-slimWORKDIR /appCOPY --from=build /publish .ENTRYPOINT ["dotnet", "App.dll"]The runtimes/linux-x64/native/libpragmatic_native.so is copied by dotnet publish automatically.
Verifying the native binary is present
Section titled “Verifying the native binary is present”At startup, try calling a simple operation and catch the DllNotFoundException:
try{ using var _ = ImagePipeline.Load(TestFixtures.TinyPng); logger.LogInformation("Pragmatic.Imaging native library OK");}catch (DllNotFoundException ex){ logger.LogCritical(ex, "Pragmatic.Imaging native library not found — check deployment"); throw;}The library loads lazily on first use, so an app without image-processing work won’t notice a missing binary until the first request.
Building the native library yourself
Section titled “Building the native library yourself”The Rust source lives at Pragmatic.Imaging/native/:
cd Pragmatic.Imaging/nativecargo build --release# Output at target/release/libpragmatic_native.{so,dylib} or pragmatic_native.dll
# Copy into your app's runtime foldercp target/release/libpragmatic_native.so \ ../src/Pragmatic.Imaging/runtimes/linux-x64/native/Requires Rust 1.80+. See Pragmatic.Imaging/native/README.md for build instructions and feature flags.
Version compatibility
Section titled “Version compatibility”The native library and managed binding are versioned together. Mixing mismatched versions (old managed + new native, or vice versa) produces undefined behaviour — usually an immediate crash on the first FFI call.
The MSBuild targets in the NuGet ensure the binary shipped matches the managed DLL. If you build a native binary yourself, match the version tagged in Pragmatic.Imaging/native/Cargo.toml.
Troubleshooting deployment
Section titled “Troubleshooting deployment”See troubleshooting.md for common deployment issues:
- “Unable to load DLL ‘pragmatic_native’”
- Alpine / musl failures
- Self-contained publish missing the native file