Azure функция HTTP-запрос 404 при публикации в Azure через Docker и Visual Studio - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь узнать больше о Azure функциях 2.0 и Docker контейнерах для публикации sh в моем Azure экземпляре. Я следовал инструкциям ниже, с той лишь разницей, что я опубликовал с docker в реестре контейнеров в azure с использованием Visual Studio 2019.

https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-your-first-function-visual-studio

Все это работало правильно, и я смог запустить свой контейнер и зайти на сайт. Однако в примере вы можете посетить / api / function1 и получить ответ. Это работает на моем локальном хосте, но на живом сайте возвращает 404. Кажется, что / api / function1 после публикации недоступен.

Приложение само возвращает это при посещении самого IP, так что я знаю, что это за работой. Нужно ли что-то еще делать в Azure, чтобы выставить свои API?

Azure screenshot working default page

Мой журнал контейнеров показывает только это.

Hosting environment: Production
Content root path: C:\
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.

Я взял отсюда свой докер-файл

https://github.com/Azure/azure-functions-docker/blob/master/host/2.0/nanoserver-1809/Dockerfile

# escape=`

# Installer image
FROM mcr.microsoft.com/windows/servercore:1809 AS installer-env

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

# Retrieve .NET Core SDK
ENV DOTNET_SDK_VERSION 2.2.402

RUN Invoke-WebRequest -OutFile dotnet.zip https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$Env:DOTNET_SDK_VERSION/dotnet-sdk-$Env:DOTNET_SDK_VERSION-win-x64.zip; `
    $dotnet_sha512 = '0fa3bf476b560c8fc70749df37a41580f5b97334b7a1f19d66e32096d055043f4d7ad2828f994306e0a24c62a3030358bcc4579d2d8d439d90f36fecfb2666f6'; `
    if ((Get-FileHash dotnet.zip -Algorithm sha512).Hash -ne $dotnet_sha512) { `
        Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
        exit 1; `
    }; `
    `
    Expand-Archive dotnet.zip -DestinationPath dotnet; `
    Remove-Item -Force dotnet.zip

ENV ASPNETCORE_URLS=http://+:80 `
    DOTNET_RUNNING_IN_CONTAINER=true `
    DOTNET_USE_POLLING_FILE_WATCHER=true `
    NUGET_XMLDOC_MODE=skip `
    PublishWithAspNetCoreTargetManifest=false `
    HOST_COMMIT=69f124faed40d20d9d8e5b8d51f305d249b21512 `
    BUILD_NUMBER=12858

RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; `
    Invoke-WebRequest -OutFile host.zip https://github.com/Azure/azure-functions-host/archive/$Env:HOST_COMMIT.zip; `
    Expand-Archive host.zip .; `
    cd azure-functions-host-$Env:HOST_COMMIT; `
    /dotnet/dotnet publish /p:BuildNumber=$Env:BUILD_NUMBER /p:CommitHash=$Env:HOST_COMMIT src\WebJobs.Script.WebHost\WebJobs.Script.WebHost.csproj --output C:\runtime


# Runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2.7-nanoserver-1809

COPY --from=installer-env ["C:\\runtime", "C:\\runtime"]

ENV AzureWebJobsScriptRoot=C:\approot `
    WEBSITE_HOSTNAME=localhost:80

CMD ["dotnet", "C:\\runtime\\Microsoft.Azure.WebJobs.Script.WebHost.dll"]

Вот мой код function1 для моей azure функции

public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string productid = req.Query["productid"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            productid = productid ?? data?.product;

            Product newProduct = new Product()
            {
                ProductNumber = 0,
                ProductName = "Unknown",
                ProductCost = 0
            };
            if (Convert.ToInt32(productid) ==1)
            {
                newProduct = new Product()
                {
                    ProductCost = 100,
                    ProductName = "Lime Tree",
                    ProductNumber = 1
                };
            }
            else if(Convert.ToInt32(productid) == 2) 
            {
                newProduct = new Product()
                {
                    ProductCost = 500,
                    ProductName = "Lemon Tree",
                    ProductNumber = 2
                };
            }
            return productid != null
                ? (ActionResult)new JsonResult(newProduct)
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }

Вот фотография моего контейнера, работающего с моим изображением.

Container image

Я новичок в этом, поэтому любой совет будет полезен наверняка!

Спасибо!

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Во-первых, я не знаю, нужно ли вам (или хотите) запускать функции для Windows контейнеров. Если вы хотите запустить в контейнере, я бы, вероятно, выбрал Linux. Для этого это пример Dockerfile. Он построен поверх базового образа, предоставленного Microsoft. Так что вам не нужно создавать это с нуля.

Я уверен, что есть также базовый образ для Windows, который уже собран. Если вам это нужно, просто посмотрите в похожем репо, я думаю.

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

COPY . ./
RUN dotnet publish myfunction -c Release -o myfunction /out

FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base
WORKDIR /app
EXPOSE 80

COPY --from=build-env /app/ao-backendfunctions/out .

ENV AzureWebJobsScriptRoot=/app
ENV AzureFunctionsJobHost__Logging__Console__IsEnabled=true

Важная часть - RUN dotnet publish myfunction -c Release -o myfunction /out. Замените myfunction именем (папки) вашей фактической функции.

0 голосов
/ 14 февраля 2020

@ silent ответ был правильным - Linux контейнеры - это путь к go для Azure функций. Моя среда не была правильно настроена для Linux контейнеров, но как только я получил правильную среду, это сработало из коробки.

Вот мой последний DockerFile для другого проекта, который использует Linux Контейнеры

См. https://aka.ms/containerfastmode, чтобы понять, как Visual Studio использует этот Dockerfile для создания ваших изображений для более быстрой отладки.

FROM mcr.microsoft.com/azure-functions/dotnet:2.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build
WORKDIR /src
COPY ["FunctionTestAppLinux/FunctionTestAppLinux.csproj", "FunctionTestAppLinux/"]
RUN dotnet restore "FunctionTestAppLinux/FunctionTestAppLinux.csproj"
COPY . .
WORKDIR "/src/FunctionTestAppLinux"
RUN dotnet build "FunctionTestAppLinux.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "FunctionTestAppLinux.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV AzureWebJobsScriptRoot=/app
...