dotnet-docker icon indicating copy to clipboard operation
dotnet-docker copied to clipboard

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

Open DanielLaberge opened this issue 1 year ago • 17 comments

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

DanielLaberge avatar Oct 19 '23 19:10 DanielLaberge

@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?

mthalman avatar Oct 19 '23 19:10 mthalman

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

DanielLaberge avatar Oct 19 '23 20:10 DanielLaberge

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!

richlander avatar Oct 19 '23 20:10 richlander

@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.

DanielLaberge avatar Oct 19 '23 22:10 DanielLaberge

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.

lbussell avatar Oct 19 '23 22:10 lbussell

@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 avatar Oct 19 '23 23:10 DanielLaberge

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.

DanielLaberge avatar Oct 19 '23 23:10 DanielLaberge

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.

richlander avatar Oct 20 '23 03:10 richlander

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.

DanielLaberge avatar Oct 20 '23 14:10 DanielLaberge

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.

richlander avatar Oct 20 '23 19:10 richlander

[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.

lbussell avatar Oct 26 '23 18:10 lbussell

@lbussell: Yes, thank you.

DanielLaberge avatar Oct 26 '23 20:10 DanielLaberge

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.

orjan avatar Nov 15 '23 22:11 orjan

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.

zyofeng avatar Feb 15 '24 22:02 zyofeng

@baronfel

richlander avatar Feb 15 '24 22:02 richlander

@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?

RaviTejaKaruturi avatar Apr 02 '24 13:04 RaviTejaKaruturi

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.

Aitor-ES avatar May 15 '24 06:05 Aitor-ES