dotnet / dotnet-docker

Docker images for .NET and the .NET Tools.
https://hub.docker.com/_/microsoft-dotnet
MIT License
4.44k stars 1.93k forks source link

Provide an official ASP.NET alpine-extra image with globalization support (ICU and tzdata) #4955

Open DanielLaberge opened 11 months ago

DanielLaberge commented 11 months ago

Please reconsider providing an official alpine-extra image for ASP.NET (and runtime) that supports globalization.

This announcement mentions:

We don't plan to offer runtime and aspnet images based on 8.0-jammy-chiseled-extra. We will re-consider that if there is sufficient demand.

Currently, we are either forced to:

This goes against the "Batteries included and Choose your own adventure" themes in the announcement. We would like to concentrate on developing apps, not maintaining custom containers.

Thank you.

EDIT: For anyone looking to get the smallest image in the meantime, you can use the the runtime-deps:8.0-alpine-extra image like this:

dotnet publish --os linux-musl --self-contained true -p:ContainerBaseImage=mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra -p:PublishProfile=DefaultContainer

mthalman commented 11 months ago

@DanielLaberge - based on the referenced issue at https://github.com/dotnet/sdk-container-builds/issues/512, I'm assuming this is in the context of wanting to use the SDK container publishing feature and that you don't want to have to maintain your own Dockerfile. Is that correct?

DanielLaberge commented 11 months ago

@mthalman That is correct. I will edit the issue to reflect that.

richlander commented 11 months ago

You could use self-contained deployment with the runtime-deps:8.0-alpine-extra image with SDK OCI publishing. Can you share why that isn't satisfactory?

This goes against the "Batteries included and Choose your own adventure" themes in the announcement.

I'm glad that folks read our announcements!

DanielLaberge commented 11 months ago

@richlander I will gladly try this and report my results if someone could point me to relevant documentation on how to achieve this with an ASP.NET app.

I've tried adding the following to my .csproj: <ContainerBaseImage>mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra</ContainerBaseImage>

Then building with dotnet publish --os linux --arch x64 --self-contained true -p:PublishProfile=DefaultContainer -c Release But running the container produces this error: exec /app/MyAppName: no such file or directory

I assume I must be missing some step, but I couldn't find relevant documentation or examples.

lbussell commented 11 months ago

Could you try adding the argument --self-contained true to your publish command, or adding <SelfContained>true</SelfContained> property to your csproj?

Also adding @baronfel.

DanielLaberge commented 11 months ago

@lbussell I indeed had the <SelfContained>true</SelfContained> property in my .csproj but forgot to mention it in my last comment. I'll edit it to avoid further confusion.

DanielLaberge commented 11 months ago

I have reproduced the same error with a blank ASP.NET template like so:

mkdir aspnet-alpine-extra-test && cd aspnet-alpine-extra-test
dotnet new webapp
dotnet publish --os linux --arch x64 --self-contained true -p:ContainerBaseImage=mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra -p:PublishProfile=DefaultContainer -c Release
docker run aspnet-alpine-extra-test:latest
exec /app/aspnet-alpine-extra-test: no such file or directory

However, if I don't specify the ContainerBaseImage, it defaults to mcr.microsoft.com/dotnet/runtime-deps:8.0.0-rc.2 (based on Debian 12 instead of runtime-deps:8.0-alpine-extra) and then runs successfully. Clearly there is something missing.

richlander commented 11 months ago

Switch to:

dotnet publish --os linux-musl 

You are saying "I want an app compatible with Linux glibc" when you want one compatible with musl (what Alpine uses).

If you are building on x64, then you can skip --arch x64. Also -c Release can be skipped. That's now the default for dotnet publish.

After we get this resolved, you can try trimming to try to make the image smaller, with -p:PublishTrimmed=true.

We have not rejected the overall request. It makes sense to see if this works.

DanielLaberge commented 11 months ago

Specifying --os linux-musl does indeed work. Thank you for that.

