skip to Main Content

I’m playing around building a self-contained .NET API to be used within Docker.
Instead of relying on the official aspnet image I decided to build a self-contained executable and use it on top of the alpine image, however I ran into the following issue:
When I’m trying to run the image I see an error saying that the executable I’m trying to run does not exist:

exec /app/api: no such file or directory

And here’s my Docker file:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
WORKDIR /app
COPY . .
RUN dotnet publish "DotnetSandbox.MinimalApi/DotnetSandbox.MinimalApi.csproj" -c Release -o /app/publish

FROM alpine AS final
USER $APP_UID
EXPOSE 5000
WORKDIR /app
COPY --from=builder /app/publish .
RUN ls /app
ENTRYPOINT ["/app/api"]

As you can see I added a ls command to see if the executable is actually copied to the output image and yes, it’s copied. I can see that at the build logs.
This is what is I see in the logs after the RUN ls /app command is executed:

api
api.pdb
appsettings.Development.json
appsettings.json

Also I tried using ["api"] as the entrypoint as well but no luck.
Is there anything I’m missing?

UPD
This is my .csproj file. No other configuration file is used.

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <InvariantGlobalization>true</InvariantGlobalization>
        <PublishReadyToRun>true</PublishReadyToRun>
        <PublishSingleFile>true</PublishSingleFile>
        <SelfContained>true</SelfContained>
        <AssemblyName>api</AssemblyName>
    </PropertyGroup>

    <ItemGroup>
      <Content Update="appsettings.Development.json">
        <DependentUpon>appsettings.json</DependentUpon>
      </Content>
    </ItemGroup>

</Project>

2

Answers


  1. Because that isn’t valid entrypoint, make user u already have that user in you enviroment variables
    ENTRYPOINT ["dotnet", "MinimalApi.dll"]

    Login or Signup to reply.
  2. This can sometimes happen when a dependency is missing or there’s a platform mismatch. Please post your publish settings. I assume these are in your project file?

    But I believe if you change your Dockerfile to the following, it will help:

    FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS builder
    ARG TARGETARCH
    WORKDIR /app
    COPY . .
    RUN dotnet publish "DotnetSandbox.MinimalApi/DotnetSandbox.MinimalApi.csproj" -a $TARGETARCH -c Release -o /app/publish
    
    FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS final
    USER $APP_UID
    EXPOSE 5000
    WORKDIR /app
    COPY --from=builder /app/publish .
    RUN ls /app
    ENTRYPOINT ["/app/api"]
    

    A few notes of what’s been changed here:

    • Use Alpine SDK image. Will give you the correct RID by default for publishing. More efficient because it uses some of the same layers as the final image.
    • Use of $BUILDPLATFORM AND $TARGETARCH. This ensures get an SDK image of the same architecture as your host machine. If you happen to be targeting an image of a differing architecture, this ensures you avoid QEMU emulation which .NET does not support.
    • Use the .NET runtime-deps for the final base image rather than the base Alpine image. This is because a self-contained .NET app still requires certain native libraries. The runtime-deps image provides these (and also defines the user identified by $APP_UID).
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search