dockerasp.net-web-api.net-coredocker-pull

How to pull and run a docker image from a repo - Docker


I have a WebApi created using .Net Core. I have a .dockerfile in the root of my solution:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build

WORKDIR /src
COPY ["Nuget.config", ""]
COPY ["Proyecto.WebApi/Proyecto.WebApi.csproj", "Proyecto.WebApi/"]
COPY ["Proyecto.Model/Proyecto.Model.csproj", "Proyecto.Model/"]
COPY ["Proyecto.Bl/Proyecto.Bl.csproj", "Proyecto.Bl/"]

RUN dotnet restore "Proyecto.WebApi/Proyecto.WebApi.csproj" --configfile "Nuget.config"
COPY . .

WORKDIR "/src/Proyecto.WebApi"
RUN dotnet build "Proyecto.WebApi.csproj" -c Release -o /app/build

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

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

I can build, run and push my Api without problem using those commands:

docker build -t dockerlocal .
docker run -d -p 8080:80 --name myapp dockerlocal
docker tag <image_id> docker.nexus.example.com/dockerlocal
docker push docker.nexus.example.com/dockerlocal

When I test my api from the browser http://localhost:8080/api/values, it works perfectly. Now I need, download the image from the repo and run the Api, so I execute:

docker pull docker.nexus.example.com/dockerlocal
docker run -d -p 9090:90 --name mynexusapp docker.nexus.example.com/dockerlocal

According the console, everything is working. But when I test the API http://localhost:9090/api/values I get in my browser: "localhost no envió ningún dato. ERR_EMPTY_RESPONSE"

What is the problem? Why I can't run my WebApi after docker pull comand.


Solution

  • Following discussion in the comments: the issue here was that the port mapping was changed from 8080:80 in the first command to 9090:90 in the second command. Switching mapping back to port 80 for container port fixes the issue as confirmed by the author.

    Now, to explain what happens here: Port mapping 8080:80 means that you are mapping port 8080 on the host environment to port 80 on the guest environment. Where guest environment is the actual container.

    Host port part of the mapping may be changed arbitrarily - i.e. changing it from 8080 to 9090 works - as long as the host port is not taken by another process. The same however is not true about the guest port, since the guest port is determined by the process that is run on the container. So if the container application listens to port 80, then switching guest mapping to port 90 (as happened in this case) won't work - because nothing is listening there.

    It is also quite possible to have several port mapping, i.e. if in the container you have port 80 where your application listens and port 90 where some admin console listens, you may end up with 2 port mappings: say, 8080:80 and 9090:90.

    If you want to use multiple environments at the same time - spawn multiple containers, i.e. you could do something like:

    docker run -d -p 8080:80 --name myapp1 dockerlocal
    docker run -d -p 9090:80 --name myapp2 dockerlocal
    

    Note however, that you will end up with 2 separate containers running independent from each other.