dotnet / dotnet-docker

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

ASP.NET Core Runtime 3.1 Alpine based image gets run automatically on Alpine 3.16 #3851

Closed santoshsg1308 closed 2 years ago

santoshsg1308 commented 2 years ago

Describe the Bug

ASP.NET Core Runtime 3.1 Alpine based image mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine have started to run automatically on 3.16.

We are referencing icu=69.1-r1 in the docker file which was working fine till yesterday however we started seeing the below error without any changes to the docker file. On analysing it we see that the ASP.NET Core Runtime 3.1 Alpine based image has started pointing to 3.16 version instead of 3.15. The icu version 69.1-r1 is present in 3.15 and not 3.16. We are trying to understand the issue how the ASP.NET Core Runtime 3.1 Alpine based image version got automatically updated from 3.15 to 3.16 and want to come up with a permanent fix as we don't want to keep changing the docker file to include a new version of icu package when alpine based version of .net core runtime changes. Is there a way we can control which alpine version the .netcore runtime alpine based image can point to i.e. can we explicitly mention it should point to 3.15 version or is there any better way to handle this situation?

Steps to Reproduce

# build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine

# Install system dependencies.
RUN apk add libc-dev=0.7.2-r3 icu=69.1-r1

Other Information

Output of docker version

 > [stage-2 2/8] RUN apk add libc-dev=0.7.2-r3 icu=69.1-r1:
#7 0.504 fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/x86_64/APKINDEX.tar.gz
#7 1.079 fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/x86_64/APKINDEX.tar.gz
#7 1.628 ERROR: unable to select packages:
#7 1.663   icu-71.1-r2:
#7 1.663     breaks: world[icu=69.1-r1]
mthalman commented 2 years ago

If you're dependent on package versions from a specific version of Alpine, you should use a version-specific Alpine tag. You can see all our supported tags at https://hub.docker.com/_/microsoft-dotnet-aspnet/. In this case, you'd want 3.1-alpine3.15. The 3.1-alpine tag gets moved to new versions of Alpine as they become supported.

santoshsg1308 commented 2 years ago

Thanks for a prompt reply......so will changing to FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine3.15 instead of FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine work ?

I see we went ahead with the build being successfull but just wanted to ensure any other .net core dependencies were not affected by this change in the docker file?

Also do we need to change the below command for the sdk version as well?

# build aspnetcore app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-netcore
mthalman commented 2 years ago

Thanks for a prompt reply......so will changing to FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine3.15 instead of FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine work ?

Yes, that will give you the latest servicing version of .NET Core 3.1 on Alpine 3.15. Note that the Alpine 3.15 tags will only be supported for 3 more months now that support for Alpine 3.16 is available (see platform support doc). So you'll want to ensure your dependencies have been updated to transition to Alpine 3.16 by that time.

Also do we need to change the below command for the sdk version as well?

# build aspnetcore app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-netcore

If that tag has been working for you, there's no need to update it. Because the tag only specifies a .NET version and not a Linux distro version, you're getting Debian Linux by default (Debian 10, in this case). It's perfectly reasonable to use Debian 10 to build your .NET project to be deployed for an Alpine container, assuming that you've configured your publish settings appropriately with a RID which would have to be the case if it's been working for you. Note that you could remove the core portion of the repo name so it's just mcr.microsoft.com/dotnet/sdk:3.1 (see https://github.com/dotnet/dotnet-docker/discussions/3674).

santoshsg1308 commented 2 years ago

Can you please advise what could be the reason that icu=69.1-r1 version works fine with alpine version 3.15 but icu=71.1-r2 doesn't work with alpine version 3.16 even though it builds successfully.

We see a runtime error as below after deploying the updated icu and alpine version image

How do we ensure we always keep the icu version uptodate with the alpine version changing, as in this case we started facing problems as the specific version icu=69.1-r1 was not present in alpine version 3.16 ?

mthalman commented 2 years ago

Please see the discussion at https://github.com/dotnet/dotnet-docker/issues/3844. The ICU data has been split into a separate package. So in addition to installing icu, you'd also need to install icu-data-full in order to have other locales available.

santoshsg1308 commented 2 years ago

Using the below code now works for icu=69.1-r1

# build aspnetcore app
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build-netcore
# build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine3.15
# Install system dependencies.
RUN apk add libc-dev=0.7.2-r3 icu=69.1-r1

However I still get the same runtime error above when the system tries to execute icu-library related code using alpine3.16 version with icu=71.1-r2 image

This is what I changed from the working version above to try getting it to work for alpine3.16

# build aspnetcore app
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build-netcore
# build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine
# Install system dependencies.
RUN apk add libc-dev icu-data-full icu
mthalman commented 2 years ago

Ok, that exception looks to be coming from your code though. I would suggest debugging to see why it's not able to find what it needs.

mthalman commented 2 years ago

@santoshsg1308 - Have you had a chance to debug through the code to determine whether this is an issue in your own code and not .NET?

santoshsg1308 commented 2 years ago

We can't find anything wrong in the code as the place it throws exception wasn't changed for months and below is what it does

                using (var transliteratorLatn = Icu.Transliterator.CreateInstance("Any-Latn"))
                {
                    return transliteratorLatn.Transliterate(input, textMultiplier);
                }

Below are nuget packages we are using for icu image

There is something not quite right with alpine3.16 version and icu=71.1-r2 when the same code worked fine with alpine3.15 version and icu=69.1-r1. As a temporary fix we explicitly added 3.15 tag and using icu=69.1-r1, but any insights from you please on any differences in alpine3.16 version with icu=71.1-r2 as opposed to 3.15 using icu=69.1-r1 would be helpful!

mthalman commented 2 years ago

I see. From the callstack you shared, it looked like the exception was being thrown from your code but it's actually coming from icu.net: https://github.com/sillsdev/icu-dotnet/blob/d10b5ead8939668963cbf1565766dea01aef4acf/source/icu.net/NativeMethods/NativeMethods.cs#L291. I would suggest logging an issue in that repo because it doesn't appear to be compatible with Alpine 3.16 or at least may require a certain configuration in that environment.

Closing this since this is outside the scope of the .NET container images.

damsad commented 2 years ago

From what I see in the release notes of the Alpine 3.16 https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.16.0#ICU_data_split the ICU was split into 2 separate packages. If you want to utilize a culture different than en than aside of icu-libs you have to also install icu-data-full package.

santoshsg1308 commented 2 years ago

Yes did try installing icu-data-full package as well for alpine3.16 with icu=71.1-r2 and icu-libs as you see below but still the error

# build aspnetcore app
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build-netcore
# build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine
# Install system dependencies.
RUN apk add libc-dev icu-data-full icu
damsad commented 2 years ago

This is my dockerfile and the ICU works well for me on Alpine 3.16

FROM mcr.microsoft.com/dotnet/aspnet:3.1-alpine
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
RUN apk add --no-cache icu-libs icu-data-full
santoshsg1308 commented 2 years ago

Ok thanks I will give that a try