Не удается протестировать простой Asp.net базовый веб-api, развернутый в Docker

#.net #docker #asp.net-web-api #asp.net-core

#.net #docker #asp.net-web-api #asp.net-core

Вопрос:

Я новичок в Docker и действительно хочу испытать его возможности. Здесь я хотел бы запустить простой Asp.net базовый веб-api в Docker (с использованием docker run ) вместо того, чтобы запускать его с помощью IIS.

Это просто, потому что это именно автогенерация по умолчанию ASP.NET основной проект веб-API с именем только одного контроллера ValuesController . Обычно при отладке с помощью IISExpress следующий URI должен выдавать массив значений:

 http://localhost:[some_port]/api/values
  

Теперь я добавляю поддержку Docker для проекта (используя контейнер Windows). После создания образа Docker его можно перечислить с помощью docker images . Теперь я запускаю образ Docker для размещения моего веб-api следующим образом:

 docker run -t -rm -p 80:50633 hellodocker:dev
  

Он работает нормально, и я могу проверить это с помощью docker ps . Однако, чтобы проверить, действительно ли это работает, я попытался ввести следующий адрес в браузере:

 http://localhost/api/values
  

и это не работает, ничего не отображается, и это выглядело так же, как несуществующий сайт.

Когда я пытаюсь выполнить следующую команду docker exec [container_id] netstat , она иногда показывает запись со статусом TIME_WAIT , и почти все время ее нет. Хотя я не уверен, связано ли это с внешним прослушиванием.

Вот содержимое файла Dockerfile:

 FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base
WORKDIR /app
EXPOSE 50633
EXPOSE 44322

FROM microsoft/dotnet:2.2-sdk-nanoserver-1803 AS build
WORKDIR /src
COPY HelloDocker/HelloDocker.csproj HelloDocker/
RUN dotnet restore HelloDocker/HelloDocker.csproj
COPY . .
WORKDIR /src/HelloDocker
RUN dotnet build HelloDocker.csproj -c Release -o /app

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "HelloDocker.dll"]
  

Я действительно застрял на этом. Приложение hello-world может просто распечатать простую строку, но это hellodocker должно размещаться в docker и обслуживать любые HTTP-запросы точно так же, как когда мы размещаем его в IIS.

Обновить

После попытки удалить созданный образ и вместо него перестроить другой, он выглядит иначе после запуска с той же docker run командой выше:

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

Как и раньше, ничего не отображается, и корневой путь запроса становится C:app .
Итак, на этот раз кажется более очевидным, что он прослушивает запросы. Однако он все еще не работает.

Комментарии:

1. Какой порт по умолчанию для сервера hello-world? Вы уверены, что это так 50633 ?

2. @Jack Gore Я не совсем уверен, это то, что я предположил, основываясь на dockerfile , вы можете увидеть строку EXPOSE 50633

Ответ №1:

Перед вашей инструкцией ENTRYPOINT попробуйте добавить

  ENV ASPNETCORE_URLS=http:// :50633 DOTNET_RUNNING_IN_CONTAINER=true 
  

итак, это выглядит так:

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENV ASPNETCORE_URLS=http:// :50633 DOTNET_RUNNING_IN_CONTAINER=true
ENTRYPOINT ["dotnet", "HelloDocker.dll"]

Помогает ли это?

Комментарии:

1. На самом деле я думаю, что нам не нужна эта строка (потому что она уже предоставляет веб-api через порт 80 по умолчанию, и мы можем просто сопоставить его с портом 80 хоста вместо сопоставления с 50633 на 80). Цель здесь — обслуживать запрос извне, независимо от используемого внутри порта. Однако ваш ответ заставляет прослушивать (внутренне) порт 50633, который не принудительно выполняется EXPOSE . С добавлением этой строки моя исходная команда работает. В любом случае, спасибо вам за это.

Ответ №2:

Я не уверен, почему я не мог найти решение на форумах Docker, но после попытки поиска Now listening on: http://[::]:80 и это привело меня к самой верхней ссылке на очень похожую проблему на форумах Docker здесь.

Итак, я попробовал одно решение, используя docker inspect [container_id] first для поиска IP-адреса контейнера, и использовал этот IP для успешного доступа к веб-API 🙂

IP контейнера можно найти в Networks разделе:

 "Networks": {
            "nat": {
                "IPAMConfig": null,
                "Links": null,
                "Aliases": null,
                "NetworkID": "e336becc4500435f7338ebd8f84fef47ec2fc247f77bc82b6dbf49553f68afd5",
                "EndpointID": "a8ede68e3f4bb02392c295901f65d50f0ee014c114f564768d9c82a4644b0218",
                "Gateway": "172.30.240.1",
                "IPAddress": "172.30.242.85",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "00:15:5d:5a:29:8d",
                "DriverOpts": null
            }
        }
  

Правильный адрес, который я использовал для тестирования веб-api сейчас, это:

 http://172.30.242.85/api/values
  

Обновить:

Я предположил, что это EXPOSE 50633 означает, что docker предоставит веб-api через порт, 50633 поэтому я запускаю команду docker run -t -p 80:50633 hellodocker:dev .

Но на самом деле порт, который он предоставляет здесь, по-прежнему используется по умолчанию 80 (не уверен, почему). Но, по крайней мере, это имеет смысл. Поэтому для сопоставления портов между docker и хост-машиной мы используем вместо этого команду docker run -t -p:80:80 hellodocker:dev . Я пробовал это, и это отлично работает для http://localhost/api/values .

Я думаю, что команда, использованная ранее, docker run -t -p:80:50633 hellodocker:dev имеет бесполезное сопоставление портов (по крайней мере, для тестирования web api с хост-компьютера), потому что http://172.30.242.85/api/values должно сработать, если docker действительно запускает web api для прослушивания порта по умолчанию 80 .