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
Because that isn’t valid entrypoint, make user u already have that user in you enviroment variables
ENTRYPOINT ["dotnet", "MinimalApi.dll"]
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:
A few notes of what’s been changed here:
$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.$APP_UID
).