I wasn't aware of this detail, being unfamiliar with alpine images. The error message produced when calling dotnet publish --self-contained -p:PublishProfile=DefaultContainer without specifying --os is misleading in that regard as it doesn't mention 'linux-musl'.

error MSB4018: Microsoft.NET.Build.Containers.BaseImageNotFoundException: The RuntimeIden 
tifier 'win-x64' is not supported by dotnet/runtime-deps:8.0-alpine-extra. 
The supported RuntimeIdentifiers are linux-x64,linux-arm,linux-arm64

I think this discussion illustrates why an official aspnet alpine-extra image might be helpful to the community; allowing everyone to benefit from the smallest possible image without this kind of friction and specific required knowledge. It would be as simple as setting -p:ContainerFamily=alpine-extra.

Thank you for the consideration.

richlander commented 11 months ago

Can you file a bug on dotnet/sdk with your findings on supported RuntimeIdentifiers. You are correct with your interpretation. Only linux-musl variants should be offered there.

Part of the reason that Alpine images are smaller is because they use a different libc variant called musl. That makes Alpine incompatible with software compiled for Ubuntu, for example. This is a generic problem. For example Project Portola was established to create a Java port for Alpine. We didn't make such a big deal of doing the work, but it wasn't cheap.

This complexity leaks out to users. This is what RIDs are for. We've tried to hide that with this -a and --os arguments. Still, you need to know how linux and linux-musl are different. This isn't needed in a Dockerfile if you use the Alpine SDK since dotnet publish defaults to linux-musl in that context. With SDK publish run on your dev machine (likely not Alpine), then you need to address this inherent targeting complexity.

I hope that explanation helps.

lbussell commented 11 months ago

[Triage] @DanielLaberge, it seems like your problem is resolved, right?

We will leave this issue open in order to collect feedback on whether there is more demand for runtime- and aspnet-extra images.

DanielLaberge commented 11 months ago

@lbussell: Yes, thank you.

orjan commented 10 months ago

Globalization and the icu support are pretty important features.

--self-contained is working with runtime-deps:8.0-jammy-chiseled-extra but it would introduce around 100MB for every single build and application. If there was an aspnet:8.0-jammy-chiseled-extra we could use --no-self-containted.

Having a small image might be important but safe by default and making it simple to do the right thing is even more important. No root user and no shell are awesome features in that regards.

zyofeng commented 7 months ago

I would definitely appreciate this change, we are currently using dotnet publish in combination with ContainerFamily to build the containers.

at the moment we have to use -p:ContainerFamily=jammy-chiseled-extra but if there is an equivalent -p:ContainerFamily=alpine-extra that would be great.

richlander commented 7 months ago

@baronfel

RaviTejaKaruturi commented 6 months ago

@richlander

Can you please clarify few question? I am using dotnet cli 8.0.203 I have created webapi app using cli and added following in .csproj file <ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:8.0.3-jammy-chiseled-extra</ContainerBaseImage> published & run using following commands.

dotnet publish -t:PublishContainer
docker run --rm -d -p 8000:8080 webapidemo

I am able to access the API.

I want to try the same with Alpine, so I followed this issue. Command I have used is this

dotnet publish -t:PublishContainer --os linux-musl \
--self-contained -p:PublishTrimmed=true \
-p:ContainerBaseImage=mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra 

When I try to run the container using above command and access the API it returns 500 error. Doesn't above command include dotnet runtime & aspnet in the image? I thought --self-contained does that. How should I resolve this?

Also, is there a way to output dockerfile generated by publish command?

Aitor-ES commented 4 months ago

We would greatly benefit from having aspnet alpine-extra images at my company. Right now, we have many of our services running on the base alpine image but, as Entity Framework Core needs ICU to work, we have to install ICU manually with Dockerfiles. Having more options is never bad, and support for Entity Framework Core on aspnet Alpine would be appreciated by lots of developers.