.Net 6 Web Api docker port forwarding issue - docker

I have an empty .NET 6 web api solution with swagger installed. I have generated a docker file from Visual Studio which looks like this:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Api.Permissions/Api.Permissions.csproj", "Api.Permissions/"]
COPY ["Api.Permissions.Models/Api.Permissions.Models.csproj", "Api.Permissions.Models/"]
COPY ["Api.Permissions.Services/Api.Permissions.Services.csproj", "Api.Permissions.Services/"]
RUN dotnet restore "Api.Permissions/Api.Permissions.csproj"
COPY . .
WORKDIR "/src/Api.Permissions"
RUN dotnet build "Api.Permissions.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Api.Permissions.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Api.Permissions.dll"]
I have created a docker image and pushed to my docker hub account.
I have then run this command to pull and run the image locally:
docker container run -d --name mynewapi -p 8000:443 myusername/myreponame:mycontainername
However when I browse to http://localhost:433/swagger/index.html I get:
This site can’t be reached localhost refused to connect.
I have also tried to make a GET request using postman to the sample endpoint but i just get the same error.
What am i doing wrong here?

When you run the container, you map port 443 in the container to port 8000 on the host. So you need to access it using port 8000.
Since you map port 443 which is the https port, you should be using https. So your URL should be ​https://localhost:8000/swagger/index.html
But that still isn't enough. By default Swagger is only available when your solution is running in Development mode. You control that using the environment variable ASPNETCORE_ENVIRONMENT which needs to be set to 'Development'. You can do that in your docker command when you run the container like this
docker container run -d --name mynewapi -p 8000:443 -e ASPNETCORE_ENVIRONMENT=Development myusername/myreponame:mycontainername
or you can add it to the Dockerfile like this
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT=Development
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Api.Permissions/Api.Permissions.csproj", "Api.Permissions/"]
COPY ["Api.Permissions.Models/Api.Permissions.Models.csproj", "Api.Permissions.Models/"]
COPY ["Api.Permissions.Services/Api.Permissions.Services.csproj", "Api.Permissions.Services/"]
RUN dotnet restore "Api.Permissions/Api.Permissions.csproj"
COPY . .
WORKDIR "/src/Api.Permissions"
RUN dotnet build "Api.Permissions.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Api.Permissions.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Api.Permissions.dll"]

Related

How do I find my .NET Core web app running in Docker?

When I run my .NET Core API locally in VS, I can hit it at localhost:5000. I added a Dockerfile to containerize it, but it's not clear to me how to figure out what port to expose and use?
Here is my Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine as build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish -o /app/published-app
EXPOSE 5000
ENV ASPNETCORE_URLS=http://*:5000
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine as runtime
WORKDIR /app
COPY --from=build /app/published-app /app
ENTRYPOINT [ "dotnet", "/app/Api.dll" ]
The image builds, and I run it with this command:
docker run -p 5000:5000 --name my-api -d my-api
I can see it running on port 5000 in my Docker Client, but navigating to localhost:5000 yields no results ("localhost didn't send any data").
Move the ASPNETCORE_URLS and EXPOSE to the runtime image section as shown below also try changing
http://*:5000
to
http://+:5000
Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine as build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish -o /app/published-app
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine as runtime
WORKDIR /app
COPY --from=build /app/published-app /app
EXPOSE 5000
ENV ASPNETCORE_URLS=http://+:5000
ENTRYPOINT [ "dotnet", "/app/Api.dll" ]
Rakesh's answer works, but I just want to give you another option. I prefer to let the container listen on port 80 as it's the default. If you want to do that, you can remove the EXPOSE and ASPNETCORE_URLS statements, so your Dockerfile becomes
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine as build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish -o /app/published-app
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine as runtime
WORKDIR /app
COPY --from=build /app/published-app /app
ENTRYPOINT [ "dotnet", "/app/Api.dll" ]
Then you need to map port 80 to the port you want, when you run it
docker run -p 5000:80 --name my-api -d my-api
Now you can reach it on http://localhost:5000/
The reason .NET apps based on the aspnet images listen on port 80 by default is that Microsoft set the ASPNETCORE_URLS environment variable to http://+:80 in it and that overrides any port configuration you have in your appsettings.

Docker run command like in Visual Studio

