在 Docker 中运行 .NET 6 项目会抛出 Globalization.CultureNotFoundException

Bha*_*anu 27 azure-storage docker dockerfile asp.net-core-6.0 .net-6.0

我已成功将 API 项目从 .NET 5 升级到 .NET 6,并且在本地执行时运行良好(没有 Docker)。

我还将 Dockerfile 中的版本从“5.0-alpine3.13”更新为“ 6.0-alpine3.14 ”,如下所示(仅我所做的更改)。

ARG VERSION=6.0-alpine3.14

#Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base
EXPOSE 8080
ENV DOTNET_RUNNING_IN_CONTAINER=true \
  ASPNETCORE_URLS=http://+:8080

#Build stage
FROM mcr.microsoft.com/dotnet/sdk:$VERSION AS build
WORKDIR /src
COPY ["/src/RM.Api/RM.Api.csproj", "/src/RM.Api/"]
RUN dotnet restore "/src/RM.Api/RM.Api.csproj"
COPY . .
WORKDIR "/src/src/RM.Api"

#Publish dotnet project
FROM build AS publish
ARG BUILDCONFIG=RELEASE
RUN dotnet publish "RM.Api.csproj" -c $BUILDCONFIG -o /app/publish

#Create local user, change ownership, and copy artifacts
FROM base AS final
WORKDIR /app
RUN adduser \
  --disabled-password \
  --home /app \
  --gecos '' app \
  && chown -R app /app
USER app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RM.Api.dll"]
Run Code Online (Sandbox Code Playgroud)

但是当我在 Docker 中运行这个 .NET 6 项目时,它会在 Startup.cs 文件中引发以下 Azure.Storage 异常。

API-Startup.cs

完整的堆栈跟踪在这里。

Microsoft.Azure.Storage.StorageException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
en-US is an invalid culture identifier.
---> System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
en-US is an invalid culture identifier.
at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride)
at Microsoft.Azure.Storage.Core.Util.AuthenticationUtility.AppendCanonicalizedCustomHeaders(CanonicalizedString canonicalizedString, HttpRequestMessage request)
at Microsoft.Azure.Storage.Core.Auth.SharedKeyCanonicalizer.CanonicalizeHttpRequest(HttpRequestMessage request, String accountName)
at Microsoft.Azure.Storage.Auth.Protocol.StorageAuthenticationHttpHandler.GetSharedKeyAuthenticationTask(StorageRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Azure.Storage.Auth.Protocol.StorageAuthenticationHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<>n__0(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
--- End of inner exception stack trace ---
at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
at Microsoft.Azure.Storage.Blob.CloudBlobContainer.CreateAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
at Microsoft.Azure.Storage.Blob.CloudBlobContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
at RM.Api.Startup.ConfigureServices(IServiceCollection services) in /src/src/RM.Api/Startup.cs:line 91
Run Code Online (Sandbox Code Playgroud)

我已经更新了 Dockerfile,如下所示,但它不起作用。有人可以帮忙吗?

ARG VERSION=6.0-alpine3.14

#Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base
EXPOSE 8080
ENV DOTNET_RUNNING_IN_CONTAINER=true \
  ASPNETCORE_URLS=http://+:8080

#Build stage
FROM mcr.microsoft.com/dotnet/sdk:$VERSION AS build
WORKDIR /src
COPY ["/src/RM.Api/RM.Api.csproj", "/src/RM.Api/"]
RUN dotnet restore "/src/RM.Api/RM.Api.csproj"
COPY . .
WORKDIR "/src/src/RM.Api"

RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib

ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true

#Publish dotnet project
FROM build AS publish
ARG BUILDCONFIG=RELEASE
RUN dotnet publish "RM.Api.csproj" -c $BUILDCONFIG -o /app/publish

#Create local user, change ownership, and copy artifacts
FROM base AS final
WORKDIR /app
RUN adduser \
  --disabled-password \
  --home /app \
  --gecos '' app \
  && chown -R app /app
USER app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RM.Api.dll"]
Run Code Online (Sandbox Code Playgroud)

Emi*_*ınç 28

您的 docker 文件的基本部分应如下所示:

FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base
WORKDIR /app
RUN apk add --no-cache icu-libs
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
EXPOSE 80
EXPOSE 443
Run Code Online (Sandbox Code Playgroud)


Bha*_*anu 8

进行以下两项更改解决了该问题。

  1. 更新 Dockerfile 如下
    ARG VERSION=6.0-alpine3.14

    #Runtime stage
    FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base
    EXPOSE 8080

    ENV DOTNET_RUNNING_IN_CONTAINER=true \
      ASPNETCORE_URLS=http://+:8080
    
    RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib
    
    ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
Run Code Online (Sandbox Code Playgroud)
  1. 在 .csproj 文件中添加了以下内容

    ARG VERSION=6.0-alpine3.14

    #Runtime stage
    FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base
    EXPOSE 8080

    ENV DOTNET_RUNNING_IN_CONTAINER=true \
      ASPNETCORE_URLS=http://+:8080
    
    RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib
    
    ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
Run Code Online (Sandbox Code Playgroud)


Han*_*ian 5

您已将 ENV 语句放入 Dockerfile 的“构建”部分,这意味着它不会放置在最终映像中。将其放在“基础”部分或“最终”部分。

我将其与其他 ENV 语句一起放在“base”部分中。

如果您希望将软件安装在最终映像中,您可能还需要将其移动apk add到文件的基础部分或最后部分。