When running a Standard ASP.NET Core Web API project created by Visual Studio 2022 with docker option enabled, connecting to the server via browser is possible by using https://localhost:65215/swagger/index.html (which even pops up by itself).
When running the container with specifying the mapping of port 80 and 443 (such as 65214 and 65215), reaching Swagger is not possible on the specified ports. So there must clearly be more to it.
How can one run the docker container from the console, using a docker run command? And how can the port be set or at least identified?
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WebApiContainerized/WebApiContainerized.csproj", "WebApiContainerized/"]
RUN dotnet restore "WebApiContainerized/WebApiContainerized.csproj"
COPY . .
WORKDIR "/src/WebApiContainerized"
RUN dotnet build "WebApiContainerized.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApiContainerized.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApiContainerized.dll"]
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI(); }
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Project creation
Assuming your code contains something like this...
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
}
... Swagger will only be available in development environment mode that is controlled by the ASPNETCORE_ENVIRONMENT environment variable.
The easiest is to set this to Development as part of your run command:
docker run -p 65215:80 -e ASPNETCORE_ENVIRONMENT=Development yourimage:yourtag
By default, Swagger is only available when you run your app in the 'development' environment.
By default, a containerized app runs in production.
To change it, you set the ASPNETCORE_ENVIRONMENT variable to 'Development'. You can either do that on the docker run or you can set it in the Dockerfile.
As for the ports, Microsoft set ASPNETCORE_URLS to http://+:80 in the aspnet images, causing the app to listen on port 80.
Add a line to set ASPNETCORE_ENVIRONMENT to your Dockerfile like this
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT Development
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WebApiContainerized/WebApiContainerized.csproj", "WebApiContainerized/"]
RUN dotnet restore "WebApiContainerized/WebApiContainerized.csproj"
COPY . .
WORKDIR "/src/WebApiContainerized"
RUN dotnet build "WebApiContainerized.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApiContainerized.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApiContainerized.dll"]
Build and run with
docker build -t myimage .
docker run -d -p 65214:80 myimage
You should now be able to reach the Swagger page at http://localhost:65214/swagger

Docker run does not binding host port

I'm trying to run simplest asp.net core 3.1 WebApplication inside docker as simple as possible but, docker does not binding host port.
Host: Windows 10
Container target: Linux
Docker version: 20.10.7
Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
EXPOSE 80
EXPOSE 443
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY . .
RUN dotnet restore "WebApplication.csproj"
RUN dotnet build "WebApplication.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApplication.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication.dll"]
Docker build command (ok)
docker build -t webapplication .
Docker run command (ok)
docker run webapplication -p 5000:80 -p 5001:443
When I try to access website on my localhost (http://localhost:5000) I'm getting This site can’t be reached. Running the docker ps returned ports information without host mapping port
As #marzelin correctly pointed out, you need to add the flag right after run.

How do I open a site using ASP.net Core in Docker on Ubuntu on Google.Cloud?

When I run docker with Asp.net Core locally everything is ok. But when I use the Ubuntu virtual machine in cloud.google, I kind of start the container and everything works. But I don't know how to open the site. Login via External ip doesn't open anything. I just have "Can't access the site" Although everything opens locally. Am I missing any settings?
Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
RUN dotnet restore "WebApplication1/WebApplication1.csproj"
COPY . .
WORKDIR "/src/WebApplication1"
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]
Command: sudo docker run -d -p 8000:80 gamehomm/webapplication1
I got it!
docker run -d -p 80:80/tcp gamehomm/webapplication1
Then I changed VM instance details
Firewalls
Allow HTTP traffic
Allow HTTPS traffic

Net Core on Docker for Windows SQL Server not working

I'm creating a new empty ASP.NET Core 2.2 with Docker support enabled (Docker for Windows).
When I run it on Docker, it does not connect to SQL Server. I was expecting that the nanoserver had a SQL Server in it. Am I wrong?
How should I connect this instance to an SQL Server?
I was trying to avoid creating a second Docker instance for the SQL Server. Is this the only way to achieve what I'm looking for?
Here's the auto generated Dockerfile:
FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-1803 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM microsoft/dotnet:2.1-sdk-nanoserver-1803 AS build
WORKDIR /src
COPY ["DockerTest2/DockerTest2.csproj", "DockerTest2/"]
RUN dotnet restore "DockerTest2/DockerTest2.csproj"
COPY . .
WORKDIR "/src/DockerTest2"
RUN dotnet build "DockerTest2.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "DockerTest2.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "DockerTest2.dll"]

Resources